Распределенные системы. Паттерны проектирования - [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. Шардированные сервисы