Рецепт создания экономичного решения для автоматического масштабирования потоков Kinesis с использованием лямбда-функций

В моем последнем посте мы обсудили 3 полезных совета по эффективной работе с Lambda и Kinesis. Теперь давайте посмотрим, как мы можем использовать Lambda в качестве экономичного решения для автоматического масштабирования потоков Kinesis.

Автоматическое масштабирование для DynamoDB и Kinesis - две из наиболее часто запрашиваемых функций для AWS, и когда я пишу этот пост, я уверен, что люди в AWS усердно работают чтобы это произошло. А пока вы можете самостоятельно разработать экономичное решение.

С высокого уровня мы хотим:

  • быстрое масштабирование потоков Kinesis для соответствия возрастающей нагрузке
  • уменьшите количество недостаточно используемых потоков Kinesis, чтобы сократить расходы

Автоматическое масштабирование потоков Kinesis

Время реакции важно для увеличения масштабов. Основываясь на личном опыте, я считаю, что опрос показателей CloudWatch - плохое решение. Вот почему:

  • Показатели CloudWatch обычно отстают более чем на минуту
  • в зависимости от частоты опроса время реакции еще больше отстает
  • высокая частота опроса имеет небольшое влияние на стоимость

Я кратко поэкспериментировал с утилитой масштабирования Kinesis от AWS Labs, прежде чем решил внедрить собственное решение. Я обнаружил, что он не масштабируется достаточно быстро, потому что он использует этот подход к опросу, и я тоже испытывал аналогичные проблемы со временем реакции с dynamic-Dynamodb.

Вместо этого рассмотрите возможность использования подхода на основе push с помощью CloudWatch Alarms. Хотя CloudWatch Alarms недоступен в качестве триггера для функций Lambda, вы можете использовать SNS в качестве прокси:

  1. добавить тему SNS в качестве цели уведомления для CloudWatch Alarm
  2. добавить тему SNS в качестве триггера к функции Lambda для увеличения потока, вызвавшего срабатывание сигнализации

Метрики для запуска автомасштабирования

Вы можете использовать ряд метрик для запуска действия масштабирования. Вот несколько показателей, которые следует учитывать.

WriteProvisionedThroughputExceeded (поток)

Самый простой способ - увеличить масштаб сразу после удушения. С метрикой на уровне потока вам нужно установить сигнал тревоги только один раз для каждого потока, и вам не нужно будет настраивать пороговое значение после каждого действия масштабирования. Однако, поскольку вы повторно используете один и тот же будильник CloudWatch, вы должны не забыть установить для него статус OK после масштабирования.

IncomingBytes и / или IncomingRecords (поток)

Вы можете упреждающе масштабировать (до того, как служба будет фактически задушена), рассчитав подготовленную пропускную способность и затем установив порог срабатывания сигнализации, равный, скажем, 80% от подготовленной пропускной способности.

В конце концов, это именно то, что мы сделали для масштабирования кластеров EC2, и здесь применяется тот же принцип - зачем ждать, пока на вас повлияет нагрузка, если вы можете масштабировать заранее? Однако нам нужно управлять некоторыми дополнительными сложностями, которые включены в сервис автоматического масштабирования EC2:

  • Если мы будем тревожить и IncomingBytes, и IncomingRecords, то возможно завышение масштаба (скажется на стоимости), если оба срабатывают примерно в одно и то же время. Это можно смягчить, но мы должны гарантировать, что только одно действие масштабирования может выполняться одновременно, и чтобы после каждого действия масштабирования было охлаждение.
  • После каждого действия по масштабированию нам необходимо пересчитать предоставленную пропускную способность и обновить пороговые значения срабатывания сигнализации.

WriteProvisionedThroughputExceeded (осколок)

IncomingBytes и / или IncomingRecords (осколок)

Используя метрики уровня сегментов, вы получаете преимущество знания идентификатора сегментов (в сообщении SNS), что позволяет более точно выполнять масштабирование путем разделения определенных сегментов. Обратной стороной является то, что вам нужно добавлять или удалять сигналы тревоги CloudWatch после каждого действия масштабирования.

Как увеличить масштаб Kinesis Stream

Чтобы действительно масштабировать поток Kinesis, вам нужно увеличить количество активных сегментов, разделив один или несколько существующих сегментов. Следует иметь в виду, что после того, как сегмент разделен на 2, он перестает быть Active, но по-прежнему будет доступен в течение 7 дней (в зависимости от настройки политики хранения).

Вообще говоря, вам доступны два варианта:

  1. Используйте UpdateShardCount, и пусть Kinesis выяснит, как это сделать.
  2. Выберите один или несколько осколков и разделите их самостоятельно с помощью SplitShard

Вариант 1 - UpdateShardCount - намного проще, но этот подход связан с тяжелым багажом:

  • Поскольку текущий поддерживает только UNIFORM_SCALING, это означает, что это действие может привести к созданию множества временных шардов, если вы не удваиваете каждый раз.
  • Удвоение может быть очень дорогостоящим в масштабе - и, возможно, ненужным в зависимости от схемы загрузки.
  • Плюс еще масса других ограничений.

Вариант 2 - SplitShard - использует метрики уровня сегментов для разделения только сегментов, вызвавших срабатывание сигнализации. Простая стратегия - отсортировать осколки по диапазону хешей и сначала разделить самые большие осколки.

Как уменьшить масштаб потока Kinesis

Чтобы уменьшить поток Kinesis, просто объедините два смежных сегмента. Подобно тому, как при разделении осколка остается неактивный осколок, слияние осколков оставляет после себя два неактивных осколка.

Поскольку уменьшение масштаба - это в первую очередь средство экономии, я настоятельно рекомендую не выполнять его слишком часто. Вместо этого вы можете легко увеличить свою стоимость, если вам придется увеличивать масштаб вскоре после уменьшения - следовательно, останется много неактивных осколков.

Поскольку мы хотим уменьшить масштаб нечасто, имеет смысл делать это с помощью задания cron (например, CloudWatch Event + Lambda), а не с помощью CloudWatch Alarms . После некоторых проб и ошибок мы решили уменьшать масштаб каждые 36 часов, что в 1,5 раза больше нашей 24-часовой политики хранения.

Как определить, КАКОЙ поток Kinesis нужно уменьшить

При выполнении задания cron наша функция Lambda будет перебирать весь поток Kinesis. Для каждого потока мы должны:

  • рассчитать предоставленную пропускную способность как в байтах / с, так и в записях / с
  • получить 5-минутные показатели (IncomingBytes и IncomingRecords) за последние 24 часа
  • если все точки данных за последние 24 часа ниже 50% от предоставленной пропускной способности - тогда масштабируйте поток вниз

Причина, по которой мы выбрали 5-минутные метрики, заключается в том, что это степень детализации, которую использует панель управления Kinesis и позволяет мне проверять мои расчеты. Помните, что вы не получаете значения bytes/s и records/s напрямую из CloudWatch, но вам нужно будет рассчитать их самостоятельно.

Кроме того, мы требуем, чтобы все точки данных за последние 24 часа были ниже порогового значения 50%. Это помогает нам быть абсолютно уверенными в том, что уровень использования постоянно ниже порогового значения, а не временным скачком, который может быть результатом сбоя.

При рассмотрении подхода к уменьшению потоков Kinesis вы будете иметь те же компромиссы, что и увеличение масштаба - между использованием UpdateShardCount и самостоятельной работой с MergeShards.

Заключение

Чтобы настроить исходные CloudWatch Alarms для потока, мы использовали репозиторий, в котором размещены конфигурации для всех наших потоков Kinesis. Репозиторий содержал сценарий для создания любых отсутствующих потоков и связанных CloudWatch Alarms с использованием шаблонов CloudFormation.

  • В каждой среде есть файл конфигурации, в котором подробно описаны все потоки Kinesis, которые необходимо создать, а также минимальный и максимальный номер. осколков для каждого.
  • Также существует сценарий create-streams.js, который можно запустить для создания любых недостающих потоков в среде с желаемым номером. осколков.
  • Сценарий также создаст связанные сигналы CloudWatch Alarms с использованием шаблона CloudFormation.
  • В файле конфигурации также указываются минимальный и максимальный номер. шардов для каждого потока Kinesis. Когда сценарий create-streams создает новый поток, он будет создан с указанным desiredShards номером. осколков.

Надеюсь, вам понравился этот пост - если вы делаете что-то похожее на автоматическое масштабирование потоков Kinesis, поделитесь своим опытом и дайте мне знать в комментариях!