Стратегии предотвращения сбоев в распределенных системах
Что-то в распределенной системе неизбежно выйдет из строя, и мы должны планировать это так, как если бы это было обычным явлением. Одним из решений этой проблемы является запуск нескольких экземпляров службы. Таким образом, если один потерпит неудачу, другие могут взять на себя ответственность.
В этой статье мы рассмотрим некоторые из различных способов достижения этого в Kubernetes (K8s).
Никто
Избыточность имеет свою цену, и мы должны учитывать это при принятии решения о том, какой уровень отказоустойчивости нам нужен. Если ваши клиенты могут мириться с небольшими перебоями в работе, и это не слишком сильно повлияет на их работу, возможно, они вам не понадобятся.
Когда говорят о времени безотказной работы службы, оно часто указывается числом девять (например, 99,9% времени безотказной работы). Это означает, что на каждые 1000 запросов может произойти сбой только один. Как показывает опыт, каждые девять дополнительных услуг будут стоить в десять раз дороже.
Если ваше приложение не дает постоянных сбоев, вы можете запустить один модуль и полагаться на изменение расписания K8s, если что-то пойдет не так. Это предполагает, что один модуль может справиться с нагрузкой, которую получает служба.
N
По мере того, как ваша служба начинает требовать больше модулей для обработки нагрузки, вы можете масштабировать ее. Если профиль трафика со временем меняется (например, во время обеденного перерыва), у вас должно быть достаточно модулей, чтобы справиться с нагрузкой в часы пик. Эта стратегия дает вам большую устойчивость только тогда, когда модули получают значительно меньше трафика.
Если модуль выходит из строя в часы пик, запросы будут распространяться по оставшимся модулям и потенциально перегрузить их. В периоды низкой загруженности оставшиеся модули могут иметь достаточную емкость, чтобы справиться с нагрузкой.
Говоря о масштабировании, вы можете услышать термины in, out, up и down. Как правило, увеличение и уменьшение масштаба означает сохранение того же количества экземпляров, но увеличение ЦП и / или памяти серверов. Вход и выход - это процесс добавления или удаления экземпляров службы, но с сохранением ресурсов. Это позволяет вам масштабироваться дальше, так как вы можете быть ограничены максимальным объемом ЦП или памяти, которые вы можете использовать.
N + 1
Как и раньше с n
, нам нужно понять, сколько модулей необходимо для обработки пикового трафика. На этот раз мы добавляем еще одну капсулу. Это дает нам защиту от отказа одного модуля в часы пик. Стоимость такой устойчивости - это стоимость одного модуля, поскольку он является дополнительным и необходим только в сценариях сбоя. Если один модуль может обрабатывать весь трафик, у вас все равно должен быть дополнительный модуль.
Масштабирование
Вместо того, чтобы вручную рассчитывать количество модулей, которые нам нужны в часы пик, мы можем позволить K8s сделать это за нас. Учитывая метрику масштабирования, K8s может масштабировать наши услуги в зависимости от текущего спроса. Это снижает затраты за счет уменьшения масштаба при снижении спроса и увеличения, когда это необходимо. Само по себе масштабирование не дает нам устойчивости к сбоям модуля, но защищает от растущего спроса. Сохранение небольших размеров модулей с точки зрения памяти и ЦП позволяет нам более точно масштабировать и еще больше сокращать расходы.
Для получения информации о том, как узнать, когда масштабировать вашу услугу, ознакомьтесь с моей статьей Тестирование производительности для автомасштабирования K8s.
При масштабировании службы вы должны включить некоторый запас, то есть не следует доводить свои поды до предела. Для запуска ваших модулей потребуется некоторое время, а показатели автомасштабирования рассчитываются периодически. Ваше приложение должно иметь возможность обрабатывать запросы между запросом на масштабирование и фактическим масштабированием. Если у вас много стручков, запас может уменьшиться, так как он распределен по всем стручкам.
Горизонтальные автомасштабирующие модули Pod (HPA) используются для автомасштабирования наших услуг в K8s. Для получения дополнительной информации о том, как их можно настроить, ознакомьтесь с документацией. Для получения дополнительной информации о том, какие метрики не рекомендуется использовать для автомасштабирования, ознакомьтесь с этой статьей.
75% масштабирование
Когда у нас работает автомасштабирование и мы знаем, когда следует масштабировать наш сервис, мы можем контролировать, какой степени устойчивости мы хотим. Масштабируя до 75% емкости службы, мы можем потерять 25% подов и остаться только на полную мощность. Чем больше у нас капсул, тем больше мы можем потерять, но также тем больше мы платим за недостаточно используемые капсулы. При запуске большого количества модулей вы можете рассмотреть возможность уменьшения процента отказоустойчивости, так как у вас по-прежнему будет большое количество модулей, которые могут выйти из строя.
Этот метод особенно полезен, если профиль трафика службы особенно резкий. Пики могут быть особенно неприятными для автомасштабирования, поскольку они могут быть настолько короткими по времени, что автомасштабирование не успевает среагировать. Если вы приблизительно знаете, насколько велики пики, вы можете спланировать это в зависимости от масштабов услуги.
Масштабирование + N
Если мы хотим контролировать нашу избыточность более точно, чем в процентах, мы можем масштабировать ее до емкости, а затем ввести n
дополнительных модуля. Это позволит n
pod'ам выйти из строя, но все равно оставит нам достаточную емкость. Это позволяет нам точно контролировать, за сколько избыточных модулей мы платим.
Сервисы K8s используют метки, чтобы решить, к каким модулям направляются запросы. Это позволяет нам развернуть два набора реплик одной и той же службы с разными конфигурациями. Один набор реплик будет масштабироваться с помощью горизонтального автомасштабирования модулей, а другой набор будет иметь n
модуля. Оба набора реплик помечают модули одной и той же меткой, и служба перенаправляет на эту метку. Сервис будет равномерно разделять трафик между всеми модулями, позволяя масштабировать сервис при сохранении n
избыточных модулей.
Множественные кластеры
Переходя на новый уровень, мы могли развернуть наше приложение на двух кластерах K8s. Это позволит всему кластеру выйти из строя и по-прежнему поддерживать службы. Балансировщик нагрузки будет располагаться перед кластерами и направлять трафик между кластерами. Если вы размещаете кластер у поставщика облачных услуг, такого как AWS, кластер автоматически развертывается в нескольких зонах доступности. Это защищает от физического сбоя, такого как отключение электроэнергии, стихийное бедствие или чего-то еще хуже, поэтому должна быть веская причина для создания нескольких кластеров.
При запуске нескольких кластеров автоматическое масштабирование становится более сложной задачей, поскольку обычно показатели масштабирования не являются общими для кластеров. Если кластер все-таки выйдет из строя, все еще работающий кластер получит весь трафик от отказавшего кластера без особого уведомления. Есть несколько способов справиться с этим внезапным увеличением нагрузки. Ваше автомасштабирование может реагировать достаточно быстро, чтобы справиться с трафиком, или вы можете принять удар и снизить производительность при масштабировании.
В зависимости от того, насколько необходима избыточность, кластеры могут работать в активно-пассивном режиме, что означает, что один кластер получает все запросы. В этой настройке службам пришлось бы масштабироваться с нуля, если только показатели масштабирования не были общими для кластеров.
Количество против избыточности
Чем больше у вас модулей, тем меньше сбой одного модуля влияет на другие модули. Допустим, у нас есть десять капсул, которые могут обслуживать 100 оборотов в секунду. Если мы масштабируем 90 об / с и один модуль выйдет из строя, остальные модули получат 100 оборотов в секунду, что соответствует их максимуму. Если у нас будет 20 модулей, а один из них выйдет из строя, оставшимся модулям придется иметь дело только с 95 об / сек. Оба этих сценария предполагают, что службы получают ровно столько запросов, сколько необходимо для масштабирования службы. В действительности, сервисы обычно получают немного меньше трафика или немного больше, если сервис пытается масштабироваться.
Заключение
Автомасштабирование - сложный зверь, и есть много вариантов, которые следует учитывать. Я надеюсь, что вы лучше понимаете доступные вам варианты и можете использовать их, чтобы сократить расходы на счета за облачные услуги, сохранив при этом время безотказной работы.
Спасибо за прочтение!