Может ли нарушаться порядок сообщений в Кафке?
Известно, что Кафка обеспечивает порядок сообщений в рамках партиции. Если мы отправили сообщения в разные партиции одного топика, то гарантии порядка между ними не будет. Но если говорить об одной партиции, может ли нарушиться порядок?
С высоты птичьего полета процесс выглядит так:
Продюсеры отправляют данные -> Брокеры записывают данные на диск -> Консьюмеры забирают данные для обработки.
➡️ Начнем с хранения.
Партиция в Kafka — это последовательный append-only log. Новые сообщения не вставляются в середину и не перезаписывают старые, а просто добавляются в конец файла и так лежат на диске. Брокер не сортирует и не тасует сообщения, поэтому перепутаться непосредственно при хранении не могут.
➡️ Теперь посмотрим на продюсера.
Есть комбинация настроек продюсера, при которой может произойти нарушение порядка:
enable.idempotence=false
retries > 0 //сколько раз продюсер будет переотправлять запрос при ошибке
max.in.flight.requests.per.connection > 1 //сколько запросов продюсер может отправить брокеру, не дожидаясь подтверждения предыдущих
Сценарий такой:
Этот случай прямо описывается в доке Кафки.
Как избежать такой ситуации?
1️⃣ Максимально строгий и простой режим:
max.in.flight.requests.per.connection = 1
Тогда продюсер не будет держать несколько незавершенных запросов одновременно, и сценарий "второй батч записался раньше первого" исчезнет.
➖ Но такая настройка снижает пропускную способность.
2️⃣Включение идемпотентности продюсера и соответствующей ей комбинации настроек:
enable.idempotence = true
retries > 0
max.in.flight.requests.per.connection
Известно, что Кафка обеспечивает порядок сообщений в рамках партиции. Если мы отправили сообщения в разные партиции одного топика, то гарантии порядка между ними не будет. Но если говорить об одной партиции, может ли нарушиться порядок?
С высоты птичьего полета процесс выглядит так:
Продюсеры отправляют данные -> Брокеры записывают данные на диск -> Консьюмеры забирают данные для обработки.
➡️ Начнем с хранения.
Партиция в Kafka — это последовательный append-only log. Новые сообщения не вставляются в середину и не перезаписывают старые, а просто добавляются в конец файла и так лежат на диске. Брокер не сортирует и не тасует сообщения, поэтому перепутаться непосредственно при хранении не могут.
➡️ Теперь посмотрим на продюсера.
Есть комбинация настроек продюсера, при которой может произойти нарушение порядка:
enable.idempotence=false
retries > 0 //сколько раз продюсер будет переотправлять запрос при ошибке
max.in.flight.requests.per.connection > 1 //сколько запросов продюсер может отправить брокеру, не дожидаясь подтверждения предыдущих
Сценарий такой:
Исходный порядок сообщений: 1, 2, 3, 4, 5, 6.
1. Продюсер отправляет batch A: сообщения 1, 2, 3
2. Не дожидаясь ответа, отправляет batch B: сообщения 4, 5, 6
3. Batch A з-за кратковременного сбоя не записался или потерялось его подтверждение записи
4. Batch B успешно записался в партицию
5. Продюсер ретраит batch A
6. Batch A успешно записывается позже batch B 😱
В логе Kafka сообщения оказываются записаны в порядке: 4, 5, 6, 1, 2, 3
Этот случай прямо описывается в доке Кафки.
Как избежать такой ситуации?
1️⃣ Максимально строгий и простой режим:
max.in.flight.requests.per.connection = 1
Тогда продюсер не будет держать несколько незавершенных запросов одновременно, и сценарий "второй батч записался раньше первого" исчезнет.
➖ Но такая настройка снижает пропускную способность.
2️⃣Включение идемпотентности продюсера и соответствующей ей комбинации настроек:
enable.idempotence = true
retries > 0
max.in.flight.requests.per.connection