Даже у таких монстров облачной индустрии, как Amazon случаются проблемы с оборудованием. В связи с недавними перебоями в работе US East-1 датацентра, данная статья может быть полезной.
Варианты построения высокодоступных систем в AWS. Преодоление перебоев в работе
Отказоустойчивость является одной из основных характеристик для всех облачных систем. Каждый день множество приложений проектируются и разворачиваются на AWS без учета этой характеристики. Причины данного поведения могут варьироваться от технической неосведомленности в том, как правильно спроектировать отказоустойчивую систему до высокой стоимости создания полноценной высокодоступной системы в рамках сервисов AWS. В данной статье освещается несколько решений, которые помогут преодолеть перебои в работе оборудования провайдеров и создать более подходящее решение в рамках AWS инфраструктуры.
Для работы типичного Интернет приложения состоит из следующих уровней: DNS, Load Balancer, веб сервер, сервер приложения, база данный, кэш. Давайте возьмем этот стек и подробно рассмотрим основные моменты, которые необходимо учитывать при построении высокодоступной системы:
Построение высокодоступной системы в AWS
Высокая доступность на уровне веб сервера / сервера приложения
Высокая доступность на уровне балансировки нагрузки / DNS
Высокая доступность на уровне базы данных
Построение высокодоступной системы между зонами доступности AWS
Построение высокодоступной системы между регионами AWS
Построение высокодоступной системы между различными облачными и хостинг провайдерами
Высокая доступность на уровне веб сервера / сервера приложения
Для того чтобы исключить компонент наличие единой точки отказа (SPOF — Single Point of Failure), обычной практикой является запуск веб приложения на двух и более экземплярах виртуальных серверов EC2. Такое решение позволяет обеспечить более высокую отказоустойчивость по сравнению с использованием одного сервера. Сервера приложений и веб сервера могут быть настроены как с использованием проверки состояния, так и без неё. Ниже изображены самые часто встречающиеся архитектурные решения для высокодоступных систем с использованием проверки состояния:
Ключевые моменты, на которые нужно обратить внимание при построении такой системы:
Так как текущая инфраструктура AWS не поддерживает Multicast протокол на уровне приложения данные необходимо синхронизировать, используя обычный Unicast TCP. Например, для Java приложений можно использовать JGroups, Terracotta NAM или подобное программное обеспечения для синхронизации данных между серверами. В простейшем случае можно использовать одностороннюю синхронизацию при помощи rsync, более универсальным и надежным решением является использование сетевых распределенных файловых систем таких, как GlusterFS.
Для хранения пользовательских данных и информации о сессиях можно использовать Memcached EC2, ElastiCache или Amazon DynamoDB. Для большей надежности можно развернуть ElastiCache кластер в различных зонах доступности AWS.
Использование ElasticIP для переключения между серверами, не рекомендуется для высоко критичных систем, так как этот процесс может занимать до двух минут.
Пользовательские данные и сессии могут храниться в базе данных. Использовать данный механизм нужно с осторожностью, необходимо оценить возможные задержки при операциях чтения/записи в базу.
Загружаемые пользователями файлы и документы должны храниться на сетевых файловых системах, таких как NFS, Gluster Storage Pool или Amazon S3.
Должен быть включена политика фиксации сессий на уровне Amazon ELB или реверсного прокси, если сессии не синхронизируются посредством единого хранилища, базы данных или другого подобного механизма. Этот подход обеспечивает высокую доступность, но не обеспечивает отказоустойчивость на уровне приложения.
Высокая доступность на уровне балансировки нагрузки / DNS
Уровень DNS/Load Balancing является главной точкой входа для веб приложения. Нет смысла в построении сложных кластеров, тяжелых реплицируемых веб ферм на уровне приложения и базы данных без построения высоко доступной системы на уровне DNS/LB. Если балансировщик нагрузки является единой точкой отказа, то его выход из строя сделает недоступной всю систему. Ниже приведены самые распространенные решения для обеспечения высокой доступности на уровне балансировщика нагрузки:
1) Использование Amazon Elastic Load Balancer в качестве балансировщика нагрузки для обеспечения высокой доступности. Amazon ELB автоматически распределяет нагрузку приложения между несколькими EC2 серверами. Этот сервис дает возможность достичь большего чем обычная отказоустойчивость приложения, это дает возможность плавного увеличения ресурсов между которыми распределяется нагрузка в зависимости от интенсивности входящего трафика. Это позволяет обеспечить обслуживание нескольких тысяч одновременных подключений и при этом может гибко расширятся, при возрастании нагрузки. ELB по своей сути является отказоустойчивым блоком, который может самостоятельно исправить сбои в своей работе. Когда нагрузка увеличивается, то на уровне ELB автоматически добавляются дополнительные виртуальные машины ELB EC2. Это автоматически исключает наличие единой точки отказа и весь механизм распределения нагрузки продолжает работать, даже если некоторые виртуальные машины ELB EC2 выходят из строя. Так же Amazon ELB автоматически определяет доступность сервисов, между которыми необходимо распределять нагрузку и в случае проблем автоматически направляет запросы на доступные сервера. Amazon ELB может быть настроен как для распределения нагрузки с использованием случайного распределения Round Robin, без проверки состояния сервисов, так и с использованием механизма закрепления сессий и проверкой состояния. Если же синхронизация сессий не реализована, то даже использование закрепления сессий не может обеспечить отсутствия появления ошибок приложения при отказе одного из серверов и перенаправлении пользователей на доступный сервер.
2) Иногда приложения требуют:
— Сложного балансирования нагрузки с возможностью кэширования (Varnish)
— Использования алгоритмов распределения нагрузки:
— Минимум соединений (least connection) – сервера с меньшим количеством активных подключений получают больше запросов
— Минимум соединений с весовыми коэффициентами (Weighted Least-Connections) -сервера с меньшим количеством активных соединений и большей мощностью получают больше запросов
— Распределение по источнику (Destination Hash Scheduling)
— Распределение по получателю (Source Hash Scheduling)
— Распределение, основанное на размещении и минимуме соединений (Locality-Based Least-Connection Scheduling) — Больше запросов будут получать сервера с меньшим количеством активных подключений с учётом IP-адресов получателей
— Обеспечить работу при больших краткосрочных всплесках нагрузки
— Наличие фиксированного IP адреса у балансировщика нагрузки
Во всех вышеперечисленных случаях использование Amazom ELB не подходит. Лучше использовать сторонние балансировщики или реверсные прокси, такие как: Nginx, Zeus, HAproxy, Varnish. Но при этом нужно обеспечить отсутствие единой точки отказа, самое просто решение данной проблемы использовать несколько балансировщиков. Реверсный прокси Zeus уже имеет встроенную функциональность для работы в кластере, для других сервисов необходимо использовать циклическое распределение DNS Round Robin. Давайте рассмотрим этот механизм подробнее, но для начала определим несколько ключевых моментов, которые нужно учесть при построении надежной системы распределения нагрузки в рамках AWS:
Несколько Nginx или HAproxy сервисов могут быть сконфигурированы для обеспечения высокой доступности в AWS, эти сервисы могут определять доступность сервиса и распределять запросы между доступными серверами
Nginx или HAproxy могут быть настроены для циклического распределения нагрузки, в случае если приложение не поддерживает проверку доступности состояния. Так же эти сервисы поддерживают работу с использованием механизма закрепления сессий, но если синхронизация сессий не обеспечена должным образом это не гарантирует отсутствие появления ошибок на уровне приложения при выходе одного сервера из строя
Горизонтальное масштабирование балансировщиков нагрузки вертикального масштабирования. Горизонтальное масштабирование увеличивает количество отдельных машин выполняющих функцию балансировки, исключая наличие единой точки отказа. Для масштабирования таких балансировщиков нагрузки как Nginx и HAproxy необходима разработка своих скриптов и образов системы, использование для масштабирования Amazon AutoScaling не рекомендуется в данном случае.
Для определения доступности серверов балансировщика можно использовать систему мониторинга Amazon CloudWatch или сторонние сервисы мониторинга, такие как Nagios, Zabbix, Icinga и в случае недоступности одного из серверов при помощи скриптов и утилит командной строки для управления EC2 запускать новый экземпляр сервера для балансировщика в течение нескольких минут.
Теперь давайте обсудим уровень, который стоит над балансировщиком – DNS. Amazon Route 53 является высоко доступным, надежным и масштабируемым сервисом DNS. Этот сервис может эффективно распределять пользовательские запросы ко всем сервисам Amazon, таким как EC2, S3, ELB, а так же за пределы AWS инфраструктуры. Route 53 по сути является отказоучтойчивым управляемым DNS сервером и может быть сконфигурирован, как через интерфейс командной строки, так и через веб консоль. Сервис поддерживает как циклическое, так и весовое распределение нагрузки и может распределять запросы как между отдельными EC2 серверами, входящими в балансировщик, так и для Amazon ELB. При использовании циклического распределения проверка доступности сервиса и переключения запросов на доступные сервера не работает и должна быть вынесена на уровень приложения.
Высокая доступность на уровне базы данных
Данные это самая ценная часть любого приложения и проектирование высокой доступности на уровне базы данных является самой приоритетной в любой высоко доступной системе. Для исключения единой точки отказа на уровне базы данных общей практикой является использование нескольких серверов баз данных с репликацией данных между ними. Это может быть как использование, кластера так и использование схемы Master-Slave. Давайте рассмотрим наиболее популярные решения данной задачи в рамках AWS:
1) Использование репликации Master-Slave.
Мы можем использовать один EC2 сервер в качестве основного (master) и один или более в качестве второстепенных серверов (slave). Если эти сервера находятся в публичном облаке необходимо использовать ElastcIP, если же используется приватное облако (VPC) доступ между серверами может быть осуществлен через приватные IP адреса. В таком режиме сервера базаы данных могут использовать асинхронную репликацию. Когда основной сервер баз данных выходит из строя, мы можем переключить второстепенный сервер в режим Master, используя свои скрипты, тем обеспечив высокую доступность. Мы можем запустить репликацию между серверами в режиме Active-to-Active или в режиме Active-to-Passive. В первом случае операции записи, операции промежуточной записи и чтения должны выполняться на основном сервере, а операции чтения должны выполняться на второстепенном сервере. Во втором случае все операции чтения и записи должны выполняться только на основном сервере, а на второстепенный сервер только в случае недоступности основного сервера после того как второстепенный сервер переключается в режим Master. Рекомендуется использовать EBS образы для EC2 серверов баз данных для обеспечения надежности и стабильности на уровне работы с диском. Для обеспечения дополнительной производительности и целостности данных можно настроить EC2 сервер баз данных с различными вариантами RAID массивов в рамках AWS.
2) MySQL NDBCluster
Мы можем настроить два или более MySQL EC2 серверов в качестве SQLD и узлов данных, для хранения данных и один управляющий MySQL сервер для создания кластера. Все узлы данных в кластере могут использовать асинхронную репликацию для синхронизации данных между собой. Операции чтения и записи могут быть одновременно распределены между всеми узлами хранения данных. Когда один из узлов хранения данных в кластере отказывает, другой становится активным и обрабатывает все поступающие запросы. Если используется публичное облако, необходимы ElasticIP адреса для каждого сервера в кластере, если же используется приватное облако можно использовать внутренние IP адреса. Рекомендуется использовать EBS образы для EC2 серверов баз данных для обеспечения надежности и стабильности на уровне работы с диском. Для обеспечения дополнительной производительности и целостности данных можно настроить EC2 сервер баз данных с различными вариантами RAID массивов в рамках AWS.
3) Использование зон доступности совместно с RDS
Если мы используем Amazon RDS MySQL на уровне базы данных, мы можем создать один Master сервер в одной зоне доступности и один Hot Standby сервер в другой зоне доступности. Дополнительно мы модем иметь несколько второстепенных Read Replica серверов в нескольких зонах доступности. Основной и второстепенный узлы RDS могут использовать синхронную репликацию данных между собой, Read Replica сервер использует асинхронную репликацию. Когда Master RDS серве недоступен, Hot Standby становится автоматически доступен по тому же адресу в течение нескольких минут. Все операции записи, промежуточного чтения и записи должны быть выполнены на Master сервере, операции чтения могут быть выполнены на Read Replica серверах. Все RDS сервисы используют EBS образы. Так же сервис RDS предоставляет автоматическое создание резервных копий и с его помощью можно восстановить данные с определенной точки, так же RDS может работать в рамках приватного облака.
Остальные пункты будут рассмотрены во второй части:
Построение высокодоступной системы между зонами доступности AWS
Построение высокодоступной системы между регионами AWS
Построение высокодоступной системы между различными облачными и хостинг провайдерами