Skip to content
困难

一句话答案

Kafka 精确一次语义:幂等 Producer(PID+序列号去重)+ 事务性写入(跨 Partition 原子)+ 消费端业务幂等。

核心要点

三种消息语义:

语义含义实现难度
At Most Once消息最多被消费一次(可能丢失)最简单
At Least Once消息至少被消费一次(可能重复)较简单
Exactly Once消息恰好被消费一次(不丢不重)最复杂

Kafka Exactly-Once 的两层实现:

1. 生产者幂等性(Idempotent Producer)

properties
enable.idempotence=true  # Kafka 3.0+ 默认开启
  • 每个 Producer 分配唯一的 PID(Producer ID)
  • 每条消息附带单调递增的 Sequence Number
  • Broker 根据 <PID, Partition, SeqNum> 去重,重复的消息不会被写入
  • 范围:仅保证单 Producer、单 Partition、单 Session 的幂等

2. 事务(Transactional Producer + Consumer)

java
// 生产者
producer.initTransactions();
producer.beginTransaction();
try {
    producer.send(record1);
    producer.send(record2);
    producer.sendOffsetsToTransaction(offsets, groupMetadata); // 提交消费位移
    producer.commitTransaction();
} catch (Exception e) {
    producer.abortTransaction();
}

// 消费者
props.put("isolation.level", "read_committed"); // 只读已提交的消息
  • 引入 Transaction Coordinator__transaction_state 内部 Topic
  • 消息写入 + Offset 提交放在同一个事务中
  • 消费者设置 isolation.level=read_committed,只读取已提交事务的消息
  • 范围:保证跨 Partition、跨 Topic 的原子性

实际应用场景:

  • Kafka Streams 内部使用事务实现 Exactly-Once 流处理
  • 消费-处理-生产(consume-transform-produce)模式
追问与易错

追问方向:

  • 这个概念在你的项目中是怎么应用的?
  • 和相关技术/方案相比有什么优劣?
  • 如果出了问题你会怎么排查?

易错点:

  • ❌ 只知道概念不知道原理——面试官会追问底层实现
  • ❌ 缺乏实际使用经验——结合项目场景回答更有说服力

💡 记忆锚点

Exactly-Once分两层:幂等Producer像快递编号(PID+SeqNum,同一单号不重复签收),事务像银行转账(跨账户要么全成功要么全回滚)。消费端仍需业务幂等兜底——Kafka管到Broker不重复,业务层你自己管。