образом, уменьшилась до 77,5 миллисекунд. Кэш не только увеличивает количество обрабатываемых в секунду запросов, но и ускоряет выполнение каждого отдельного запроса, поэтому замедление обработки запросов в результате отказа части экзем-пляров кэша или развертывания новой его версии беспокоит нас не слишком сильно. Однако в некоторых случаях влияние на производительность окажется настолько велико, что запросы начнут скапливаться в очередях и часть из них будет отклонять-ся по истечении времени ожидания. Никогда не будет лишним выполнять нагрузочное тестирование сервиса как при наличии, так и при отсутствии кэша, чтобы понять его влияние на общую производительность системы.
Наконец, нужно думать не только об отказах. Если вы хотите об-новить или повторно развернуть шардированный кэш, не полу-чится просто развернуть новую копию сервиса и рассчитывать на то, что он сразу же возьмет на себя нагрузку. Развертывание новой версии шардированного кэша в общем случае приведет к временной потере производительности. Другим, более слож-ным решением будет репликация шардов. Реплицированный и шардированный кэш Иногда система оказывается настолько зависимой от кэша в плане задержек или нагрузки, что потеря даже одного шарда в результате отказа или в процессе обновления оказывается неприемлемой.
Или же нагрузка на определенный шард становится слишком велика и вам приходится его масштабировать, чтобы он выдер-живал объем работ. Указанные причины могут подтолкнуть вас к развертыванию одновременно реплицированного и шардирован-ного сервиса. Шардированный сервис с репликацией совмещает паттерн построения реплицированного сервиса, рассмотренный в предыдущей главе, с паттерном шардирования, описанным 108Часть II. Паттерны проектирования обслуживающих систем в предыдущих разделах. По сути, каждый шард кэша в таком слу-чае реализуется не одним сервером, а реплицированным сервисом. Такая архитектура более сложна в реализации и развертывании, но имеет определенные преимущества перед просто шарди-рованным сервисом. Что наиболее важно, замена одиночного сервера реплицированным сервисом повышает устойчивость шардов к отказам и обеспечивает их доступность в случае от-каза одной из реплик. Вместо того чтобы закладывать в систему устойчивость к снижению производительности из-за отказа шардов, можно рассчитывать на улучшение производитель-ности за счет использования кэша. Если вы готовы обеспечить избыточный резерв вычислительной мощности для шардов, развертывание новой версии даже в периоды пиковой нагрузки для вас не представляет никакой опасности. Теперь нет необхо-димости ждать, когда нагрузка спадет.
Кроме того, поскольку каждый шард представляет собой неза-висимый реплицированный сервис, любой шард можно масшта-бировать в зависимости от его текущей нагрузки. Такого рода «горячее» шардирование мы рассмотрим в конце этой главы. Практикум. Развертывание реализации паттерна Ambassador и сервиса memcache для организации шардированного кэша В главе 3 мы рассмотрели процесс развертывания шардирован-ного сервиса Redis. Развертывание шардированного сервиса memcache происходит подобным образом. Сначала развернем memcache с помощью Kubernetes-объекта StatefulSet :
apiVersion: apps/v1beta1
kind: StatefulSet
Глава 6. Шардированные сервисы 109
metadata:
name: sharded-memcache
spec:
serviceName: "memcache"
replicas: 3
template:
metadata:
labels:
app: memcache
spec:
terminationGracePeriodSeconds: 10
containers:
- name: memcache
image: memcached
ports:
- containerPort: 11211
name: memcache
Сохраните этот код в файле с именем memcached-shards.yaml , который можно развернуть командой kubectl create -f mem-cached-shards.yaml . В результате этого будут созданы три кон-тейнера с запущенным сервисом memcached. Как и в примере с Redis, нам также необходимо создать Kubernetes-сервис, который назначит DNS-имена созданным экземплярам memcached. Он будет выглядеть следующим образом: apiVersion: v1
kind: Service
metadata:
name: memcache
labels:
app: memcache
spec:
ports:
- port: 11211
name: memcache
clusterIP: None
selector:
app: memcache
110Часть II. Паттерны проектирования обслуживающих систем Сохраните этот код в файле с именем memcached-service.yaml и разверните полученный файл командой kubectl create -f mem-cached-shards.yaml . Теперь на вашем DNS-сервере должны по-явиться записи для хостов memcache-0.memcache , memcache-1.mem-cache и т. д. Как и в случае с redis, эти имена следует использовать для настройки twemproxy ( https://github.com/twitter/twemproxy ). memcache:
listen: 127.0.0.1:11211
hash: fnv1a_64
distribution: ketama
auto_eject_hosts: true
timeout: 400
Читать дальше