Kafka: producer, acks, идемпотентность, порядок сообщений
↑ 5.4 Очереди и брокеры: Kafka, RabbitMQ · ← Предыдущая · → Следующая
Зачем это на собесе
Как не потерять и не продублировать сообщение при отправке.
Объяснение
| Параметр | Смысл |
|---|---|
acks=0 | не ждать подтверждения (возможна потеря) |
acks=1 | подтверждает лидер (потеря при падении лидера до репликации) |
acks=all | подтверждают все in-sync реплики (надёжно) |
min.insync.replicas | минимум реплик для успешной записи |
enable.idempotence=true | брокер отбрасывает дубли ретраев продюсера (сессия + sequence) |
retries, delivery.timeout.ms | повторы и общий срок доставки |
linger.ms, batch.size, compression.type | батчинг и пропускная способность |
max.in.flight.requests.per.connection | параллельные неподтверждённые запросы (≤5 при идемпотентности сохраняют порядок) |
Надёжная конфигурация: acks=all + enable.idempotence=true + min.insync.replicas=2 при replication.factor=3.
var config = new ProducerConfig
{
BootstrapServers = "kafka:9092",
Acks = Acks.All,
EnableIdempotence = true,
LingerMs = 5,
CompressionType = CompressionType.Zstd,
};
using var producer = new ProducerBuilder<string, string>(config).Build();
var result = await producer.ProduceAsync("orders", new Message<string, string> { Key = orderId, Value = json }, ct);Транзакции
Транзакционный продюсер атомарно пишет в несколько топиков/партиций и коммитит offset потребителя (exactly-once в связке consume-transform-produce внутри Kafka).
Нюансы и подводные камни
- Идемпотентность продюсера защищает только от дублей в рамках одной сессии продюсера, а не от повторной публикации из приложения.
- Порядок при ретраях теряется без идемпотентности и с большим
max.in.flight. - Ключ определяет партицию; смена ключа ломает порядок.
- Всегда обрабатывайте результат
ProduceAsync(ошибка не молчит). - Слишком большие сообщения (по умолчанию ~1 МБ): передавайте ссылку на объект в хранилище.
Практика
- Сымитируйте падение брокера при
acks=1иacks=all. - Включите идемпотентность и проверьте отсутствие дублей при ретраях.
- Настройте компрессию и батчинг, замерьте throughput.
Вопросы с ответами
Какие настройки нужны для «не потерять сообщение»?
acks=all,min.insync.replicas>=2,replication.factor>=3, идемпотентный продюсер.
Что делает enable.idempotence?
Брокер дедуплицирует повторные отправки одной записи по producer id и sequence number.
Как сохранить порядок событий сущности?
Использовать ключ сущности (одна партиция) и не ломать порядок ретраями.