Проверяет понимание механизмов обеспечения exactly-once семантики в Kafka и умение применять их на практике.
Exactly-once доставка означает, что каждое сообщение обрабатывается ровно один раз, даже при сбоях сети, перезапусках или повторных попытках. В Kafka это достигается не просто настройкой одного параметра, а комбинацией двух механизмов: идемпотентного продюсера и транзакций. Без них возможны дубликаты или потеря данных.
Идемпотентный продюсер (enable.idempotence=true) присваивает каждому сообщению уникальный номер (sequence number) и идентификатор продюсера (producer id). Брокер отслеживает эти номера и отбрасывает дубликаты, если продюсер повторно отправляет одно и то же сообщение из-за сетевого сбоя. Это устраняет дубликаты на уровне записи в партицию, но не решает проблему атомарности между несколькими партициями или между записью и чтением.
Транзакции позволяют атомарно записывать сообщения в несколько партиций и одновременно обновлять consumer offsets. Это гарантирует, что либо все операции внутри транзакции применяются, либо ни одна. Для этого продюсер должен быть настроен с transactional.id, а consumer должен использовать isolation.level=read_committed, чтобы не видеть незакоммиченные сообщения.
// Продюсер с транзакциями
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("transactional.id", "my-transactional-id");
props.put("enable.idempotence", "true");
KafkaProducer<String, String> producer = new KafkaProducer<>(props);
producer.initTransactions();
try {
producer.beginTransaction();
producer.send(new ProducerRecord<>("orders", "key1", "value1"));
producer.send(new ProducerRecord<>("payments", "key2", "value2"));
producer.commitTransaction();
} catch (Exception e) {
producer.abortTransaction();
}
// Consumer с read_committed
Properties consumerProps = new Properties();
consumerProps.put("isolation.level", "read_committed");
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(consumerProps);Exactly-once критичен в финансовых системах, обработке платежей, системах бронирования и любых сценариях, где дубликаты или потеря данных недопустимы. Однако он добавляет накладные расходы и сложность, поэтому для большинства приложений достаточно at-least-once с идемпотентностью.
Используйте exactly-once только там, где это действительно необходимо, и помните, что правильная настройка требует согласованной работы продюсера, consumer и конфигурации брокера. В остальных случаях предпочтительнее более простые семантики доставки.