上一篇【第02篇】手把手搭建Kafka开发环境——Win/Mac/Linux三平台全攻略下一篇【第04篇】Kafka生产者快速上手——5分钟发出你的第一条消息摘要Kafka好不好用很大程度上取决于你对它核心概念的理解程度。很多人装了Kafka就开始噼里啪啦发消息结果Topic设计不合理、分区乱分配、消费者组搞不清——最后怪Kafka不好用。其实只要把Topic、Partition、Offset、Broker、Producer、Consumer Group这六大概念的关系理顺了Kafka就是一个极其优雅的系统。本文用快递中转站的比喻串起全部概念配合ASCII架构图解和对比表格帮你一次性建立Kafka的完整认知。不堆概念不背定义——你看完就能在脑子里画出Kafka的数据流转全景图。一、快递中转站模型——一个比喻串起全部概念假设你开了一家全国连锁快递公司——“卡夫卡快递”卡夫卡快递中转站 (Kafka Cluster) ┌──────────────────────────────────────────────────────────────┐ │ │ │ ┌─────────────────┐ ┌─────────────────┐ ┌──────────────┐ │ │ │ 北京仓(Broker) │ │ 上海仓(Broker) │ │ 深圳仓(Broker)│ │ │ │ │ │ │ │ │ │ │ │ [A-0] [B-1] │ │ [A-1] [B-0] │ │ [A-2] [B-2] │ │ │ │ [C-0] │ │ [C-1] │ │ │ │ │ └─────────────────┘ └─────────────────┘ └──────────────┘ │ │ ▲ ▲ ▲ │ │ │ │ │ │ │ ┌────┴────┐ ┌───┴───┐ ┌───┴───┐ │ │ │ 寄件人 │ │ 寄件人 │ │ 寄件人 │ │ │ │(Producer)│ │(Producer)│ │(Producer)│ │ │ └─────────┘ └────────┘ └────────┘ │ │ │ │ ┌─────────┐ ┌────────┐ ┌────────┐ │ │ │ 收件人 │ │ 收件人 │ │ 收件人 │ │ │ │(Consumer)│ │(Consumer)│ │(Consumer)│ │ │ └─────────┘ └────────┘ └────────┘ │ │ │ └──────────────────────────────────────────────────────────────┘现在把这个比喻映射到Kafka快递公司概念Kafka概念一句话解释快递公司Kafka Cluster整个消息系统各地仓库Broker存储和处理消息的服务器节点货架区域Topic消息的逻辑分类如订单、“日志”货架编号PartitionTopic的物理分片每个分片是一个有序队列快递单号Offset消息在分区中的唯一序号寄件人Producer往Kafka写消息的应用收件人Consumer从Kafka读消息的应用收件小组Consumer Group一组协同消费的消费者有了这个整体概念我们来逐一把每个概念掰开揉碎。二、Topic主题——消息的分类标签2.1 Topic是什么Topic是Kafka中最核心的概念。你可以把它理解成一个消息的类别名称——就像快递公司的生鲜专区、“文件专区”、大件专区一样不同类型的包裹放在不同的区域。在Kafka中电商系统可能有order-events订单事件、payment-events支付事件日志系统可能有app-logs、access-logs、error-logs监控系统可能有cpu-metrics、memory-metricsTopic本质上是一个逻辑概念它不直接存储数据。真正存储数据的是Partition。2.2 Topic命名最佳实践# ❌ 不推荐的命名 topic1 # 不知道干啥的 test # 太笼统 MyTopic # 大小写混用Kafka不区分但看着乱 # ✅ 推荐的命名 order-events # 清晰明了 app.prod.access-logs # 用点号分层级 payment.events.v2 # 可以带版本号 _schemas # 下划线开头一般用于内部Topic命名规范建议风格示例适用场景kebab-caseorder-events通用推荐清晰可读dot.notationapp.prod.logs多层级分类snake_caseorder_events与数据库命名一致时使用三、Partition分区——Kafka高性能的秘密武器3.1 Partition是什么如果Topic是一个货架区域Partition就是一个个具体的货架。每个Partition是一个有序、不可变的消息序列。Topic: order-events订单事件 │ ├── Partition 0: [msg1] [msg2] [msg3] [msg4] [msg5] →持续追加 │ ↑Offset0 ↑1 ↑2 ↑3 ↑4 │ ├── Partition 1: [msg6] [msg7] [msg8] [msg9] →持续追加 │ ↑0 ↑1 ↑2 ↑3 │ └── Partition 2: [msg10] [msg11] [msg12] →持续追加 ↑0 ↑1 ↑23.2 Partition的核心特性Partition 的三个关键特性 1. 有序性同一个Partition内的消息严格有序按写入先后 分区0: [A→B→C→D] ← A一定在B前面 2. 不可变性消息写入后不能修改只能追加 分区0: [A→B→C] → 写入D → [A→B→C→D] 不能变成: [A→B→X→D] ← X替换C不行 3. 持久性消息写入磁盘后不会丢失可配置副本3.3 为什么要分区一句话分区是Kafka实现水平扩展和并行处理的基础。不分区的后果 ┌──────────────────────────┐ │ Topic: big-topic │ │ [msg1][msg2]...[msg99亿]│ ← 所有消息挤在一条队列里 └───────┬──────────────────┘ │ ┌────▼────┐ │ Consumer │ ← 只有一个消费者能处理累死 └─────────┘ 分区后的好处 ┌──────────────────┐ │ Topic: big-topic │ │ │ │ Partition 0: [1亿条]──→ Consumer 1 │ Partition 1: [1亿条]──→ Consumer 2 │ Partition 2: [1亿条]──→ Consumer 3 │ Partition 3: [1亿条]──→ Consumer 4 └──────────────────┘ 3个分区 3倍并行处理能力3.4 分区数量怎么定这可能是Kafka使用中最常被问的问题。没有万能答案但有几个参考原则因素建议目标吞吐量单个Partition吞吐约10-50MB/s总需求÷单分区吞吐最小分区数消费者并行度分区数至少 消费者数一个分区同一时刻只能被一个消费者消费集群规模分区总数建议不超过Broker数×2000单Broker承受上限约4000个分区未来扩展分区数只能增加不能减少初期可以稍少后续再加血泪教训分区数不能减少创建Topic时想清楚宁可少分一点后续再扩容也比一开始就搞1000个分区强。四、Offset偏移量——每一条消息的身份证号4.1 Offset是什么Offset就是消息在Partition内的唯一序号从0开始递增。它有两个核心作用Partition 0: ┌──────┬──────┬──────┬──────┬──────┬──────┐ │ msg1 │ msg2 │ msg3 │ msg4 │ msg5 │ msg6 │ ... (持续追加) └──────┴──────┴──────┴──────┴──────┴──────┘ Offset: 0 1 2 3 4 5 读取方式 请给我 Partition 0 中 Offset3 及之后的消息 → 返回 msg4, msg5, msg6, ...4.2 Offset的三大妙用作用1精确恢复消费位置 上次消费到Offset100重启后从101继续一条不漏一条不重 作用2消息回溯 消费者可以重置Offset到任意位置重新消费历史数据 kafka-consumer-groups --reset-offsets --to-earliest 作用3监控消费进度 Consumer Lag 最新Offset - 当前消费Offset Lag越大说明消费越跟不上4.3 Offset vs 消息ID对比对比维度Kafka Offset传统MQ的消息ID本质分区内的序号全局唯一ID范围分区级别不同分区有相同的Offset全局唯一有序性天然有序递增无序用途定位消费位置去重、追踪性能极快仅递增计数器需要生成/存储UUID五、Broker代理节点——集群的劳苦功高者5.1 Broker是什么Broker就是运行Kafka服务器进程的物理节点。一个Broker就是一台服务器或一个容器负责接收生产者消息、存储到磁盘、响应消费者读取请求。Kafka Cluster3个Broker ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ Broker 1 │ │ Broker 2 │ │ Broker 3 │ │ node.id1 │ │ node.id2 │ │ node.id3 │ │ │ │ │ │ │ │ Topic-A: P0 │ │ Topic-A: P1 │ │ Topic-A: P2 │ │ Topic-A: P0 │ │ Topic-A: P1 │ │ Topic-A: P2 │ │ (Leader) │ │ (Follower) │ │ (Follower) │ │ │ │ │ │ │ │ Topic-B: P1 │ │ Topic-B: P0 │ │ Topic-B: P2 │ │ (Follower) │ │ (Leader) │ │ (Follower) │ └──────────────┘ └──────────────┘ └──────────────┘5.2 Broker的关键属性属性说明node.id集群内唯一整数ID在配置文件中设定无状态Broker本身不保存我有哪些分区——这个信息由Controller维护通过元数据请求获取对等关系所有Broker地位平等没有主从之分Controller除外自动发现新Broker加入集群后自动被其他节点感知5.3 Controller——Broker中的老大虽然Broker之间是对等的但每个集群有一个特殊的Broker同时承担Controller角色。Controller负责Controller的职责 1. 分区Leader选举哪个分区的Leader挂了立刻选出新Leader 2. Broker上下线处理节点加入/离开时重新分配分区 3. Topic管理创建/删除Topic时分配分区到Broker 4. 元数据维护维护集群状态并分发给所有Broker Controller挂了怎么办 → ZooKeeper或KRaft的Raft组会立刻选举出新的Controller → 整个过程对客户端透明六、Producer生产者与Consumer消费者6.1 Producer发送流程Producer发送消息的完整路径 Producer实例 │ ├── serializer → 把对象/字符串序列化为字节数组 ├── partitioner → 决定消息发到哪个Partition默认Hash(key)%分区数 │ └── 网络发送 ──→ Broker(Partition Leader) │ ├── 追加到本地日志 ├── Follower异步复制 └── 返回ACK给Producer三种发送方式方式代码特征适用场景发后即忘producer.send(record)不关心结果如日志收集同步发送producer.send(record).get()需要确认发送成功如订单异步回调producer.send(record, callback)兼顾吞吐和可靠性6.2 Consumer Group消费者组——Kafka消费者设计的精髓这是很多人搞混的概念。Consumer Group是Kafka实现消息广播和负载均衡的关键机制。场景1单播模式负载均衡——同一组内互斥消费 Consumer Group 订单处理组 ├── Consumer A → 消费 Partition 0 ├── Consumer B → 消费 Partition 1 └── Consumer C → 消费 Partition 2 规则一条消息只会被组内的一个消费者处理 场景2广播模式发布订阅——不同组各自独立消费 Consumer Group 订单处理组 ├── Consumer A1 → 消费 Partition 0 └── Consumer A2 → 消费 Partition 1 Consumer Group 实时分析组 ├── Consumer B1 → 消费 Partition 0 └── Consumer B2 → 消费 Partition 1 Consumer Group 审计日志组 └── Consumer C1 → 消费所有分区 同一Topic的多条消息被多个组各自消费一次核心规则一个Partition同一时刻只能被同一个Consumer Group内的一个消费者消费。这就是为什么消费者数不能超过分区数——多出来的消费者会空闲。七、六大概念的关系全景图Kafka Cluster ┌──────────────────────────────────────────────────────────────┐ │ │ │ ┌─────────────────┐ ┌─────────────────┐ ┌──────────────┐ │ │ │ Broker 1 │ │ Broker 2 │ │ Broker 3 │ │ │ │ (Controller) │ │ │ │ │ │ │ │ ___________ │ │ ___________ │ │ __________ │ │ │ │ | Topic-A | │ │ | Topic-A | │ │ | Topic-A |│ │ │ │ | P0(Leader)| │ │ | P1(Leader)| │ │ |P2(Leader)|│ │ │ │ |___________| │ │ |___________| │ │ |__________|│ │ │ │ ___________ │ │ ___________ │ │ __________ │ │ │ │ | Topic-B | │ │ | Topic-B | │ │ | Topic-B |│ │ │ │ | P1(Foll.) | │ │ | P0(Leader)| │ │ |P2(Leader)|│ │ │ │ |___________| │ │ |___________| │ │ |__________|│ │ │ └────────┬────────┘ └────────┬────────┘ └──────┬───────┘ │ │ │ │ │ │ └───────────┼────────────────────┼────────────────────┼─────────┘ │ │ │ ┌──────▼──────┐ ┌──────▼──────┐ ┌─────▼──────┐ │ Producer │ │ Producer │ │ Producer │ │ send() │ │ send() │ │ send() │ └─────────────┘ └─────────────┘ └────────────┘ │ │ │ └────────────────────┼────────────────────┘ │ ┌───────────▼───────────┐ │ Consumer Group │ │ ┌────┐┌────┐┌────┐ │ │ │ C1 ││ C2 ││ C3 │ │ │ └────┘└────┘└────┘ │ │ ↓P0 ↓P1 ↓P2 │ └───────────────────────┘这张图浓缩了Kafka设计的所有智慧Topic是逻辑分类Partition是物理实现Producer只关心发到哪个Topic的哪个PartitionConsumer通过Consumer Group协调分区分配Broker是数据的实际承载者Offset是消费进度的书签八、对比表格一次性搞懂容易混淆的概念容易混淆的概念对区别Topic vs PartitionTopic是逻辑分类如订单Partition是物理文件如订单日志文件0一个Topic可以有多个PartitionPartition vs SegmentPartition是逻辑上的有序队列Segment是Partition在磁盘上的物理文件如00000000000000000000.logOffset vs MessageIDOffset是分区内序号从0递增MessageID是全局唯一标识Kafka没有内置消息IDBroker vs ControllerBroker存储数据Controller管理集群元数据。Controller也是一台Broker只不过多了一份管理职责Leader vs FollowerLeader处理读写请求Follower只做备份复制。每个分区只有一个LeaderConsumer vs Consumer GroupConsumer是单个消费者实例Consumer Group是一组协同工作的消费者组内每个分区只有一个消费者ISR vs OSRISR(In-Sync Replicas)同步中的副本OSR(Out-of-Sync Replicas)掉队的副本HW vs LEOHW(High Watermark)消费者可见的最高OffsetLEO(Log End Offset)生产者写入的最新OffsetHW≤LEO本篇小结这六大概念是Kafka的世界观理解它们之间的关系比你记住多少条配置命令都重要Topic是消息的逻辑分类Partition是物理实现——一个Topic可以有N个PartitionPartition是并行处理的基础——分区数决定了消费者的并行度上限Offset是消费进度的书签——有序递增、不可修改、可回溯Broker是数据仓库——负责存储、复制和响应请求Consumer Group是Kafka设计最精妙的地方——同一组内负载均衡不同组间广播消费一个Partition同一时刻只能被组内一个消费者消费——这个限制决定了你的系统架构搞懂了这六个概念下一篇我们就来动手写代码——用Java Producer发出第一条消息上一篇【第02篇】手把手搭建Kafka开发环境——Win/Mac/Linux三平台全攻略下一篇【第04篇】Kafka生产者快速上手——5分钟发出你的第一条消息
【Kafka源码解读和使用指南】第03篇:Kafka核心概念图解——Topic、Partition、Offset、Broker一次看懂
上一篇【第02篇】手把手搭建Kafka开发环境——Win/Mac/Linux三平台全攻略下一篇【第04篇】Kafka生产者快速上手——5分钟发出你的第一条消息摘要Kafka好不好用很大程度上取决于你对它核心概念的理解程度。很多人装了Kafka就开始噼里啪啦发消息结果Topic设计不合理、分区乱分配、消费者组搞不清——最后怪Kafka不好用。其实只要把Topic、Partition、Offset、Broker、Producer、Consumer Group这六大概念的关系理顺了Kafka就是一个极其优雅的系统。本文用快递中转站的比喻串起全部概念配合ASCII架构图解和对比表格帮你一次性建立Kafka的完整认知。不堆概念不背定义——你看完就能在脑子里画出Kafka的数据流转全景图。一、快递中转站模型——一个比喻串起全部概念假设你开了一家全国连锁快递公司——“卡夫卡快递”卡夫卡快递中转站 (Kafka Cluster) ┌──────────────────────────────────────────────────────────────┐ │ │ │ ┌─────────────────┐ ┌─────────────────┐ ┌──────────────┐ │ │ │ 北京仓(Broker) │ │ 上海仓(Broker) │ │ 深圳仓(Broker)│ │ │ │ │ │ │ │ │ │ │ │ [A-0] [B-1] │ │ [A-1] [B-0] │ │ [A-2] [B-2] │ │ │ │ [C-0] │ │ [C-1] │ │ │ │ │ └─────────────────┘ └─────────────────┘ └──────────────┘ │ │ ▲ ▲ ▲ │ │ │ │ │ │ │ ┌────┴────┐ ┌───┴───┐ ┌───┴───┐ │ │ │ 寄件人 │ │ 寄件人 │ │ 寄件人 │ │ │ │(Producer)│ │(Producer)│ │(Producer)│ │ │ └─────────┘ └────────┘ └────────┘ │ │ │ │ ┌─────────┐ ┌────────┐ ┌────────┐ │ │ │ 收件人 │ │ 收件人 │ │ 收件人 │ │ │ │(Consumer)│ │(Consumer)│ │(Consumer)│ │ │ └─────────┘ └────────┘ └────────┘ │ │ │ └──────────────────────────────────────────────────────────────┘现在把这个比喻映射到Kafka快递公司概念Kafka概念一句话解释快递公司Kafka Cluster整个消息系统各地仓库Broker存储和处理消息的服务器节点货架区域Topic消息的逻辑分类如订单、“日志”货架编号PartitionTopic的物理分片每个分片是一个有序队列快递单号Offset消息在分区中的唯一序号寄件人Producer往Kafka写消息的应用收件人Consumer从Kafka读消息的应用收件小组Consumer Group一组协同消费的消费者有了这个整体概念我们来逐一把每个概念掰开揉碎。二、Topic主题——消息的分类标签2.1 Topic是什么Topic是Kafka中最核心的概念。你可以把它理解成一个消息的类别名称——就像快递公司的生鲜专区、“文件专区”、大件专区一样不同类型的包裹放在不同的区域。在Kafka中电商系统可能有order-events订单事件、payment-events支付事件日志系统可能有app-logs、access-logs、error-logs监控系统可能有cpu-metrics、memory-metricsTopic本质上是一个逻辑概念它不直接存储数据。真正存储数据的是Partition。2.2 Topic命名最佳实践# ❌ 不推荐的命名 topic1 # 不知道干啥的 test # 太笼统 MyTopic # 大小写混用Kafka不区分但看着乱 # ✅ 推荐的命名 order-events # 清晰明了 app.prod.access-logs # 用点号分层级 payment.events.v2 # 可以带版本号 _schemas # 下划线开头一般用于内部Topic命名规范建议风格示例适用场景kebab-caseorder-events通用推荐清晰可读dot.notationapp.prod.logs多层级分类snake_caseorder_events与数据库命名一致时使用三、Partition分区——Kafka高性能的秘密武器3.1 Partition是什么如果Topic是一个货架区域Partition就是一个个具体的货架。每个Partition是一个有序、不可变的消息序列。Topic: order-events订单事件 │ ├── Partition 0: [msg1] [msg2] [msg3] [msg4] [msg5] →持续追加 │ ↑Offset0 ↑1 ↑2 ↑3 ↑4 │ ├── Partition 1: [msg6] [msg7] [msg8] [msg9] →持续追加 │ ↑0 ↑1 ↑2 ↑3 │ └── Partition 2: [msg10] [msg11] [msg12] →持续追加 ↑0 ↑1 ↑23.2 Partition的核心特性Partition 的三个关键特性 1. 有序性同一个Partition内的消息严格有序按写入先后 分区0: [A→B→C→D] ← A一定在B前面 2. 不可变性消息写入后不能修改只能追加 分区0: [A→B→C] → 写入D → [A→B→C→D] 不能变成: [A→B→X→D] ← X替换C不行 3. 持久性消息写入磁盘后不会丢失可配置副本3.3 为什么要分区一句话分区是Kafka实现水平扩展和并行处理的基础。不分区的后果 ┌──────────────────────────┐ │ Topic: big-topic │ │ [msg1][msg2]...[msg99亿]│ ← 所有消息挤在一条队列里 └───────┬──────────────────┘ │ ┌────▼────┐ │ Consumer │ ← 只有一个消费者能处理累死 └─────────┘ 分区后的好处 ┌──────────────────┐ │ Topic: big-topic │ │ │ │ Partition 0: [1亿条]──→ Consumer 1 │ Partition 1: [1亿条]──→ Consumer 2 │ Partition 2: [1亿条]──→ Consumer 3 │ Partition 3: [1亿条]──→ Consumer 4 └──────────────────┘ 3个分区 3倍并行处理能力3.4 分区数量怎么定这可能是Kafka使用中最常被问的问题。没有万能答案但有几个参考原则因素建议目标吞吐量单个Partition吞吐约10-50MB/s总需求÷单分区吞吐最小分区数消费者并行度分区数至少 消费者数一个分区同一时刻只能被一个消费者消费集群规模分区总数建议不超过Broker数×2000单Broker承受上限约4000个分区未来扩展分区数只能增加不能减少初期可以稍少后续再加血泪教训分区数不能减少创建Topic时想清楚宁可少分一点后续再扩容也比一开始就搞1000个分区强。四、Offset偏移量——每一条消息的身份证号4.1 Offset是什么Offset就是消息在Partition内的唯一序号从0开始递增。它有两个核心作用Partition 0: ┌──────┬──────┬──────┬──────┬──────┬──────┐ │ msg1 │ msg2 │ msg3 │ msg4 │ msg5 │ msg6 │ ... (持续追加) └──────┴──────┴──────┴──────┴──────┴──────┘ Offset: 0 1 2 3 4 5 读取方式 请给我 Partition 0 中 Offset3 及之后的消息 → 返回 msg4, msg5, msg6, ...4.2 Offset的三大妙用作用1精确恢复消费位置 上次消费到Offset100重启后从101继续一条不漏一条不重 作用2消息回溯 消费者可以重置Offset到任意位置重新消费历史数据 kafka-consumer-groups --reset-offsets --to-earliest 作用3监控消费进度 Consumer Lag 最新Offset - 当前消费Offset Lag越大说明消费越跟不上4.3 Offset vs 消息ID对比对比维度Kafka Offset传统MQ的消息ID本质分区内的序号全局唯一ID范围分区级别不同分区有相同的Offset全局唯一有序性天然有序递增无序用途定位消费位置去重、追踪性能极快仅递增计数器需要生成/存储UUID五、Broker代理节点——集群的劳苦功高者5.1 Broker是什么Broker就是运行Kafka服务器进程的物理节点。一个Broker就是一台服务器或一个容器负责接收生产者消息、存储到磁盘、响应消费者读取请求。Kafka Cluster3个Broker ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ Broker 1 │ │ Broker 2 │ │ Broker 3 │ │ node.id1 │ │ node.id2 │ │ node.id3 │ │ │ │ │ │ │ │ Topic-A: P0 │ │ Topic-A: P1 │ │ Topic-A: P2 │ │ Topic-A: P0 │ │ Topic-A: P1 │ │ Topic-A: P2 │ │ (Leader) │ │ (Follower) │ │ (Follower) │ │ │ │ │ │ │ │ Topic-B: P1 │ │ Topic-B: P0 │ │ Topic-B: P2 │ │ (Follower) │ │ (Leader) │ │ (Follower) │ └──────────────┘ └──────────────┘ └──────────────┘5.2 Broker的关键属性属性说明node.id集群内唯一整数ID在配置文件中设定无状态Broker本身不保存我有哪些分区——这个信息由Controller维护通过元数据请求获取对等关系所有Broker地位平等没有主从之分Controller除外自动发现新Broker加入集群后自动被其他节点感知5.3 Controller——Broker中的老大虽然Broker之间是对等的但每个集群有一个特殊的Broker同时承担Controller角色。Controller负责Controller的职责 1. 分区Leader选举哪个分区的Leader挂了立刻选出新Leader 2. Broker上下线处理节点加入/离开时重新分配分区 3. Topic管理创建/删除Topic时分配分区到Broker 4. 元数据维护维护集群状态并分发给所有Broker Controller挂了怎么办 → ZooKeeper或KRaft的Raft组会立刻选举出新的Controller → 整个过程对客户端透明六、Producer生产者与Consumer消费者6.1 Producer发送流程Producer发送消息的完整路径 Producer实例 │ ├── serializer → 把对象/字符串序列化为字节数组 ├── partitioner → 决定消息发到哪个Partition默认Hash(key)%分区数 │ └── 网络发送 ──→ Broker(Partition Leader) │ ├── 追加到本地日志 ├── Follower异步复制 └── 返回ACK给Producer三种发送方式方式代码特征适用场景发后即忘producer.send(record)不关心结果如日志收集同步发送producer.send(record).get()需要确认发送成功如订单异步回调producer.send(record, callback)兼顾吞吐和可靠性6.2 Consumer Group消费者组——Kafka消费者设计的精髓这是很多人搞混的概念。Consumer Group是Kafka实现消息广播和负载均衡的关键机制。场景1单播模式负载均衡——同一组内互斥消费 Consumer Group 订单处理组 ├── Consumer A → 消费 Partition 0 ├── Consumer B → 消费 Partition 1 └── Consumer C → 消费 Partition 2 规则一条消息只会被组内的一个消费者处理 场景2广播模式发布订阅——不同组各自独立消费 Consumer Group 订单处理组 ├── Consumer A1 → 消费 Partition 0 └── Consumer A2 → 消费 Partition 1 Consumer Group 实时分析组 ├── Consumer B1 → 消费 Partition 0 └── Consumer B2 → 消费 Partition 1 Consumer Group 审计日志组 └── Consumer C1 → 消费所有分区 同一Topic的多条消息被多个组各自消费一次核心规则一个Partition同一时刻只能被同一个Consumer Group内的一个消费者消费。这就是为什么消费者数不能超过分区数——多出来的消费者会空闲。七、六大概念的关系全景图Kafka Cluster ┌──────────────────────────────────────────────────────────────┐ │ │ │ ┌─────────────────┐ ┌─────────────────┐ ┌──────────────┐ │ │ │ Broker 1 │ │ Broker 2 │ │ Broker 3 │ │ │ │ (Controller) │ │ │ │ │ │ │ │ ___________ │ │ ___________ │ │ __________ │ │ │ │ | Topic-A | │ │ | Topic-A | │ │ | Topic-A |│ │ │ │ | P0(Leader)| │ │ | P1(Leader)| │ │ |P2(Leader)|│ │ │ │ |___________| │ │ |___________| │ │ |__________|│ │ │ │ ___________ │ │ ___________ │ │ __________ │ │ │ │ | Topic-B | │ │ | Topic-B | │ │ | Topic-B |│ │ │ │ | P1(Foll.) | │ │ | P0(Leader)| │ │ |P2(Leader)|│ │ │ │ |___________| │ │ |___________| │ │ |__________|│ │ │ └────────┬────────┘ └────────┬────────┘ └──────┬───────┘ │ │ │ │ │ │ └───────────┼────────────────────┼────────────────────┼─────────┘ │ │ │ ┌──────▼──────┐ ┌──────▼──────┐ ┌─────▼──────┐ │ Producer │ │ Producer │ │ Producer │ │ send() │ │ send() │ │ send() │ └─────────────┘ └─────────────┘ └────────────┘ │ │ │ └────────────────────┼────────────────────┘ │ ┌───────────▼───────────┐ │ Consumer Group │ │ ┌────┐┌────┐┌────┐ │ │ │ C1 ││ C2 ││ C3 │ │ │ └────┘└────┘└────┘ │ │ ↓P0 ↓P1 ↓P2 │ └───────────────────────┘这张图浓缩了Kafka设计的所有智慧Topic是逻辑分类Partition是物理实现Producer只关心发到哪个Topic的哪个PartitionConsumer通过Consumer Group协调分区分配Broker是数据的实际承载者Offset是消费进度的书签八、对比表格一次性搞懂容易混淆的概念容易混淆的概念对区别Topic vs PartitionTopic是逻辑分类如订单Partition是物理文件如订单日志文件0一个Topic可以有多个PartitionPartition vs SegmentPartition是逻辑上的有序队列Segment是Partition在磁盘上的物理文件如00000000000000000000.logOffset vs MessageIDOffset是分区内序号从0递增MessageID是全局唯一标识Kafka没有内置消息IDBroker vs ControllerBroker存储数据Controller管理集群元数据。Controller也是一台Broker只不过多了一份管理职责Leader vs FollowerLeader处理读写请求Follower只做备份复制。每个分区只有一个LeaderConsumer vs Consumer GroupConsumer是单个消费者实例Consumer Group是一组协同工作的消费者组内每个分区只有一个消费者ISR vs OSRISR(In-Sync Replicas)同步中的副本OSR(Out-of-Sync Replicas)掉队的副本HW vs LEOHW(High Watermark)消费者可见的最高OffsetLEO(Log End Offset)生产者写入的最新OffsetHW≤LEO本篇小结这六大概念是Kafka的世界观理解它们之间的关系比你记住多少条配置命令都重要Topic是消息的逻辑分类Partition是物理实现——一个Topic可以有N个PartitionPartition是并行处理的基础——分区数决定了消费者的并行度上限Offset是消费进度的书签——有序递增、不可修改、可回溯Broker是数据仓库——负责存储、复制和响应请求Consumer Group是Kafka设计最精妙的地方——同一组内负载均衡不同组间广播消费一个Partition同一时刻只能被组内一个消费者消费——这个限制决定了你的系统架构搞懂了这六个概念下一篇我们就来动手写代码——用Java Producer发出第一条消息上一篇【第02篇】手把手搭建Kafka开发环境——Win/Mac/Linux三平台全攻略下一篇【第04篇】Kafka生产者快速上手——5分钟发出你的第一条消息