В прошлом уроке мы видели, как после падения участника его партиции переходят к другому. Но с какого места новый участник продолжит чтение? Если с начала, «Гонец» оплатит все заказы второй раз. Если с конца, пропустит те, что ещё не обработаны. Ответ хранит закладка группы, и от того, когда её двигать, зависит, потеряется заказ или придёт дважды.
Закладка в книге
Ты читаешь толстую книгу перед сном. Закладку можно переложить в двух местах: перед тем, как начать главу, или после того, как дочитал её.
Переложил заранее и уснул на середине главы? Утром откроешь книгу на закладке и пропустишь половину главы. Зато ничего не прочтёшь дважды.
Перекладываешь после главы и уснул на середине? Утром начнёшь главу заново и перечитаешь то, что уже читал. Зато ничего не пропустишь.
Третьего способа «ни пропусков, ни повторов» у закладки нет. С Kafka так же.
Закладка группы
У каждой группы на каждой партиции своя закладка. Она называется закоммиченным оффсетом: номер следующей записи, которую группа ещё не обработала. Сдвинуть закладку значит закоммитить оффсет.
Хранит закладки координатор группы в служебном топике __consumer_offsets. Поэтому закладка переживает и падение консьюмера, и перезапуск всего сервиса.
Важно различать два числа:
- позиция это место, до которого консьюмер дочитал в памяти. Она двигается при каждом
poll; - закоммиченный оффсет это то, что сохранено в Kafka. Он двигается только при коммите.
Пока консьюмер жив, он читает с позиции. Упал, и новый участник начнёт с закоммиченного оффсета. Всё между ними будет прочитано снова.
Разница между концом партиции и закладкой группы называется лагом. Его показывает колонка LAG в kafka-consumer-groups --describe, и это главная метрика здоровья консьюмера. Подробно о ней в уроке про мониторинг.
Когда коммитить
Порядок «прочитать, обработать, закоммитить» можно переставить, и от этого зависит семантика доставки:
| Порядок | Что при падении посередине | Название |
|---|---|---|
| коммит, потом обработка | сообщение пропадёт | at-most-once |
| обработка, потом коммит | сообщение обработают ещё раз | at-least-once |
Для «Гонца» потерянный заказ хуже повторного: курьер, которого никто не назначил, хуже уведомления, пришедшего дважды. Поэтому почти всегда выбирают at-least-once и учат обработчик спокойно переживать повторы. Как получить «ровно один раз», разберём в уроке про exactly-once.
урок из курса
Урок из курса «Data Engineering». Курс покупается один раз и остаётся навсегда: 500 ₽.
Оплата пока не подключена: премиум и курсы открываются промокодом.