Блог Слёрм

Apache Kafka: примеры практических заданий курса

Чтобы хорошо разбираться в технологии надо практиковаться, почитать документацию недостаточно. Частично в этом прелесть курсов Слёрм, темы сопровождаются с практикой. Но задания могут быть разными. Поделимся практическим заданием по одной из тем и итоговыми проектами всего курса по Kafka.

Здесь специально оставили только суть, то что надо сделать, внутренние ссылки курса и строчки кода убрали.

Одно из заданий по теме "Клиентские библиотеки": Exactly-Once обработка данных


Практический стенд этого урока автоматически запускает кластер Apache Kafka, состоящий из 3 брокеров, установленных на 3 виртуальных машинах.

  • Заходим на наши брокеры в 3-х консольных окнах.
  • Клонируем репо и соберем тестовых клиентов на всех брокерах.
  • Создаем топики для теста на любом из брокеров.
  • Запускаем идемпотентного продюсера для записи случайно сгенерированных оплат в топик transactions-input на любом из брокеров.
  • Запускаем инстанс нашего exactly-once приложения, которое будет отфильтровывать оплаты с суммами свыше 90 долларов из топика --in и отправлять их в выходной топик --out на любом из брокеров. Параметр --id должен быть уникальным для каждого из инстансов. Попробуйте запустить несколько инстансов с одинаковым значением.
  • Убедимся, что отфильтрованные сообщения действительно пишутся в выходной топик на любом из брокеров.
  • Убедимся, что приложение действительно коммитит оффсеты на любом из брокеров.
  • Поднимем еще один инстанс* нашего приложения с другим --id на любом из брокеров.
  • Убедимся, что оба инстанса обрабатывают уникальные партиции входного топика:
 — В логе приложения видим "Committed offsets" для обрабатываемых топик-партиций
 — Сделаем describe группы и увидим 2 живых инстанса.
  • Попробуйте провести дополнительные операции с приложениями, например:
— Остановите один из инстансов: партиции будут переданы живому инстансу через session.timeout.ms
 — Остановите оба инстанса: при перезапуске обработка будет восстановлена с последней закоммиченной позиции
 — Консьюмер в приложении также сконфигурирован с функционалом Static Membership: попробуйте перезапустить инстанс в пределах session.timeout.ms (10 сек) и вне этого лимита
  • Попробуйте отключить Cooperative Rebalancing и Static Membership опциями --no-cooperative-rebalancing --no-static-membership, после чего остановите инстансы и запустите снова. Попробуйте останавливать один из инстансов и поднимать его обратно через 5−10 секунд — замечаете ли вы разницу во времени ребаланса группы по сравнению со включенным Cooperative Rebalancing?*
*Если вы видите InconsistentGroupProtocolException — подождите session.timeout.ms (10сек) пока все инстансы будут помечены, как мертвые брокером.

Итоговые проекты


Один из области разработки, один из области администрирования. В первом варианте понадобится создать приложение для генерации real-time статистики продаж интернет-магазина, а во втором — спасти кластер от хаоса.

Задание для разработчиков (Java)


Цель:
Проверить полученные знания на практике, создав ReadProcessWrite приложение для генерации real-time статистики продаж.
Задача:
Давайте представим, что у нас есть успешный интернет-магазин. На прошлой неделе наши инженеры установили кластер Apache Kafka, в топик которого отправляются сообщения о всех проведённых оплатах на нашем сайте.

Наша задача — создать аналитическое приложение, которое бы считывало успешные платежи из топика (см. флаг "isSuccessful") и агрегировало их суммы в поминутные срезы (i.o.w. поминутные окна, Tumbling Window). Подсчитанные агрегации должны отправляться в отдельный топик.

Постарайтесь подойти к задаче итеративно, двигаясь от простого решения к более сложному — кажущаяся простота скрывает под собой массу вопросов связанных с обработкой времени. Для решения подобного класса задач созданы целые фреймворки, например Kafka Streams или Apache Flink!

  • В качестве генератора случайных оплат вы можете воспользоваться классом io.slurm.kafka.TestProducer.
  • Вы также можете воспользоваться Docker для запуска кластера Apache Kafka локально.
  • В помощь есть пример ReadWriteApp приложения.
  • Подумайте, каким образом вы будете высчитывать границы минутного окна? Можем ли мы использовать для этого локальное время нашего приложения (Processing Time), какие плюсы и минусы есть у этого подхода по сравнению с использованием времени отправки/генерации самих сообщений (Event Time)?
  • Для упрощения задачи, предположим, что у в исходном топике оплат не бывает out-of-order или late сообщений. Мы можем гарантировать это выставив конфигурационную опцию топика message.timestamp.type в LogAppendTime
  • Каким образом мы можем гарантировать корректность репорта: например, отсутствие повторных обработок одних и тех же сообщений или потерь данных? При желании, попробуйте так же имплементировать репорт используя библиотеку Kafka Streams.

Задания по администрированию кластера Kafka


Как мы уже обсуждали на предыдущих уроках — нет ничего идеального. Любая система, даже самая надежная, рано или поздно даст сбой. И мы при всем желании не сможем защититься от всех возможных отказов на 100%.

Что же с этим делать? Внимательные ученики курса уже знают ответ — иметь disaster recovery plan и время от времени тренироваться на практике. Ребята из Netflix думали также и поэтому создали инструменты для контролируемого создания хаоса в вашей системе. Наверное, самый известный из них — Chaos Monkey, но в разрушительном зоопарке у Netflix есть еще и другие виды обезьян и даже Chaos Kong.

Вот что они сами инженеры Netflix пишут в своем блоге про идею, подтолкнувшую их на создание таких на первый взгляд вредных инструментов:
"Представьте, что у вас спустило колесо. Даже если у вас в багажнике есть запаска, знаете ли вы, накачано ли она? Есть ли у вас инструменты, чтобы её поставить? И, что важнее всего, вы помните, как это правильно делать? Способ убедиться, что вы можете справиться со спущенной шиной на автостраде, под дождем, посреди ночи, — это проделать дыру в шине один раз в неделю рядом с домом в воскресенье ​​и выполнить упражнение по замене. Это дорого и требует много времени в реальности, но может быть (почти) бесплатным и автоматизированным в облаке.
Так мы размышляли, создавая Chaos Monkey — инструмент, который случайным образом отключает наши инстансы в продакшне, чтобы убедиться, что мы сможем пережить эту нередкую проблему без последствий для клиентов. Название происходит от идеи выпустить дикую обезьяну с оружием в вашем центре обработки данных (или регионе облака), чтобы она случайным образом уничтожала инстансы и грызла кабели — а всё это время мы продолжаем непрерывно обслуживать наших клиентов. Запустив Chaos Monkey в середине рабочего дня в тщательно контролируемой среде с инженерами, готовыми решить любые проблемы, мы все равно можем извлечь уроки о слабых местах нашей системы и создать механизмы автоматического восстановления для их устранения. Так что в следующий раз, когда произойдет сбой инстанса в 3 часа ночи в воскресенье, мы этого даже не заметим." netflixtechblog.com/the-netflix-simian-army-16e57fbab116

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

Задание 1
Для начала нам нужен кластер Apache Kafka. Именно в него мы будем селить наших обезьянок. Если вам потребуется помощь — пересмотрите третий урок.
Установить и запустить кластер из трех брокеров Apache Kafka и трех ZooKeeper.

Задание 2
Предустановка: JMX Exporter + Prometheus + Grafana с настроенным дашбордом можно поставить заранее.
Обезьянки любят, когда их работа у всех на виду. На тестовых стендах уже установлены Prometheus и Grafana и настроен дашборд для кластера Apache Kafka. Но у нас нет никакого представления о том, что происходит с клиентами.
  • Добавить JMX Exporter агентов для брокеров Apache Kafka и серверов ZooKeeper (не забыть про рестарт);
  • Проверить метрики кластера Apache Kafka на уже готовом дашборде.

Задание 3
Уже готовы запускать обезьянок? Осталось чуть-чуть. Ронять кластер, которым никто не пользуется, как-то неинтересно. Давайте запустим несколько клиентов, которым и будем портить жизнь. Если вы уже выполнили предыдущий шаг этого практического задания, то можете использовать клиентов из него или из урока "Клиентские библиотеки". Если готовых клиентов у вас под рукой нет, можно воспользоваться встроенными асинхронными клиентами Kafka.
  • Установить Burrow и настроить сбор метрики consumer lag через Prometheus;
  • Добавить Prometheus JMX Exporter конфиг файл с запросами для сбора метрик producer/consumer.
  • Создать тестовый топик с 3 партициями, фактором репликации 3, минимальным числом синхронных реплик 2 и запретом на "грязные" выборы лидера;
  • Запустить ProducerPerformance клиента;
  • Запустить ConsumerPerformance клиента;
  • Создать новый дашборд в Grafana c метриками consumer lag и клиентскими метриками из Prometheus.

Задание 4
Окей, кластер готов, клиенты работают, мониторинг на месте — в общем все слишком хорошо. Давайте запустим пару злобных обезьян. Нашей основной задачей будет настроить клиентов и кластер так, чтобы минимизировать время неработоспособности при авариях.
Мы не будем пользоваться инструментами Netflix, так как они тянут за собой ряд зависимостей, которые усложнят наш проект. Вместо этого мы призовем на помощь дракона! Встречайте — Trogdor. Кстати, именно этим инструментом сами разработчики Apache Kafka проводят различные стресс-тесты.
  • Запустить Trogdor;
  • Имитировать неисправность на стороне брокера при помощи ProcessStopFault;
  • Имитировать разрыв сети при помощи NetworkPartitionFault;
  • Повторить имитации, изменяя продолжительность действия проблемы;
  • Увеличить latency между брокерами;
  • Увеличить latency между продюсером и кластером;
  • Выключить один брокер руками "навсегда". Вернуть ноду в качестве "новой". Восстановить балансировку партиций нашего топика.

Задание 5
Давайте завершим наше тестирование кластера на отказоустойчивость и немного порефлексируем.
  • Как мы поняли, что с кластером все в порядке?
  • Как мы поймали момент, когда начались проблемы? Какие метрики помогли нам в этом? На какие метрики мы бы хотели повесить алерты? Было ли в это время что-то интересное в логах брокеров? Был ли достаточным уровень логирования на брокерах?
  • Все ли партиции были в синхронном состоянии? Как повели себя при этом асинхронные клиенты? А как бы повели синхронные с acks=all?
  • Что еще могло пойти не так? Как бы мы это заметили?
  • Была ли просадка в скорости работы наших клиентов?
  • Появились ли дубли? Потеряли ли мы данные? Как можно это понять?
  • Можно ли было автоматизировать восстановление после каких-то неисправностей? Есть ли уже готовые инструменты для этого?
  • Подумать, что может пойти не так с вашим боевым кластером Kafka и какие требования вы к нему предъявляете. Составить disaster recovery plan. В плане описать "флаги", сигнализирующие о наличии проблем и шаги по их устранению.

Курс по Kafka от Александра Миронова, Infrastructure Engineer в Stripe, ex-Booking и Анатолия Солдатова, Lead Engineer в Авито, готовит к тому, чтобы не только сделать задания на курсе, но и уверенно выполнять такие задачи у себя на проде.
Apache Kafka