Understanding Message Delivery Semantics

1. Understanding Delivery Guarantees

Semantic Meaning Tradeoff
At-most-once May lose, never duplicate Commit before process
At-least-once Never lose, may duplicate Commit after process
Exactly-once No loss, no dup Transactions

Example: At-least-once

for (var r : records) process(r);
consumer.commitSync(); // commit AFTER processing

2. Understanding At-Most-Once Delivery

Aspect Description Detail
Order Commit then process Loss on crash
No Dup Never reprocesses Guaranteed
Use Case Metrics where loss is OK Lossy tolerable

Example: At-most-once

consumer.commitSync(); // commit FIRST
for (var r : records) process(r); // crash here = data lost

3. Understanding At-Least-Once Delivery

Aspect Description Detail
Order Process then commit Default pattern
Duplicates Reprocess on crash Need idempotent ops
acks=all Producer durability No loss

Example: At-least-once with idempotent sink

for (var r : records) upsert(r.key(), r.value()); // idempotent
consumer.commitSync();

4. Implementing Exactly-Once Semantics

Mechanism Role Detail
Idempotent Producer No dup on retry Per partition
Transactions Atomic multi-partition write Consume-transform-produce
read_committed Consumer skips aborts End-to-end EOS

Example: Streams exactly-once

props.put("processing.guarantee", "exactly_once_v2");

5. Configuring Producer Idempotence

Config Description Detail
enable.idempotence true Default 3.0+
acks Forced to all Required
PID + Epoch Broker dedup key Per session

Example: Idempotent config

props.put("enable.idempotence", "true");
props.put("acks", "all");

6. Using Transactional Producer

Element Description Detail
transactional.id Stable producer identity Fencing
initTransactions Register and recover Once at start
commit/abort Atomic batch outcome All or nothing

Example: Transactional send

props.put("transactional.id", "tx-1");
producer.initTransactions();
producer.beginTransaction();
producer.send(record);
producer.commitTransaction();

7. Setting Consumer Isolation Level

Level Behavior Use Case
read_uncommitted See aborted records Default
read_committed Only committed transactions EOS
LSO bound Reads stop at last stable offset Tx-aware

Example: Read committed

props.put("isolation.level", "read_committed");

8. Understanding Duplicate Messages

Cause Description Fix
Producer Retry Ack lost, resend Idempotence
Reprocessing Crash before commit Idempotent consumer
Rebalance Uncommitted offsets replayed Commit on revoke

Example: Dedup by key+offset

String id = r.topic() + "-" + r.partition() + "-" + r.offset();
if (seen.add(id)) process(r); // skip duplicates

9. Handling Message Ordering

Aspect Description Detail
Idempotence Preserves order on retry Per partition
EOS Order + no dup Transactions
Key Routing Same key stays ordered Co-located

Example: Ordered EOS pipeline

props.put("enable.idempotence", "true");
props.put("transactional.id", "ordered-tx");

10. Implementing Idempotent Consumer

Strategy Description Detail
Upsert Write keyed, overwrite-safe DB merge
Dedup Store Track processed IDs Redis/DB
Atomic Commit Persist offset with data Same tx

Example: Atomic DB upsert + offset

tx.begin();
db.upsert(r.key(), r.value());
db.saveOffset(r.partition(), r.offset() + 1);
tx.commit(); // exactly-once into DB

11. Understanding Message Loss Scenarios

Scenario Cause Prevention
acks=0/1 Leader fails before replicate acks=all
Unclean Election Stale replica promoted Disable unclean
Early Commit Commit before process Commit after

Example: No-loss producer/topic

# producer: acks=all, enable.idempotence=true
# topic:   min.insync.replicas=2, unclean.leader.election.enable=false