Распределенные системы. Паттерны проектирования - [26]
volumeMounts:
- name: conf
mountPath: /etc/nginx
- name: certs
mountPath: /etc/certs
volumes:
- name: conf
configMap:
# Объект ConfigMap для nginx, созданный ранее
name: nginx-conf
100 Часть II. Паттерны проектирования обслуживающих систем - name: certs
secret:
# Ссылка на загруженные ранее сертификат
# и секретный ключ
secretName: ssl
Для создания реплицированных nginx-серверов нужно выпол-нить такую команду:
kubectl create -f nginx-deploy.yaml
Наконец, опубликуйте SSL-сервер nginx в виде сервиса: kind: Service
apiVersion: v1
metadata:
name: nginx-service
spec:
selector:
app: nginx-ssl
type: LoadBalancer
ports:
- protocol: TCP
port: 443
targetPort: 443
Чтобы создать сервис балансировщика, выполните команду: kubectl create -f nginx-service.yaml
Если вы создали этот сервис в кластере Kubernetes, поддержи-вающем внешние балансировщики нагрузки, у вас появился открытый внешний сервис, принимающий запросы на внешний IP-адрес.
Чтобы узнать этот адрес, выполните команду: kubectl get services
По этому адресу вы сможете обратиться к вашему сервису из браузера.
Глава 5. Реплицированные сервисы с распределением нагрузки 101 Резюме
Глава начиналась с описания простого паттерна для реплици-рованных stateless-сервисов. Затем мы дополнили его двумя реплицированными сервисами с балансировщиками нагрузки. Один выполняет функцию кэширования для повышения про-
изводительности, а другой — функцию SSL-моста для обеспе-чения защищенного соединения с клиентами. Полный паттерн реплицированного stateless-сервиса представлен на рис. 5.8. Его можно развернуть в Kubernetes с помощью трех объектов развертывания и трех объектов — сервисов балансировщиков нагрузки. Полные исходные тексты примеров можно найти по адресу https://github.com/brendandburns/designing-distributed-systems . 6> Шардированные сервисы В предыдущей главе мы обсудили значимость репликации sta-teless-сервисов для надежности, избыточности и масштабирова-ния. В этой главе поговорим о шардированных сервисах. В рамках реплицированных сервисов, рассмотренных в предыдущей главе, каждая копия сервиса была равноценна и могла обслужить любой запрос. В отличие от реплицированных сервисов каждая копия шардированного сервиса (шард) может обслужить только часть запросов. Узел балансировки нагрузки (корневой узел ) отвечает за изучение каждого запроса и перенаправление его соответствую-щему узлу (или узлам) для обработки. Разница между реплици-рованными и шардированными сервисами показана на рис. 6.1. Репликация сервиса обычно используется для построения stateless-сервисов, а шардирование — для сервисов, хранящих состояние (stateful-сервисов). Необходимость шардинга данных возникает, когда объем данных становится слишком велик для обслуживания одной машиной. Шардинг позволяет масштаби-ровать сервис в зависимости от объема обслуживаемых данных. Глава 6. Шардированные сервисы 103
Рис. 6.1. Схемы реплицированного и шардированного сервисов Шардирование кэша
Чтобы разобраться в структуре шардированной системы, нужно детально рассмотреть устройство шардированного кэша . Шар-дированный кэш — реализация кэша, стоящая между пользова-тельскими запросами и собственно распределенной реализаци-ей кэша. Общая схема системы приведена на рис. 6.2.
Рис. 6.2. Шардированный кэш
104 Часть II. Паттерны проектирования обслуживающих систем В главе 3 мы рассмотрели, как можно использовать паттерн Ambassador для распределения данных в шардированном сер-висе. Здесь поговорим о том, как построить такой сервис. При проектировании шардированного кэша следует задать себе не-сколько вопросов:
> зачем нужен шардированный кэш;
> какова роль кэша в вашей архитектуре; > нужен ли реплицированный и шардированный кэш; > в чем состоит функция шардирования? Зачем вам нужен шардированный кэш Как уже упоминалось во введении, шардирование в первую очередь необходимо для увеличения объема хранимых в сер-висе данных. Чтобы понять, как это помогает кэшированию, рассмотрим следующую систему. В каждом экземпляре кэша есть 10 Гбайт памяти для хранения результатов. Каждый эк-земпляр кэша может обслуживать до 100 запросов в секунду (RPS). Допустим, в нашем сервисе хранится 200 Гбайт данных, а ожидаемая нагрузка составляет 1000 RPS. Очевидно, требуется десять экземпляров кэша, чтобы удовлетворить 1000 запросов в секунду (десять экземпляров по 100 RPS на экземпляр). Про-ще всего будет развернуть этот сервис в реплицированном виде, как показано в предыдущей главе. Но, если развернуть его та-ким образом, распределенный кэш сможет хранить не более 5 % (10 из 200 Гбайт) общего набора данных. Так происходит потому, что каждый экземпляр кэша независим от остальных, а значит, хранит примерно те же данные, что и остальные. Это отличный подход для обеспечения избыточности, который совершенно не способствует эффективному использованию памяти. Если же мы развернем шардированный на десять частей кэш, то все так же сможем обслуживать нужное количество запросов в секунду Глава 6. Шардированные сервисы