Вы уже знаете, что фейловер-стратегии — это механизм обеспечения высокой доступности приложения, в рамках которого «основная» система в случае сбоя может быть заменена «резервной». В этом уроке вы рассмотрите конкретные типы фейловер-стратегий, которые помогают минимизировать время простоя и сохранить доступность приложения даже в условиях непредвиденных сбоев.
Вы изучите основные подходы к проектированию систем с высокой доступностью: Active-Active и Active-Standby, а также специфические стратегии Cold Standby и георезервирование. Ещё вы узнаете, как правильно разработать Disaster Recovery Plan, чтобы быть готовым к любым неожиданным ситуациям.
В этом уроке вы получите ответы на вопросы:
Каковы основные различия между стратегиями Active-Active и Active-Standby?
Что такое Cold Standby и какие преимущества и недостатки он имеет по сравнению с Warm Standby?
Как георезервирование помогает повысить отказоустойчивость системы?
Что нужно включить в Disaster Recovery Plan для обеспечения быстрого восстановления системы после сбоя?
Начнём с разбора типов фейловер-стратегий.
Типы фейловер-стратегий
Есть два основных типа фейловер-стратегий: Active-Active и Active-Standby. У них также есть некоторые вариации.
Базовые принципы не зависят от того, в рамках какого компонента или окружения они применяются. Для обеспечения отказоустойчивости аналогичные принципы стоит соблюдать не только при развёртывании на локальных серверах, но и в облаке.
Этот урок посвящён проектированию высоконагруженных приложений. Речь идёт не об экземплярах приложения как единицах деплоймента, а о развёртывании приложения на нескольких узлах/серверах. На одном узле может быть развёрнуто несколько экземпляров приложения или его компонентов/сервисов, но это не обеспечивает защиту от всех типов сбоев.
Пора разобрать каждый тип фейловер-стратегии подробнее.
Active-Active
В рамках этой стратегии ваше приложение будет развёрнуто как минимум на двух узлах (серверах), которые одновременно обрабатывают запросы. В такой конфигурации обязательно используется балансировщик нагрузки для равномерного распределения нагрузки по всем узлам. Индивидуальные настройки и конфигурации каждого из узлов должны быть идентичны, чтобы обеспечить избыточность и бесперебойную работу приложения.
Пример
Предполагается, что все узлы приложения одновременно обрабатывают трафик. При этом перед ними стоит балансировщик, который этот трафик распределяет между узлами.
Если один из узлов выходит из строя, трафик распределятся между оставшимися. Если приложение развёрнуто на двух узлах, то весь трафик уходит на второй. В таком случае ресурсов на одном узле должно быть всегда достаточно, чтобы иметь возможность обработать весь трафик самостоятельно, иначе есть риск деградации производительности оставшегося узла или даже сбоев, связанных с нагрузкой, превышающей его возможности.
Плюсы:
Такой подход улучшает отклик приложения благодаря равномерному распределению нагрузки.
Потенциальное время простоя стремится к нулю, так как оба узла постоянно активны и готовы к работе. Сильно зависит от конфигурации балансировщика: частоты проверки работоспособности экземпляра приложения и скорости ребалансировки трафика.
Даже в период с момента сбоя одного из узлов до переключения всего трафика на другие узлы приложение всё ещё будет отвечать в случаях, когда запросы отправятся на работающие узлы. То есть сбой одного узла приводит только к частичной недоступности.
Приложение проще масштабировать в случаях нехватки или неэффективности вертикального масштабирования ресурсов самих серверов.
Минусы:
Высокая стоимость конфигурации приложения. Ресурсы обоих узлов находятся в постоянной эксплуатации, что ведёт к быстрому износу.
Сложность имплементации для stateful-приложений. Если ваше приложение зависит от состояния, это усложняет вопросы балансировки трафика, а также повышает вероятность потери данных в случае сбоев.
Каждый из узлов должен быть способен обработать всю нагрузку самостоятельно. Это необходимо на случай сбоя одного из узлов. Проверить это можно с помощью показателей утилизации, в обычном состоянии они не должны превышать 50% на каждом из узлов. Если утилизация выше, то в случае сбоя приложение столкнётся с деградацией производительности, ошибками и увеличением времени отклика.
Балансировщик также не должен становиться точкой отказа, и для него также нужно предусмотреть фейловер-стратегию. Балансировщик должен быть развёрнут на нескольких узлах.
Когда применять?
Active-Active подходит для высоконагруженных систем с высокими требованиями к доступности и отказоустойчивости: интернет-магазинов и финансовых сервисов. Если требования к доступности >= 99,5% и/или RTO =< 30 минут, настоятельно рекомендуется присмотреться к этой стратегии.
Однако всегда нужно искать экономическое обоснование, которое сводится к определению разницы между потенциальными потерями в случае недоступности приложения и стоимостью разработки и сопровождения приложения в той или иной конфигурации.
При этом для высоконагруженных приложений Active-Active — более выигрышная стратегия из-за возможности эффективнее масштабировать систему.
Active-Standby (или Active-Passive)
Для реализации активно-пассивной стратегии также должно быть не менее двух узлов, в отличие от Active-Active не все из них активны.
Приведём пример с двумя узлами. Когда первый узел находится в активном режиме, второй будет в режиме ожидания (или в пассивном режиме). Этот второй узел считается отказоустойчивым сервером, готовым функционировать в качестве резервного, если основной активный сервер перестанет функционировать по какой-либо причине. При этом конфигурации этого сервера также должны быть идентичны активному, чтобы иметь возможность обработать весь трафик в случае отказа основного. Между тем в обычном режиме клиенты будут подключаться только к активному серверу.
Очевидно, что, хотя в конфигурации Active-Passive резервный узел всегда работает, фактическая утилизация ресурсов на нём практически равна нулю.
Плюсы:
Меньшее потребление ресурсов резервными узлами в пассивном состоянии, что уменьшает затраты. Это актуально для ситуаций, когда приложение разворачивается в облачной среде из-за динамического ценообразования и тарификации за используемые ресурсы.
Простое администрирование, так как трафик должен идти всегда только на один узел. Такой подход может существовать с ручным администрированием в случае сбоев для переключения между узлами.
Обеспечивает относительно короткое время восстановления за счёт того, что приложение на резервном узле находится в рабочем состоянии.
Минусы:
Возможные задержки при переключении на резервный компонент. Это может быть связано со временем, которое приложению необходимо, чтобы адаптироваться под нагрузку. Например, из-за необходимости прогреть кеш или горизонтально масштабироваться под нагрузку.
Меньшее потребление ресурсов может привести к проблемам. Фактически ресурсы для резервного узла закреплены за ним и «простаивают». А слишком низкая утилизация может трактоваться как неэффективное использование.
Когда использовать?
Active-Passive подходит для критически важных систем, в которых предпочтение отдаётся стабильности и простоте управления над временем переключения. Хорошо соответствует приложениям с низкими требованиями ко времени восстановления после сбоя.
Если требования к доступности =< 99,5% и RTO >= 30 минут, можно рассмотреть такой подход в случае наличия финансовой выгоды.
У Active-Standby есть вариация — подход Cold Standby.
Cold Standby
В рамках стратегии Active-Standby мы подразумевали, что всё это время резервный узел находится в рабочем состоянии, но на него не поступает трафик (Warm Standby). Но так делать необязательно: приложение можно не разворачивать заранее. В этом случае стратегию называют Cold Standby, это частный случай реализации подхода Active-Standby. При Cold Standby, в случае сбоя основного узла, потребуется сначала его развернуть и только затем направить на него трафик. Такой подход отличается высокой степенью экономии, но в то же время гораздо более долгим временем простоя приложения.
Например, в случае применения такого подхода к резервированию СУБД предполагается, что с определённой периодичностью выполняется бэкап основного узла на какой-то ресурс. Как один из вариантов, бэкапы могут храниться в S3-хранилище. В случае сбоя основного узла производится развёртывание резервного на основе последнего сделанного бэкапа. Этот процесс занимает гораздо больше времени по сравнению с Warm Standby.
Продолжительность зависит от степени автоматизации и объёма данных. Однако такой подход даёт высокую экономию, так как всё это время ресурсы под Standby в принципе не используются.
Такой подход редко используют для высоконагруженных сервисов, к которым обычно предъявляют высокие требования доступности.
Георезервирование
Для повышения отказоустойчивости приложения развёртывание резервных копий системы может происходить уже на различных площадках или ЦОД, которые находятся в различных географических локациях.
Георезервирование не считается альтернативой выше описанных стратегий. Это скорее развитие идеи, поскольку эти подходы применяются совместно. Систему можно географически резервировать как в Active-Active конфигурации, так и в Active-Standby.
Такой подход помогает защититься от локальных сбоев и катастроф. Речь необязательно идёт о катастрофах масштаба цунами или «упавшей бомбы». Проблемы недоступности всего ЦОД могут возникать и из-за более тривиальных причин вроде обрубания кабеля питания при строительных работах неподалёку. И хотя современные ЦОД оборудованы резервными источниками питания, всё равно могут быть сценарии, при которых всё может пойти не по плану.
Такой подход может помочь оптимизировать время отклика для пользователей, которые находятся в других географических регионах. Однако есть несколько но:
Георезервирование актуально только для Active-Active стратегии, так как трафик должен попадать именно на ближайшую к пользователю площадку.
Не всегда есть возможность расположить резервный узел далеко от основного без влияния на производительность всего приложения. Например, для некоторых конфигураций кластеров БД требуется постоянная синхронизация между экземплярами в кластере. В таком случае коммиты транзакций могут занимать много времени из-за долгого ожидания подтверждения от другого узла.
При георезервировании возникает вопрос маршрутизации трафика за пределами одной площадки. Для решения этой проблемы в первую очередь поможет DNS. А также максимально эффективным инструментом считается GSLB.
Георезервирование рекомендуется применять для приложений высокого уровня критичности. Однако оно увеличивает затраты на содержание системы, поэтому решение использовать георезервирование также должно быть обосновано с точки зрения финансов. Если потенциальные потери от недоступности вашего приложения ниже накладных расходов на георезервирование в пределах года, например, то и не стоит его применять.
GSLB
GSLB (Global Server Load Balancer) — это балансировщик нагрузки, который способен направлять трафик между несколькими центрами обработки данных. В то время как обычный балансировщик распределяет трафик по серверам, расположенным в одном ЦОД.
Ещё обычный балансировщик нагрузки «встроен» во взаимодействие между клиентом и сервером, то есть весь трафик проходит через него, а GSLB используется только для выбора оптимального адреса для отправки запроса клиентом. После установки соединения весь трафик идёт напрямую между клиентом и приложением.
Метод взаимодействия между клиентом и GSLB аналогичен тому, как происходит взаимодействие с DNS. GSLB дополнительно может обеспечивать различные сценарии балансировки (Round Robin, Least Connections и т. д.) и мониторинг доступности. В результате пользователь не будет направлен к недоступному узлу.
Алгоритм работы GSLB:
Пользователь вводит URL в своём браузере или приложении, начиная процесс обращения к веб-сервису.
Запрос DNS: устройство пользователя отправляет запрос на DNS-сервер для получения IP-адреса, ассоциированного с запрашиваемым доменным именем.
Перенаправление запроса к GSLB: запрос DNS может быть перенаправлен или изначально отправлен к DNS-серверу, который является частью инфраструктуры GSLB.
Принятие решения GSLB:
a. GSLB применяет свои стратегии и правила для выбора подходящего ЦОД. Это может основываться на географии пользователя, текущей загрузке ЦОД, статусе здоровья серверов в каждом ЦОД и других параметрах.
b. GSLB может также учитывать стратегии отказоустойчивости, например, переключаясь на резервные центры данных, если основной недоступен.
Ответ DNS: GSLB отправляет ответ DNS обратно устройству пользователя, указывая IP-адрес выбранного центра данных или конкретного сервера.
Обращение к серверу: устройство пользователя использует полученный IP-адрес для направления запроса к узлу приложения в выбранном ЦОД. После получения IP-адреса взаимодействие с сервером происходит напрямую.
Обработка запроса приложением: сервер принимает запрос от пользователя и обрабатывает его, предоставляя запрашиваемый контент или выполняя нужные операции.
Реализация фейловер-стратегии при развёртывании в Kubernetes
Высокая доступность в Kubernetes — критически важный аспект для обеспечения работоспособности и доступности приложений. Надёжная архитектура кластера Kubernetes имеет решающее значение для обеспечения высокой доступности и устойчивости к сбоям. Эта архитектура включает в себя реализацию резервирования на различных уровнях: главных узлах, рабочих узлах и кластерах etcd.
Для достижения высокой доступности важно иметь несколько мастер-узлов в кластере. Такая настройка гарантирует, что плоскость управления останется работоспособной даже в случае отказа одного узла. Kubernetes позволяет собирать кластер из узлов, расположенных на разных географических площадках. Также нужно убедиться, что рабочие узлы распределены по разным зонам, стойкам или регионам. То же самое касается компонентов etcd.
В случае сбора кластера из узлов, которые располагаются в разных ЦОД, балансировка может быть обеспечена внутренними компонентами Kubernetes.
Альтернативой создания единого кластера, состоящего из узлов, расположенных в разных ЦОД, считается использование нескольких независимых кластеров, которые разворачиваются в границах разных ЦОД. В каждом из этих кластеров развёрнут независимый экземпляр приложения с аналогичными конфигурациями. При этом понадобится отдельный компонент для балансировки трафика между ними.
Этот подход снижает зависимость от сетевой связанности между ЦОД и от внутренних недостатков фейловер-механизмов в Kubernetes, что особенно актуально для ситуаций, когда площадки располагаются далеко, например, в разных странах или даже на разных континентах.
Конфигурации БД на примере PostgeSQL Patroni
Базовые принципы применения различных стратегий и методов схожи для всех компонентов и слоёв системы. На их основе разработчики открытых и промышленных решений СУБД проектируют для них отказоустойчивые конфигурации. Для многих популярных БД существуют готовые шаблоны для развёртывания, которые способны обеспечить доступность БД около 100%. Поэтому при выборе и подготовке БД обязательно изучите готовые решения.
Для БД PostgreSQL существует Patroni — это шаблон конфигурации, который позволяет добиться высокой доступности и отказоустойчивости распределённого кластера PostgreSQL. Он состоит из нескольких компонентов:
Узлы PostgreSQL, которые также могут быть геораспределены.
Кластер etcd — хранилище распределённой конфигурации, в котором находится состояние кластера PostgreSQL.
HAProxy — балансировщик нагрузки для кластера и единая точка входа для клиентских приложений.
pgBackRest — решение для резервного копирования и восстановления для PostgreSQL.
Percona Monitoring and Management (PMM) — решение для мониторинга работоспособности вашего кластера.
Каждый экземпляр PostgreSQL в кластере поддерживает согласованность с другими узлами посредством потоковой репликации. Каждый экземпляр включает в себя Patroni — менеджер кластера, который отслеживает работоспособность кластера.
Patroni использует рабочий кластер etcd для хранения конфигурации кластера и данных о работоспособности кластера. Patroni периодически отправляет данные о состоянии кластера в etcd. Если текущий основной узел не обновляет свой статус лидера в течение указанного времени, Patroni инициирует выбор нового основного узла.
Подключения к кластеру не происходят напрямую к узлам базы данных, а направляются через прокси-сервер подключений (например, HAProxy). Этот прокси-балансировщик определяет активный узел через обращение к API-менеджера Patroni. HAProxy также разворачивается в резервированной конфигурации.
Как вы можете заметить, общие принципы обеспечения отказоустойчивости сильно схожи.
Disaster Recovery Plan
Disaster Recovery Plan (DRP) — это план аварийного восстановления после сбоя. Представляет собой документ, который включает в себя:
детальное описание действий и их последовательности для устранения последствий аварии;
роли и обязанности ответственных сотрудников.
DRP необходим, так как даже если фейловер-стратегия автоматизирована, всё равно что-то может пойти не так.
DRP-планы должны обновляться сразу при внесении изменений в систему. Также важно проводить регулярные учения для проверки как работоспособности алгоритма, заложенного в план, так и самих сотрудников.
Пример
Вернёмся к приложению «ОнлиСхемы». Бизнес провёл анализ, смоделировав ситуации недоступности сервиса в течение различных периодов времени, и выявил, что, в случае недоступности приложения на протяжении двух часов, компания понесёт потери в размере 2% от чистой прибыли и получит негативные публикации в СМИ. Поэтому определены следующие требования отказоустойчивости приложения: доступность > 99,95%, RTO < 30 минут.
Команда решила использовать фейловер-стратегию Active-Active с георезервированием. При этом в двух ЦОД будут развёрнуты независимые кластеры Kubernetes. Также команда планирует использовать конфигурацию развёртывания PostgreSQL Patroni.
Задание 1
Сопоставьте характеристики Active-Active, Active-Standby и георезервирования с названиями.
Active-Active
Резервный узел обрабатывает трафик
Резервный узел обрабатывает трафик
Требуется балансировщик для маршрутизации трафика между узлами
Требуется балансировщик для маршрутизации трафика между узлами
Active-Passive
У резервного узла может потребоваться больше времени на адаптацию под нагрузку
У резервного узла может потребоваться больше времени на адаптацию под нагрузку
Резервный узел не обрабатывает трафик
Резервный узел не обрабатывает трафик
Георезервирование
Узлы приложения разворачиваются в разных ЦОД
Узлы приложения разворачиваются в разных ЦОД
Используется GSLB для маршрутизации трафика между узлами
Используется GSLB для маршрутизации трафика между узлами
Есть несколько типов фейловер-стратегий: Active-Active, Active-Standby (Active-Passive) и Cold Standby.
Георезервирование помогает защититься от локальных сбоев и катастроф. Оно актуально только для Active-Active стратегии, так как трафик должен попадать именно на ближайшую к пользователю площадку.
GSLB (Global Server Load Balancer) — это балансировщик нагрузки, который способен направлять трафик между несколькими центрами обработки данных. В то время как обычный балансировщик распределяет трафик по серверам, расположенным в одном ЦОД.
Disaster Recovery Plan (DRP) — это план аварийного восстановления после сбоя. Представляет собой документ с детальным описанием действий для устранения последствий аварии.