Kafka Flashcards
(6 cards)
Общее описание, термины
- Кафку можно использовать как брокер сообщений, сервис интеграции разных источников, микросервисов, отделов и пр. в компании
- Продьюсер создаёт сообщение и пишет в топик
- Топики разделены на партиции для масштабирования чтения
- Консьюмер подписан на топик и это новое сообщение читает
- Оффсет обозначает последнее обработанное сообщение в партиции
- Консьюмеры рекомендуется объединять в группы для автоматической балансировки нагрузки
Как хранится offset
Кафка хранит оффсеты в разрезе [topic, partition, consumer_group] в техническом топике __consumer_offsets. Поменяй любую составляющую, получишь другой оффсет.
Consumer group, масштабирование чтения
Нужна для увеличения устойчивости и балансировки нагрузки при масштабировании. Одну партицию читает строго один консьюмер из группы. Консьюмер может читать несколько партиций. Если одно сообщение нужно прочесть несколько раз из разных мест, создай несколько консьюмер групп.
Пусть p — партиция топика, c — консьюмер, g — группа консьюмеров:
1. Вначале p=[p1, p2], g=[c1]: с1 читает из [p1, p2]
2. Добавляем c2 в группу, g=[c1, c2]: p1->c1, p2->c2
3. Добавляем c3 в группу, g=[c1, c2, c3]: c3 простаивает
4. Убиваем c1, g=[c2, c3]: p1->c3, p2->c2
5. Добавляем 2 партиции, p=[p1, p2, p3, p4]: [p1, p3]->c3, [p2, p4]->c2
p.s. новая группа создаётся при конфигурации консьюмера просто указанием названия, которое отличается от прошлой группы; отдельных команд нет
Особенности интеграции с Clickhouse
У клика есть kafka engine – возможность забирать данные из топика кафки без ETL инструментов. При этом, если кликхауз шардирован и реплицирован, то количество партиций в топике должно без остатка делиться на количество серверов CH, иначе возможен перекос данных из-за логики выбора партиции. Подробнее в докладе (рекомендую вообще целиком глянуть).
Масштабирование записи, подтверждение об успешной записи (Acknowledgements)
Кафка это распределённый сервис (кластер), то есть несколько брокеров. Данные партиции пишутся в Leader брокер, и эти данные реплицируются между Follower брокерами. Количество реплик, которые должны синхронизироваться, настраивается.
Есть несколько режимов подтверждения записи (Acks, Acknowledgements):
* ‘acks=0’ – запись асинхронная, продьюсер не дожидается подтверждения успешной записи
* ‘acks=1’ – запись синхронная, продьюсер дожидается подтверждения “данные зафиксированы” на Leader брокере, но не ожидает успешной репликации на Follower брокеры
* ‘acks=all’ – продьюсер ждёт, пока партиция не запишется на всех репликах
Чем выше значение acks
, тем более надёжная запись, но тем медленнее работает система. Например, если с acks=1
Follower повредится сразу после записи, мы можем потерять сообщение. А с acks=all
оно будет повторно отправлено и/или явно сообщит об ошибке записи.
At most once, At least once, Exactly once delivery
В распределённых системах приходится выбирать, чем мы готовы жертвовать – надёжностью доставки, скоростью доставки или качеством доставки. Выйти из строя может сеть, а также каждый из участников взаимодействия на любом этапе отправки или приёма сообщения.
Например, иногда лучше несколько раз прислать СМС об одобрении кредита, чем не доставить вовсе. А в некоторых случаях мы готовы подождать, чтобы не встречать дубликаты. Или готовы попросить пользователя нажать на кнопку ещё раз, если СМС с кодом затеряется, но зато будем поддерживать миллионы пользователей в день.
Текущий вопрос связан с предыдущим:
* at most once delivery это acks=0
, отправили сообщение и пошли дальше, не переживая о его судьбе
* at least once delivery это acks=1|all
когда мы готовы мириться с дублями, но не хотим терять данные. Если данные записаны, но ошибка произошла на отправке подтверждения, продьюсер повторит отправку => дубль.
* exactly once = at least once + deduplication