SlideShare a Scribd company logo
Алексей Ильенко "In real-time with Apache Kafka"
Agenda
● Быстро про продукт
● Задача и проблема
● Кафка как технология
● Кафка как решение
● Решение задачи
● Результаты
● Проблемы
Продукт SignNow
● Отправлять на подпись документы
Продукт SignNow
● Отправлять на подпись документы
● Редактировать PDF
Продукт SignNow
● Отправлять на подпись документы
● Редактировать PDF
● Отправлять группы документов
● Создавать организации и управлять ими
● Использовать готовые интеграции с SalesForce, Microsoft, etc
● Интегрировать SignNow в собственный продукт используя
SignNow Api
Задача
Api Dashboard для пользователей Signnow API
● Логи ваших вызовов API
● Фильтрация и поиск
● Результаты callback вызовов
● Статистика и биллинг
Проблемы
● 100-1000 событий в секунду
● Постоянный рост продукта
● Внезапные всплески событий
● Минимальные задержки
● Сложный бизнес распределенный между микросервисами и
легаси монолитом
● Безумный размер событий
Быстрое Решение
class DocumentController extends Controller
{
public function get(Request $request)
{
$document = $factory->getDocument($request->get('id'));
$response = new DocumentResponse($document);
$loggerService->track($request, $response);
return $response;
}
}
В контроллере или где то в Middleware, в
другом слое приложения - не важно
Недостатки
● Есть легаси где архитектура требует руками
выставлять трек
● Из кода синхронно - дополнительное время
обработки запроса
● Из кода в очередь - все равно обновлять код.
Консистентность кода на микросервисах.
Распределенный горизонтально масштабируемый отказоустойчивый лог сообщений.
● Точно не очередь
● Не совсем брокер сообщений
● Не RabbitMQ
Распределенность
Высокодоступность и отказоустойчивость
Масштабируемость
Готовность к увеличению нагрузки
Отказоустойчивость
Кластер Kafka из пяти узлов остается работоспособным,
даже если два узла лягут. Даже если 4!
Основная Абстракция
● MySQL - таблица
● Storage - файл
● Kafka - ?
Лог сообщений
(лог коммитов)
Old New
Новые сообщения попадают в конец
Producer
● Producer - поставщик сообщений
● У каждого сообщения есть свой порядковый номер - offset
Лог
0 1 2 3 4 5 6 7
Сообщение
type Message struct {
Offset int64 // set by the broker
Key []byte
Value []byte
Timestamp time.Time
}
● Offset - позиция сообщения в логе. Устанавливается
автоматически брокером.
Old New
Лог
Чтение происходит для каждого
получателя с индивудуальной позиции
(offset)
● Consumer - получатель сообщения
Consumer A (offset x)Consumer B (offset z)
Consumer C (offset y)
Topic A
0
1
n
Лог = партиция топика
Сообщение
type Message struct {
Topic string
Partition int32
Offset int64 // set by the broker
Key []byte
Value []byte
Timestamp time.Time
}
В целом
Topic A
0
1
n
Consumer A
Consumer B
Consumer C
Producer
Topic A
0
1
n
Consumer A
Producer A
Producer B
Producer C
Consumer B
partition = f(key)
Consumer Group 1А как же параллелизм?
Topic A
0
1
n
Consumer 1A
Consumer 1B
Consumer 1C
Producer
Consumer Group 2
Consumer 2A
Consumer 2B
● Для каждой консьюмер группы оффсет свой.
● Читать с начала или с конкретного оффсета - решать вам!
Надежный лог
Шардинг из коробки (партиции)
● Гранулярность хранения
● Гранулярность записи (брокер)
● Гранулярность обработки (consumer)
Репликация из коробки
● Readwrite из Лидера(Мастреа). Есть возможность указать
replication_factor
● Система подтверждений(acks). Можно определить сколько реплик
должны сохранить сообщение для подтверждения записи
Отказоустойчивость
Broker 1 Broker 2 Broker 3
Topic A. Partition 0. Leader Topic A. Partition 0. Follower Topic A. Partition 0. Follower
Topic A. Partition 1. LeaderTopic A. Partition 1. Follower Topic A. Partition 1. Follower
Topic B. Partition 0. Leader Topic B. Partition 0. FollowerTopic B. Partition 0. Follower
Topic B. Partition 1. LeaderTopic B. Partition 1. FollowerTopic B. Partition 1. Follower
● 3 брокера
● 2 топика
● По 2 партиции
● Replication factor 3
Отказоустойчивость
Broker 1 Broker 2 Broker 3
Topic A. Partition 0. Leader Topic A. Partition 0. Follower Topic A. Partition 0. Follower
Topic A. Partition 1. LeaderTopic A. Partition 1. Follower Topic A. Partition 1. Follower
Topic B. Partition 0. Leader Topic B. Partition 0. FollowerTopic B. Partition 0. Follower
Topic B. Partition 1. LeaderTopic B. Partition 1. FollowerTopic B. Partition 1. Follower
● 3 брокера
● 2 топика
● По 2 партиции
● Replication factor 3
Отказоустойчивость
Broker 1 Broker 2 Broker 3
Topic A. Partition 0. Leader Topic A. Partition 0. Follower Topic A. Partition 0. Follower
Topic A. Partition 1. LeaderTopic A. Partition 1. Leader Topic A. Partition 1. Follower
Topic B. Partition 0. Leader Topic B. Partition 0. LeaderTopic B. Partition 0. Follower
Topic B. Partition 1. LeaderTopic B. Partition 1. FollowerTopic B. Partition 1. Follower
● Был запущен процесс переизбрания лидера контроллером
● Контроллер - один из брокеров. Назначается автоматически zookeeper`ом
Нюанс
Добавляя брокеры ничего само не синхронизируется
kafka-reassign-partitions.sh
● Добавляет реплику для партиции
● Ждет синхронизации
● При необходимости запускает выборы лидера
Обработка ошибок
● Нет механизма отложить плохое сообщение
● Блокироваться на ошибке: retry до успеха
● Перекладывать “плохое” сообщение в отдельный топик
● Перекладывать ”плохое” сообщение в начало текущего топика
● Использовать все и сразу
Где взять?
Развернуть самому!
Плюсы
● Дешевле в инфраструктуре
● Гибче тюнить
● Можно подключать “плагины”
● Очевиднее
Минусы
● Сложно настроить
● Нужны специалисты с опытом (читай
дорогие)
Купить у confluent.io
Плюсы
● PaaS
● Не сильно дорого
● Дашборды, мониторинги
● Продвинутые плагины с установкой в
один клик
● KSQL
● Потюнили за вас
Минусы
● Не Amazon
https://www.confluent.io/confluent-cloud
Купить у Microsoft Azure
Плюсы
● PaaS
Минусы
● Не Amazon
● Очень загадочный
https://azure.microsoft.com/ru-ru/services/hdinsight/
Купить у Amazon (MSK)
Плюсы
● Amazon
● PaaS
Минусы
● Тяжело тюнить
● Странная поддержка регионов и зон
доступности
● JMX
● ???
https://aws.amazon.com/ru/msk/
Как работать? Клиенты
● “Нативно” используя Java. Работает круто. Много информации и
примеров. Идеальный вариант. Для мира Java...
● librdkafka. Реализация на C. Поддерживает 90% фичей. Почти
официальная поддержка. Много примеров и большое комьюнити.
● “Нативно” через сеть. Боль. Страдание. Унижение. Крайний случай если
нет обертки(биндинги) librdkafka под ваш язык, а реализовывать их
(обертки) лень дорого.
PHP
https://github.com/arnaud-lb/php-rdkafka
librdkafka (ffi или extension)
Producer
$conf = new RdKafkaConf();
$conf->set('metadata.broker.list', 'localhost:9092');
$conf->set('enable.idempotence', 'true');
$producer = new RdKafkaProducer($conf);
$topic = $producer->newTopic("test");
for ($i = 0; $i < 10; $i++) {
$topic->produce(RD_KAFKA_PARTITION_UA, 0, "Message $i");
$producer->poll(0);
}
for ($flushRetries = 0; $flushRetries < 10; $flushRetries++) {
$result = $producer->flush(10000);
if (RD_KAFKA_RESP_ERR_NO_ERROR === $result) {
break;
}
}
if (RD_KAFKA_RESP_ERR_NO_ERROR !== $result) {
throw new RuntimeException('Messages might be lost!');
}
Consumer
$conf = new RdKafkaConf();
$conf->set('group.id', 'test'); // Указываем группу
$rk = new RdKafkaConsumer($conf);
$rk->addBrokers("127.0.0.1");
$topicConf = new RdKafkaTopicConf();
$topicConf->set('auto.commit.interval.ms', 100);
$topicConf->set('offset.store.method', 'broker');
$topicConf->set('auto.offset.reset', 'smallest');
$topic = $rk->newTopic("test", $topicConf);
$topic->consumeStart(0, RD_KAFKA_OFFSET_STORED);
while (true) {
$message = $topic->consume(0, 120*10000);
switch ($message->err) {
case RD_KAFKA_RESP_ERR_NO_ERROR:
var_dump($message);break;
case RD_KAFKA_RESP_ERR__PARTITION_EOF:
echo "No more messages; will wait for moren";break;
case RD_KAFKA_RESP_ERR__TIMED_OUT:
echo "Timed outn";break;
default:
throw new Exception($message->errstr(), $message->err);break;
}
}
● Батчинг
● Обработка ошибок доставкичтения
● Контроль подключения
● Кучу абстракции вокруг
Алексей Ильенко "In real-time with Apache Kafka"
Benthos
The stream processor for mundane tasks.
https://www.benthos.dev/
Benthos
Source
● kafka
● rabbit
● file
● stdin
● tcp
● redis
● s3
● http
● custom
Processor
Target
● kafka
● rabbit
● file
● stdin
● tcp
● redis
● s3
● http
● custom
Более 50 готовых процессоров(обработчиков) для ваших данных.
Отфильтровать Json, заменить данными из mysql,
зашифроватьрасшифровать, сжать, … Все уже из коробки. Low-code решение
Проще говоря Benthos - consumer.
Бинарик скомпилированный из Go кода.
Заворачиваете в контейнер и запускаете в EC2
Benthos + Kafka + SignNow = <3
RequestResponse
ES
App
Stream Flow
RequestResponse
App
Nginx Proxy
raw data
Processing
ES
BenthosKafka
raw_data
Processing flow
normalized
sensitized
normalizer
sanitizer
appended
appender
archived archivarius
ES
Nginx Proxy
Результат
● Гибко тюнить workflow
● Легко обновлять consumers
● Проще мониторить проблемы
● Отсутствие задержек
● В любой момент времени можно добавлять новую логику для
совсем другой бизнес задачи
Мониторинг
● Состояние кластера Kafka. (Для каждого брокера отдельно)
● Диск
● Consumer Lag - показатель того, насколько велика разница между
продюсером и консьмером Kafka.
● Amazon CloudWatch
● Linkedin Burrow
● https://github.com/danielqsj/kafka_exporter
Мониторинг
Проблема
Количество входящих сообщений в топики
Анализ
● Входящий поток для топика raw_data не изменился
● Активность в других топиках странно просела
Причина
● В партицию топика raw_data попало сообщение размером 1020кб
● Лимит для всех топиков и консьюмеров был установлен в 1024кб
● normalizer consumer прочитал это сообщение из своей партиции топика raw_data
● Обработал и немного увеличил размер сообщения до условных 1025кб
● normalizer при попытке записать сообщение в свой исходящий топик получил
ошибку
{"@timestamp":"2019-10-28T15:22:33Z","@service":"benthos","level":"ERROR"
,"component":"benthos.output.switch.1.output","message":"Failed to send
message to kafka: failed to send 1 parts from message: kafka server:
Message was too large, server rejected it to avoid allocation error."}
● В результате normalizer consumer lag начал быстро расти
● Общий лаг системы в пике достиг 60к сообщений
Решение
● Увеличили в Кафке для топиков значение параметра max.message.bytes
● Увеличили ограничение размера для исходящих сообщений у всех
консьюмеров
● Накинули еще консьюмеров в группы. Суммарно вышло по 4 на топик
Будущее SignNow с Kafka
● Swoole
● Async interaction via kafka (RequestReply Pattern)
Telegram: @figushki
Facebook: https://bit.ly/assada-fb
Linkedin: https://bit.ly/assada-linkedin

More Related Content

PDF
Serghei Iakovlev "Chaos engineering in action"
PDF
Enter: code style
PDF
Enter: legacy code
PPTX
MПК3 - SDL - Опыт внедрения решений SDL Trados в российских переводческих ком...
PDF
Egor Fedorov "Behavior-driven development in Python"
PDF
Лучшие практики CI/CD с Kubernetes и GitLab / Дмитрий Столяров (Флант)
PDF
Илья Ефимов «IoC/DI на примере Autofac»
PDF
Мифы о DevOps / Александр Титов, Иван Евтухович (Экспресс 42)
Serghei Iakovlev "Chaos engineering in action"
Enter: code style
Enter: legacy code
MПК3 - SDL - Опыт внедрения решений SDL Trados в российских переводческих ком...
Egor Fedorov "Behavior-driven development in Python"
Лучшие практики CI/CD с Kubernetes и GitLab / Дмитрий Столяров (Флант)
Илья Ефимов «IoC/DI на примере Autofac»
Мифы о DevOps / Александр Титов, Иван Евтухович (Экспресс 42)

What's hot (20)

PDF
Как подружить команду админов с N командами разработки / Денис Яковлев (2ГИС)
PPTX
Breaking logs
PDF
Григорий Петров "WebRTC в мобильных приложениях при помощи React Native"
PPTX
Организация эффективной работы команды при разработке и поддержке сложной инф...
PDF
Профессиональная разработка в суровом Enterprise
PDF
Эволюционный дизайн. Joker Students Day 2016
PDF
Рефакторинг и второе рождение проекта на примере Zend Framework 2.0
PDF
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
PDF
Услуги Локализации и Перевода | Alconost
PPTX
Самодиагностика сервисов на базе платформы .NET
PPTX
C#5 What's new?
PDF
Сергей Белов
PDF
DevOps-трансформация Альфа-Банка / Антон Исанин (Альфа-Банк)
PPT
Enterprise or not to enterprise
PPTX
Развитие сообщества Open DevOps Community
PDF
Артем Титаренко
PPTX
Codeception + Docker + Robo и что из этого вышло
PPTX
Online TechTalk “Flutter Mobile Development”
PPTX
Инструмент ChangelogBuilder для автоматической подготовки Release Notes
PPTX
Использование анализатора кода SonarQube
Как подружить команду админов с N командами разработки / Денис Яковлев (2ГИС)
Breaking logs
Григорий Петров "WebRTC в мобильных приложениях при помощи React Native"
Организация эффективной работы команды при разработке и поддержке сложной инф...
Профессиональная разработка в суровом Enterprise
Эволюционный дизайн. Joker Students Day 2016
Рефакторинг и второе рождение проекта на примере Zend Framework 2.0
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
Услуги Локализации и Перевода | Alconost
Самодиагностика сервисов на базе платформы .NET
C#5 What's new?
Сергей Белов
DevOps-трансформация Альфа-Банка / Антон Исанин (Альфа-Банк)
Enterprise or not to enterprise
Развитие сообщества Open DevOps Community
Артем Титаренко
Codeception + Docker + Robo и что из этого вышло
Online TechTalk “Flutter Mobile Development”
Инструмент ChangelogBuilder для автоматической подготовки Release Notes
Использование анализатора кода SonarQube
Ad

Similar to Алексей Ильенко "In real-time with Apache Kafka" (20)

PDF
Deep Dive in Magento DI
PDF
Drupal code sprint для новичков
PDF
Этюды о буферизации: асинхронные оповещения, репликация обновлений, объединен...
PDF
Moscow Python Conf 2016. Почему 100% покрытие это плохо?
PPT
Easy authcache 2 кэширование для pro. Родионов Игорь
PPT
Easy authcache 2 кеширование для pro родионов игорь
PPTX
Длинная транзакция или когда размер имеет значение / Михаил Балаян (Odin — In...
PPTX
SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотек
PDF
MySQL: Есть ли жизнь после 1 млрд. записей.
PPTX
Tdd php
PPTX
Git for you
PDF
Python и Cython
PDF
Баннерокрутилка на Erlang
PDF
Jiramania презентации @augspb
PDF
Deployment to production with an unexpected load
PDF
Другая виртуализация
PDF
Mobile Fest#spb 2012
PDF
Zero Downtime PHP Deployment with Envoyer And Forge
PDF
Эволюция репликации в MySQL и MariaDB
Deep Dive in Magento DI
Drupal code sprint для новичков
Этюды о буферизации: асинхронные оповещения, репликация обновлений, объединен...
Moscow Python Conf 2016. Почему 100% покрытие это плохо?
Easy authcache 2 кэширование для pro. Родионов Игорь
Easy authcache 2 кеширование для pro родионов игорь
Длинная транзакция или когда размер имеет значение / Михаил Балаян (Odin — In...
SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотек
MySQL: Есть ли жизнь после 1 млрд. записей.
Tdd php
Git for you
Python и Cython
Баннерокрутилка на Erlang
Jiramania презентации @augspb
Deployment to production with an unexpected load
Другая виртуализация
Mobile Fest#spb 2012
Zero Downtime PHP Deployment with Envoyer And Forge
Эволюция репликации в MySQL и MariaDB
Ad

More from Fwdays (20)

PDF
"Mastering UI Complexity: State Machines and Reactive Patterns at Grammarly",...
PDF
"Effect, Fiber & Schema: tactical and technical characteristics of Effect.ts"...
PPTX
"Computer Use Agents: From SFT to Classic RL", Maksym Shamrai
PPTX
"Як ми переписали Сільпо на Angular", Євген Русаков
PDF
"AI Transformation: Directions and Challenges", Pavlo Shaternik
PDF
"Validation and Observability of AI Agents", Oleksandr Denisyuk
PPTX
"Autonomy of LLM Agents: Current State and Future Prospects", Oles` Petriv
PDF
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
PPTX
"Co-Authoring with a Machine: What I Learned from Writing a Book on Generativ...
PPTX
"Human-AI Collaboration Models for Better Decisions, Faster Workflows, and Cr...
PDF
"AI is already here. What will happen to your team (and your role) tomorrow?"...
PPTX
"Is it worth investing in AI in 2025?", Alexander Sharko
PDF
''Taming Explosive Growth: Building Resilience in a Hyper-Scaled Financial Pl...
PDF
"Scaling in space and time with Temporal", Andriy Lupa.pdf
PDF
"Database isolation: how we deal with hundreds of direct connections to the d...
PDF
"Scaling in space and time with Temporal", Andriy Lupa .pdf
PPTX
"Provisioning via DOT-Chain: from catering to drone marketplaces", Volodymyr ...
PPTX
" Observability with Elasticsearch: Best Practices for High-Load Platform", A...
PPTX
"How to survive Black Friday: preparing e-commerce for a peak season", Yurii ...
PPTX
"Istio Ambient Mesh in production: our way from Sidecar to Sidecar-less",Hlib...
"Mastering UI Complexity: State Machines and Reactive Patterns at Grammarly",...
"Effect, Fiber & Schema: tactical and technical characteristics of Effect.ts"...
"Computer Use Agents: From SFT to Classic RL", Maksym Shamrai
"Як ми переписали Сільпо на Angular", Євген Русаков
"AI Transformation: Directions and Challenges", Pavlo Shaternik
"Validation and Observability of AI Agents", Oleksandr Denisyuk
"Autonomy of LLM Agents: Current State and Future Prospects", Oles` Petriv
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
"Co-Authoring with a Machine: What I Learned from Writing a Book on Generativ...
"Human-AI Collaboration Models for Better Decisions, Faster Workflows, and Cr...
"AI is already here. What will happen to your team (and your role) tomorrow?"...
"Is it worth investing in AI in 2025?", Alexander Sharko
''Taming Explosive Growth: Building Resilience in a Hyper-Scaled Financial Pl...
"Scaling in space and time with Temporal", Andriy Lupa.pdf
"Database isolation: how we deal with hundreds of direct connections to the d...
"Scaling in space and time with Temporal", Andriy Lupa .pdf
"Provisioning via DOT-Chain: from catering to drone marketplaces", Volodymyr ...
" Observability with Elasticsearch: Best Practices for High-Load Platform", A...
"How to survive Black Friday: preparing e-commerce for a peak season", Yurii ...
"Istio Ambient Mesh in production: our way from Sidecar to Sidecar-less",Hlib...

Алексей Ильенко "In real-time with Apache Kafka"

  • 2. Agenda ● Быстро про продукт ● Задача и проблема ● Кафка как технология ● Кафка как решение ● Решение задачи ● Результаты ● Проблемы
  • 3. Продукт SignNow ● Отправлять на подпись документы
  • 4. Продукт SignNow ● Отправлять на подпись документы ● Редактировать PDF
  • 5. Продукт SignNow ● Отправлять на подпись документы ● Редактировать PDF ● Отправлять группы документов ● Создавать организации и управлять ими ● Использовать готовые интеграции с SalesForce, Microsoft, etc ● Интегрировать SignNow в собственный продукт используя SignNow Api
  • 6. Задача Api Dashboard для пользователей Signnow API ● Логи ваших вызовов API ● Фильтрация и поиск ● Результаты callback вызовов ● Статистика и биллинг
  • 7. Проблемы ● 100-1000 событий в секунду ● Постоянный рост продукта ● Внезапные всплески событий ● Минимальные задержки ● Сложный бизнес распределенный между микросервисами и легаси монолитом ● Безумный размер событий
  • 8. Быстрое Решение class DocumentController extends Controller { public function get(Request $request) { $document = $factory->getDocument($request->get('id')); $response = new DocumentResponse($document); $loggerService->track($request, $response); return $response; } } В контроллере или где то в Middleware, в другом слое приложения - не важно
  • 9. Недостатки ● Есть легаси где архитектура требует руками выставлять трек ● Из кода синхронно - дополнительное время обработки запроса ● Из кода в очередь - все равно обновлять код. Консистентность кода на микросервисах.
  • 10. Распределенный горизонтально масштабируемый отказоустойчивый лог сообщений. ● Точно не очередь ● Не совсем брокер сообщений ● Не RabbitMQ
  • 13. Отказоустойчивость Кластер Kafka из пяти узлов остается работоспособным, даже если два узла лягут. Даже если 4!
  • 14. Основная Абстракция ● MySQL - таблица ● Storage - файл ● Kafka - ? Лог сообщений (лог коммитов)
  • 15. Old New Новые сообщения попадают в конец Producer ● Producer - поставщик сообщений ● У каждого сообщения есть свой порядковый номер - offset Лог 0 1 2 3 4 5 6 7
  • 16. Сообщение type Message struct { Offset int64 // set by the broker Key []byte Value []byte Timestamp time.Time } ● Offset - позиция сообщения в логе. Устанавливается автоматически брокером.
  • 17. Old New Лог Чтение происходит для каждого получателя с индивудуальной позиции (offset) ● Consumer - получатель сообщения Consumer A (offset x)Consumer B (offset z) Consumer C (offset y)
  • 18. Topic A 0 1 n Лог = партиция топика
  • 19. Сообщение type Message struct { Topic string Partition int32 Offset int64 // set by the broker Key []byte Value []byte Timestamp time.Time }
  • 20. В целом Topic A 0 1 n Consumer A Consumer B Consumer C Producer Topic A 0 1 n Consumer A Producer A Producer B Producer C Consumer B partition = f(key)
  • 21. Consumer Group 1А как же параллелизм? Topic A 0 1 n Consumer 1A Consumer 1B Consumer 1C Producer Consumer Group 2 Consumer 2A Consumer 2B ● Для каждой консьюмер группы оффсет свой. ● Читать с начала или с конкретного оффсета - решать вам!
  • 22. Надежный лог Шардинг из коробки (партиции) ● Гранулярность хранения ● Гранулярность записи (брокер) ● Гранулярность обработки (consumer) Репликация из коробки ● Readwrite из Лидера(Мастреа). Есть возможность указать replication_factor ● Система подтверждений(acks). Можно определить сколько реплик должны сохранить сообщение для подтверждения записи
  • 23. Отказоустойчивость Broker 1 Broker 2 Broker 3 Topic A. Partition 0. Leader Topic A. Partition 0. Follower Topic A. Partition 0. Follower Topic A. Partition 1. LeaderTopic A. Partition 1. Follower Topic A. Partition 1. Follower Topic B. Partition 0. Leader Topic B. Partition 0. FollowerTopic B. Partition 0. Follower Topic B. Partition 1. LeaderTopic B. Partition 1. FollowerTopic B. Partition 1. Follower ● 3 брокера ● 2 топика ● По 2 партиции ● Replication factor 3
  • 24. Отказоустойчивость Broker 1 Broker 2 Broker 3 Topic A. Partition 0. Leader Topic A. Partition 0. Follower Topic A. Partition 0. Follower Topic A. Partition 1. LeaderTopic A. Partition 1. Follower Topic A. Partition 1. Follower Topic B. Partition 0. Leader Topic B. Partition 0. FollowerTopic B. Partition 0. Follower Topic B. Partition 1. LeaderTopic B. Partition 1. FollowerTopic B. Partition 1. Follower ● 3 брокера ● 2 топика ● По 2 партиции ● Replication factor 3
  • 25. Отказоустойчивость Broker 1 Broker 2 Broker 3 Topic A. Partition 0. Leader Topic A. Partition 0. Follower Topic A. Partition 0. Follower Topic A. Partition 1. LeaderTopic A. Partition 1. Leader Topic A. Partition 1. Follower Topic B. Partition 0. Leader Topic B. Partition 0. LeaderTopic B. Partition 0. Follower Topic B. Partition 1. LeaderTopic B. Partition 1. FollowerTopic B. Partition 1. Follower ● Был запущен процесс переизбрания лидера контроллером ● Контроллер - один из брокеров. Назначается автоматически zookeeper`ом
  • 26. Нюанс Добавляя брокеры ничего само не синхронизируется kafka-reassign-partitions.sh ● Добавляет реплику для партиции ● Ждет синхронизации ● При необходимости запускает выборы лидера
  • 27. Обработка ошибок ● Нет механизма отложить плохое сообщение ● Блокироваться на ошибке: retry до успеха ● Перекладывать “плохое” сообщение в отдельный топик ● Перекладывать ”плохое” сообщение в начало текущего топика ● Использовать все и сразу
  • 29. Развернуть самому! Плюсы ● Дешевле в инфраструктуре ● Гибче тюнить ● Можно подключать “плагины” ● Очевиднее Минусы ● Сложно настроить ● Нужны специалисты с опытом (читай дорогие)
  • 30. Купить у confluent.io Плюсы ● PaaS ● Не сильно дорого ● Дашборды, мониторинги ● Продвинутые плагины с установкой в один клик ● KSQL ● Потюнили за вас Минусы ● Не Amazon https://www.confluent.io/confluent-cloud
  • 31. Купить у Microsoft Azure Плюсы ● PaaS Минусы ● Не Amazon ● Очень загадочный https://azure.microsoft.com/ru-ru/services/hdinsight/
  • 32. Купить у Amazon (MSK) Плюсы ● Amazon ● PaaS Минусы ● Тяжело тюнить ● Странная поддержка регионов и зон доступности ● JMX ● ??? https://aws.amazon.com/ru/msk/
  • 33. Как работать? Клиенты ● “Нативно” используя Java. Работает круто. Много информации и примеров. Идеальный вариант. Для мира Java... ● librdkafka. Реализация на C. Поддерживает 90% фичей. Почти официальная поддержка. Много примеров и большое комьюнити. ● “Нативно” через сеть. Боль. Страдание. Унижение. Крайний случай если нет обертки(биндинги) librdkafka под ваш язык, а реализовывать их (обертки) лень дорого.
  • 36. $conf = new RdKafkaConf(); $conf->set('metadata.broker.list', 'localhost:9092'); $conf->set('enable.idempotence', 'true'); $producer = new RdKafkaProducer($conf); $topic = $producer->newTopic("test"); for ($i = 0; $i < 10; $i++) { $topic->produce(RD_KAFKA_PARTITION_UA, 0, "Message $i"); $producer->poll(0); } for ($flushRetries = 0; $flushRetries < 10; $flushRetries++) { $result = $producer->flush(10000); if (RD_KAFKA_RESP_ERR_NO_ERROR === $result) { break; } } if (RD_KAFKA_RESP_ERR_NO_ERROR !== $result) { throw new RuntimeException('Messages might be lost!'); }
  • 38. $conf = new RdKafkaConf(); $conf->set('group.id', 'test'); // Указываем группу $rk = new RdKafkaConsumer($conf); $rk->addBrokers("127.0.0.1"); $topicConf = new RdKafkaTopicConf(); $topicConf->set('auto.commit.interval.ms', 100); $topicConf->set('offset.store.method', 'broker'); $topicConf->set('auto.offset.reset', 'smallest'); $topic = $rk->newTopic("test", $topicConf); $topic->consumeStart(0, RD_KAFKA_OFFSET_STORED); while (true) { $message = $topic->consume(0, 120*10000); switch ($message->err) { case RD_KAFKA_RESP_ERR_NO_ERROR: var_dump($message);break; case RD_KAFKA_RESP_ERR__PARTITION_EOF: echo "No more messages; will wait for moren";break; case RD_KAFKA_RESP_ERR__TIMED_OUT: echo "Timed outn";break; default: throw new Exception($message->errstr(), $message->err);break; } }
  • 39. ● Батчинг ● Обработка ошибок доставкичтения ● Контроль подключения ● Кучу абстракции вокруг
  • 41. Benthos The stream processor for mundane tasks. https://www.benthos.dev/
  • 42. Benthos Source ● kafka ● rabbit ● file ● stdin ● tcp ● redis ● s3 ● http ● custom Processor Target ● kafka ● rabbit ● file ● stdin ● tcp ● redis ● s3 ● http ● custom Более 50 готовых процессоров(обработчиков) для ваших данных. Отфильтровать Json, заменить данными из mysql, зашифроватьрасшифровать, сжать, … Все уже из коробки. Low-code решение Проще говоря Benthos - consumer. Бинарик скомпилированный из Go кода. Заворачиваете в контейнер и запускаете в EC2
  • 43. Benthos + Kafka + SignNow = <3 RequestResponse ES App
  • 46. Результат ● Гибко тюнить workflow ● Легко обновлять consumers ● Проще мониторить проблемы ● Отсутствие задержек ● В любой момент времени можно добавлять новую логику для совсем другой бизнес задачи
  • 47. Мониторинг ● Состояние кластера Kafka. (Для каждого брокера отдельно) ● Диск ● Consumer Lag - показатель того, насколько велика разница между продюсером и консьмером Kafka. ● Amazon CloudWatch ● Linkedin Burrow ● https://github.com/danielqsj/kafka_exporter
  • 50. Анализ ● Входящий поток для топика raw_data не изменился ● Активность в других топиках странно просела
  • 51. Причина ● В партицию топика raw_data попало сообщение размером 1020кб ● Лимит для всех топиков и консьюмеров был установлен в 1024кб ● normalizer consumer прочитал это сообщение из своей партиции топика raw_data ● Обработал и немного увеличил размер сообщения до условных 1025кб ● normalizer при попытке записать сообщение в свой исходящий топик получил ошибку {"@timestamp":"2019-10-28T15:22:33Z","@service":"benthos","level":"ERROR" ,"component":"benthos.output.switch.1.output","message":"Failed to send message to kafka: failed to send 1 parts from message: kafka server: Message was too large, server rejected it to avoid allocation error."} ● В результате normalizer consumer lag начал быстро расти ● Общий лаг системы в пике достиг 60к сообщений
  • 52. Решение ● Увеличили в Кафке для топиков значение параметра max.message.bytes ● Увеличили ограничение размера для исходящих сообщений у всех консьюмеров ● Накинули еще консьюмеров в группы. Суммарно вышло по 4 на топик
  • 53. Будущее SignNow с Kafka ● Swoole ● Async interaction via kafka (RequestReply Pattern)