Kafka_深度解析_从架构原理到生产实践

Kafka 深度解析:从架构原理到生产实践

摘要:Apache Kafka 作为当今最流行的分布式流处理平台之一,已经成为现代数据架构的核心组件。本文将从 Kafka 的核心概念出发,深入剖析其底层架构、存储机制、高可用设计以及生产环境中的最佳实践,帮助你构建对 Kafka 的系统性认知。


目录

  1. [Kafka 是什么](#Kafka 是什么)
  2. 核心概念全景图
  3. [Kafka 架构深度解析](#Kafka 架构深度解析)
  4. 消息存储机制:日志与索引
  5. [高可用设计:副本与 ISR](#高可用设计:副本与 ISR)
  6. 生产者原理与优化
  7. [消费者组与 Rebalance](#消费者组与 Rebalance)
  8. 性能优化与调优实践
  9. 典型应用场景
  10. 总结

1. Kafka 是什么

Apache Kafka 最初由 LinkedIn 开发,后捐赠给 Apache 基金会。它不仅仅是一个消息队列,更是一个分布式流处理平台,具备以下三大核心能力:

  1. 发布与订阅:类似于传统消息队列,支持高吞吐量的消息流
  2. 持久化存储:以容错持久化方式存储消息流
  3. 流处理:实时处理发生的消息流

Kafka vs 传统 MQ

特性 Kafka RabbitMQ/ActiveMQ
设计目标 高吞吐量流处理 通用消息队列
消息持久化 核心特性,长时间保留 消费后即删除或短期保留
消费模式 Pull 模式,支持回溯 Push 模式为主
吞吐量 百万级 TPS 万级 TPS
顺序性 Partition 级别严格有序 Queue 级别有序

2. 核心概念全景图

在深入架构之前,我们先梳理 Kafka 的核心概念及其关系:
#mermaid-svg-7kHkSv48PWKK4Ds3{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-7kHkSv48PWKK4Ds3 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-7kHkSv48PWKK4Ds3 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-7kHkSv48PWKK4Ds3 .error-icon{fill:#552222;}#mermaid-svg-7kHkSv48PWKK4Ds3 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-7kHkSv48PWKK4Ds3 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-7kHkSv48PWKK4Ds3 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-7kHkSv48PWKK4Ds3 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-7kHkSv48PWKK4Ds3 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-7kHkSv48PWKK4Ds3 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-7kHkSv48PWKK4Ds3 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-7kHkSv48PWKK4Ds3 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-7kHkSv48PWKK4Ds3 .marker.cross{stroke:#333333;}#mermaid-svg-7kHkSv48PWKK4Ds3 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-7kHkSv48PWKK4Ds3 p{margin:0;}#mermaid-svg-7kHkSv48PWKK4Ds3 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-7kHkSv48PWKK4Ds3 .cluster-label text{fill:#333;}#mermaid-svg-7kHkSv48PWKK4Ds3 .cluster-label span{color:#333;}#mermaid-svg-7kHkSv48PWKK4Ds3 .cluster-label span p{background-color:transparent;}#mermaid-svg-7kHkSv48PWKK4Ds3 .label text,#mermaid-svg-7kHkSv48PWKK4Ds3 span{fill:#333;color:#333;}#mermaid-svg-7kHkSv48PWKK4Ds3 .node rect,#mermaid-svg-7kHkSv48PWKK4Ds3 .node circle,#mermaid-svg-7kHkSv48PWKK4Ds3 .node ellipse,#mermaid-svg-7kHkSv48PWKK4Ds3 .node polygon,#mermaid-svg-7kHkSv48PWKK4Ds3 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-7kHkSv48PWKK4Ds3 .rough-node .label text,#mermaid-svg-7kHkSv48PWKK4Ds3 .node .label text,#mermaid-svg-7kHkSv48PWKK4Ds3 .image-shape .label,#mermaid-svg-7kHkSv48PWKK4Ds3 .icon-shape .label{text-anchor:middle;}#mermaid-svg-7kHkSv48PWKK4Ds3 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-7kHkSv48PWKK4Ds3 .rough-node .label,#mermaid-svg-7kHkSv48PWKK4Ds3 .node .label,#mermaid-svg-7kHkSv48PWKK4Ds3 .image-shape .label,#mermaid-svg-7kHkSv48PWKK4Ds3 .icon-shape .label{text-align:center;}#mermaid-svg-7kHkSv48PWKK4Ds3 .node.clickable{cursor:pointer;}#mermaid-svg-7kHkSv48PWKK4Ds3 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-7kHkSv48PWKK4Ds3 .arrowheadPath{fill:#333333;}#mermaid-svg-7kHkSv48PWKK4Ds3 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-7kHkSv48PWKK4Ds3 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-7kHkSv48PWKK4Ds3 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-7kHkSv48PWKK4Ds3 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-7kHkSv48PWKK4Ds3 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-7kHkSv48PWKK4Ds3 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-7kHkSv48PWKK4Ds3 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-7kHkSv48PWKK4Ds3 .cluster text{fill:#333;}#mermaid-svg-7kHkSv48PWKK4Ds3 .cluster span{color:#333;}#mermaid-svg-7kHkSv48PWKK4Ds3 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-7kHkSv48PWKK4Ds3 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-7kHkSv48PWKK4Ds3 rect.text{fill:none;stroke-width:0;}#mermaid-svg-7kHkSv48PWKK4Ds3 .icon-shape,#mermaid-svg-7kHkSv48PWKK4Ds3 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-7kHkSv48PWKK4Ds3 .icon-shape p,#mermaid-svg-7kHkSv48PWKK4Ds3 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-7kHkSv48PWKK4Ds3 .icon-shape .label rect,#mermaid-svg-7kHkSv48PWKK4Ds3 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-7kHkSv48PWKK4Ds3 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-7kHkSv48PWKK4Ds3 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-7kHkSv48PWKK4Ds3 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Topic-A
Kafka Cluster
Broker 1
Broker 2
Broker 3
Partition 0 Leader B1 Replica B2
Partition 1 Leader B2 Replica B3
Partition 2 Leader B3 Replica B1
Producer
Consumer Group A
Consumer 1
Consumer 2

关键术语

概念 说明
Broker Kafka 服务器节点,负责存储和转发消息
Topic 消息的逻辑分类,类似数据库的表
Partition Topic 的物理分片,实现水平扩展
Offset 消息在 Partition 中的唯一标识(位移)
Producer 消息生产者,向 Topic 发送消息
Consumer 消息消费者,从 Topic 读取消息
Consumer Group 消费者组,组内消费者共同消费一个 Topic
Replication 副本机制,保证数据高可用

3. Kafka 架构深度解析

3.1 整体架构图

#mermaid-svg-mJk8Ok1i48Wkkjk1{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-mJk8Ok1i48Wkkjk1 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .error-icon{fill:#552222;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .marker.cross{stroke:#333333;}#mermaid-svg-mJk8Ok1i48Wkkjk1 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-mJk8Ok1i48Wkkjk1 p{margin:0;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .cluster-label text{fill:#333;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .cluster-label span{color:#333;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .cluster-label span p{background-color:transparent;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .label text,#mermaid-svg-mJk8Ok1i48Wkkjk1 span{fill:#333;color:#333;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .node rect,#mermaid-svg-mJk8Ok1i48Wkkjk1 .node circle,#mermaid-svg-mJk8Ok1i48Wkkjk1 .node ellipse,#mermaid-svg-mJk8Ok1i48Wkkjk1 .node polygon,#mermaid-svg-mJk8Ok1i48Wkkjk1 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .rough-node .label text,#mermaid-svg-mJk8Ok1i48Wkkjk1 .node .label text,#mermaid-svg-mJk8Ok1i48Wkkjk1 .image-shape .label,#mermaid-svg-mJk8Ok1i48Wkkjk1 .icon-shape .label{text-anchor:middle;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .rough-node .label,#mermaid-svg-mJk8Ok1i48Wkkjk1 .node .label,#mermaid-svg-mJk8Ok1i48Wkkjk1 .image-shape .label,#mermaid-svg-mJk8Ok1i48Wkkjk1 .icon-shape .label{text-align:center;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .node.clickable{cursor:pointer;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .arrowheadPath{fill:#333333;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-mJk8Ok1i48Wkkjk1 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-mJk8Ok1i48Wkkjk1 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-mJk8Ok1i48Wkkjk1 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .cluster text{fill:#333;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .cluster span{color:#333;}#mermaid-svg-mJk8Ok1i48Wkkjk1 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-mJk8Ok1i48Wkkjk1 rect.text{fill:none;stroke-width:0;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .icon-shape,#mermaid-svg-mJk8Ok1i48Wkkjk1 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .icon-shape p,#mermaid-svg-mJk8Ok1i48Wkkjk1 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .icon-shape .label rect,#mermaid-svg-mJk8Ok1i48Wkkjk1 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-mJk8Ok1i48Wkkjk1 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-mJk8Ok1i48Wkkjk1 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-mJk8Ok1i48Wkkjk1 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Consumers
Kafka Cluster
Producers
Producer A
Producer B
Producer C
ZooKeeper KRaft Mode
Broker 1 Controller
Broker 2
Broker 3
Consumer Group 1
Consumer Group 2
Consumer 1
Consumer 2
Consumer 3
Consumer 4

3.2 Controller 机制

每个 Kafka 集群中只有一个 Controller Broker,负责:

  • 管理 Partition 的 Leader 选举
  • 监控 Broker 的存活状态
  • 维护集群元数据

当 Controller 宕机时,其他 Broker 会通过 ZooKeeper(或 KRaft)选举新的 Controller。

3.3 KRaft 模式(Kafka 3.0+)

Kafka 逐步去除对 ZooKeeper 的依赖,引入 KRaft(Kafka Raft) 模式:

  • 使用内置的 Raft 共识算法管理元数据
  • 减少外部依赖,简化部署
  • 提升元数据操作的性能和可扩展性

4. 消息存储机制:日志与索引

Kafka 的高性能很大程度上源于其顺序写磁盘的日志存储设计。

4.1 存储结构图解

#mermaid-svg-4fS3sAcEmY3VPjZo{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-4fS3sAcEmY3VPjZo .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-4fS3sAcEmY3VPjZo .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-4fS3sAcEmY3VPjZo .error-icon{fill:#552222;}#mermaid-svg-4fS3sAcEmY3VPjZo .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-4fS3sAcEmY3VPjZo .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-4fS3sAcEmY3VPjZo .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-4fS3sAcEmY3VPjZo .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-4fS3sAcEmY3VPjZo .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-4fS3sAcEmY3VPjZo .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-4fS3sAcEmY3VPjZo .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-4fS3sAcEmY3VPjZo .marker{fill:#333333;stroke:#333333;}#mermaid-svg-4fS3sAcEmY3VPjZo .marker.cross{stroke:#333333;}#mermaid-svg-4fS3sAcEmY3VPjZo svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-4fS3sAcEmY3VPjZo p{margin:0;}#mermaid-svg-4fS3sAcEmY3VPjZo .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-4fS3sAcEmY3VPjZo .cluster-label text{fill:#333;}#mermaid-svg-4fS3sAcEmY3VPjZo .cluster-label span{color:#333;}#mermaid-svg-4fS3sAcEmY3VPjZo .cluster-label span p{background-color:transparent;}#mermaid-svg-4fS3sAcEmY3VPjZo .label text,#mermaid-svg-4fS3sAcEmY3VPjZo span{fill:#333;color:#333;}#mermaid-svg-4fS3sAcEmY3VPjZo .node rect,#mermaid-svg-4fS3sAcEmY3VPjZo .node circle,#mermaid-svg-4fS3sAcEmY3VPjZo .node ellipse,#mermaid-svg-4fS3sAcEmY3VPjZo .node polygon,#mermaid-svg-4fS3sAcEmY3VPjZo .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-4fS3sAcEmY3VPjZo .rough-node .label text,#mermaid-svg-4fS3sAcEmY3VPjZo .node .label text,#mermaid-svg-4fS3sAcEmY3VPjZo .image-shape .label,#mermaid-svg-4fS3sAcEmY3VPjZo .icon-shape .label{text-anchor:middle;}#mermaid-svg-4fS3sAcEmY3VPjZo .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-4fS3sAcEmY3VPjZo .rough-node .label,#mermaid-svg-4fS3sAcEmY3VPjZo .node .label,#mermaid-svg-4fS3sAcEmY3VPjZo .image-shape .label,#mermaid-svg-4fS3sAcEmY3VPjZo .icon-shape .label{text-align:center;}#mermaid-svg-4fS3sAcEmY3VPjZo .node.clickable{cursor:pointer;}#mermaid-svg-4fS3sAcEmY3VPjZo .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-4fS3sAcEmY3VPjZo .arrowheadPath{fill:#333333;}#mermaid-svg-4fS3sAcEmY3VPjZo .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-4fS3sAcEmY3VPjZo .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-4fS3sAcEmY3VPjZo .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-4fS3sAcEmY3VPjZo .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-4fS3sAcEmY3VPjZo .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-4fS3sAcEmY3VPjZo .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-4fS3sAcEmY3VPjZo .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-4fS3sAcEmY3VPjZo .cluster text{fill:#333;}#mermaid-svg-4fS3sAcEmY3VPjZo .cluster span{color:#333;}#mermaid-svg-4fS3sAcEmY3VPjZo div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-4fS3sAcEmY3VPjZo .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-4fS3sAcEmY3VPjZo rect.text{fill:none;stroke-width:0;}#mermaid-svg-4fS3sAcEmY3VPjZo .icon-shape,#mermaid-svg-4fS3sAcEmY3VPjZo .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-4fS3sAcEmY3VPjZo .icon-shape p,#mermaid-svg-4fS3sAcEmY3VPjZo .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-4fS3sAcEmY3VPjZo .icon-shape .label rect,#mermaid-svg-4fS3sAcEmY3VPjZo .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-4fS3sAcEmY3VPjZo .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-4fS3sAcEmY3VPjZo .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-4fS3sAcEmY3VPjZo :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Broker-1-Storage
Topic-Orders
Partition 0
Partition 1
Partition 2
Segment 00000000000000000000.log 1GB
Segment 00000000000003657291.log 1GB
Segment 00000000000007314582.log Active
Index File .index
TimeIndex File .timeindex
Transaction Index .txnindex

4.2 Log Segment 详解

每个 Partition 在物理上被划分为多个 Segment(默认 1GB):

复制代码
/orders-0/
├── 00000000000000000000.log      # 消息数据文件
├── 00000000000000000000.index    # 偏移量索引(稀疏索引)
├── 00000000000000000000.timeindex # 时间戳索引
├── 00000000000003657291.log      # 下一个 Segment
├── 00000000000003657291.index
└── 00000000000003657291.timeindex

关键设计点

  • 顺序追加写:只有最后一个 Segment(Active Segment)可写,避免随机磁盘寻址
  • 稀疏索引:每隔一定字节(默认 4KB)建立一条索引记录,平衡内存占用与查询效率
  • 零拷贝(Zero-Copy) :通过 sendfile 系统调用直接将数据从 Page Cache 发送到网卡

4.3 消息查找流程

Log File Index File Broker Consumer Log File Index File Broker Consumer #mermaid-svg-g4uOpk6gtuGnIoUX{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-g4uOpk6gtuGnIoUX .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-g4uOpk6gtuGnIoUX .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-g4uOpk6gtuGnIoUX .error-icon{fill:#552222;}#mermaid-svg-g4uOpk6gtuGnIoUX .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-g4uOpk6gtuGnIoUX .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-g4uOpk6gtuGnIoUX .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-g4uOpk6gtuGnIoUX .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-g4uOpk6gtuGnIoUX .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-g4uOpk6gtuGnIoUX .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-g4uOpk6gtuGnIoUX .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-g4uOpk6gtuGnIoUX .marker{fill:#333333;stroke:#333333;}#mermaid-svg-g4uOpk6gtuGnIoUX .marker.cross{stroke:#333333;}#mermaid-svg-g4uOpk6gtuGnIoUX svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-g4uOpk6gtuGnIoUX p{margin:0;}#mermaid-svg-g4uOpk6gtuGnIoUX .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-g4uOpk6gtuGnIoUX text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-g4uOpk6gtuGnIoUX .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-g4uOpk6gtuGnIoUX .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-g4uOpk6gtuGnIoUX .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-g4uOpk6gtuGnIoUX .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-g4uOpk6gtuGnIoUX #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-g4uOpk6gtuGnIoUX .sequenceNumber{fill:white;}#mermaid-svg-g4uOpk6gtuGnIoUX #sequencenumber{fill:#333;}#mermaid-svg-g4uOpk6gtuGnIoUX #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-g4uOpk6gtuGnIoUX .messageText{fill:#333;stroke:none;}#mermaid-svg-g4uOpk6gtuGnIoUX .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-g4uOpk6gtuGnIoUX .labelText,#mermaid-svg-g4uOpk6gtuGnIoUX .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-g4uOpk6gtuGnIoUX .loopText,#mermaid-svg-g4uOpk6gtuGnIoUX .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-g4uOpk6gtuGnIoUX .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-g4uOpk6gtuGnIoUX .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-g4uOpk6gtuGnIoUX .noteText,#mermaid-svg-g4uOpk6gtuGnIoUX .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-g4uOpk6gtuGnIoUX .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-g4uOpk6gtuGnIoUX .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-g4uOpk6gtuGnIoUX .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-g4uOpk6gtuGnIoUX .actorPopupMenu{position:absolute;}#mermaid-svg-g4uOpk6gtuGnIoUX .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-g4uOpk6gtuGnIoUX .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-g4uOpk6gtuGnIoUX .actor-man circle,#mermaid-svg-g4uOpk6gtuGnIoUX line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-g4uOpk6gtuGnIoUX :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Fetch Offset 3658000 定位 Segment 3657291 二分查找 Index Offset 3658000 返回物理位置 Position 892341 从 Position 顺序扫描 找到目标消息 返回消息数据


5. 高可用设计:副本与 ISR

5.1 Replication 架构

#mermaid-svg-5IqLv39M8tOh9Cyy{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-5IqLv39M8tOh9Cyy .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-5IqLv39M8tOh9Cyy .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-5IqLv39M8tOh9Cyy .error-icon{fill:#552222;}#mermaid-svg-5IqLv39M8tOh9Cyy .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5IqLv39M8tOh9Cyy .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-5IqLv39M8tOh9Cyy .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5IqLv39M8tOh9Cyy .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5IqLv39M8tOh9Cyy .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-5IqLv39M8tOh9Cyy .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5IqLv39M8tOh9Cyy .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5IqLv39M8tOh9Cyy .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5IqLv39M8tOh9Cyy .marker.cross{stroke:#333333;}#mermaid-svg-5IqLv39M8tOh9Cyy svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5IqLv39M8tOh9Cyy p{margin:0;}#mermaid-svg-5IqLv39M8tOh9Cyy .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-5IqLv39M8tOh9Cyy .cluster-label text{fill:#333;}#mermaid-svg-5IqLv39M8tOh9Cyy .cluster-label span{color:#333;}#mermaid-svg-5IqLv39M8tOh9Cyy .cluster-label span p{background-color:transparent;}#mermaid-svg-5IqLv39M8tOh9Cyy .label text,#mermaid-svg-5IqLv39M8tOh9Cyy span{fill:#333;color:#333;}#mermaid-svg-5IqLv39M8tOh9Cyy .node rect,#mermaid-svg-5IqLv39M8tOh9Cyy .node circle,#mermaid-svg-5IqLv39M8tOh9Cyy .node ellipse,#mermaid-svg-5IqLv39M8tOh9Cyy .node polygon,#mermaid-svg-5IqLv39M8tOh9Cyy .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5IqLv39M8tOh9Cyy .rough-node .label text,#mermaid-svg-5IqLv39M8tOh9Cyy .node .label text,#mermaid-svg-5IqLv39M8tOh9Cyy .image-shape .label,#mermaid-svg-5IqLv39M8tOh9Cyy .icon-shape .label{text-anchor:middle;}#mermaid-svg-5IqLv39M8tOh9Cyy .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-5IqLv39M8tOh9Cyy .rough-node .label,#mermaid-svg-5IqLv39M8tOh9Cyy .node .label,#mermaid-svg-5IqLv39M8tOh9Cyy .image-shape .label,#mermaid-svg-5IqLv39M8tOh9Cyy .icon-shape .label{text-align:center;}#mermaid-svg-5IqLv39M8tOh9Cyy .node.clickable{cursor:pointer;}#mermaid-svg-5IqLv39M8tOh9Cyy .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-5IqLv39M8tOh9Cyy .arrowheadPath{fill:#333333;}#mermaid-svg-5IqLv39M8tOh9Cyy .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-5IqLv39M8tOh9Cyy .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-5IqLv39M8tOh9Cyy .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5IqLv39M8tOh9Cyy .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-5IqLv39M8tOh9Cyy .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5IqLv39M8tOh9Cyy .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-5IqLv39M8tOh9Cyy .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-5IqLv39M8tOh9Cyy .cluster text{fill:#333;}#mermaid-svg-5IqLv39M8tOh9Cyy .cluster span{color:#333;}#mermaid-svg-5IqLv39M8tOh9Cyy div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-5IqLv39M8tOh9Cyy .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-5IqLv39M8tOh9Cyy rect.text{fill:none;stroke-width:0;}#mermaid-svg-5IqLv39M8tOh9Cyy .icon-shape,#mermaid-svg-5IqLv39M8tOh9Cyy .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5IqLv39M8tOh9Cyy .icon-shape p,#mermaid-svg-5IqLv39M8tOh9Cyy .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-5IqLv39M8tOh9Cyy .icon-shape .label rect,#mermaid-svg-5IqLv39M8tOh9Cyy .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5IqLv39M8tOh9Cyy .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-5IqLv39M8tOh9Cyy .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-5IqLv39M8tOh9Cyy :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Partition-0-Replication
Leader Broker 1 处理读写请求
Follower 1 Broker 2 同步数据
Follower 2 Broker 3 同步数据
Producer
Consumer

5.2 ISR(In-Sync Replicas)机制

  • AR(Assigned Replicas):分配给 Partition 的所有副本
  • ISR :与 Leader 保持同步的副本集合(同步滞后不超过 replica.lag.time.max.ms
  • OSR:超出同步阈值的副本(Out-of-Sync Replicas)

关键公式

复制代码
AR = ISR + OSR

Leader 选举策略

  • unclean.leader.election.enable=false(默认):仅从 ISR 中选举 Leader,保证数据不丢失但可用性降低
  • unclean.leader.election.enable=true:允许从 OSR 中选举 Leader,提升可用性但可能丢失数据

5.3 HW 与 LEO

#mermaid-svg-5J8VPCvrmEn6Iu1E{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-5J8VPCvrmEn6Iu1E .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-5J8VPCvrmEn6Iu1E .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-5J8VPCvrmEn6Iu1E .error-icon{fill:#552222;}#mermaid-svg-5J8VPCvrmEn6Iu1E .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5J8VPCvrmEn6Iu1E .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-5J8VPCvrmEn6Iu1E .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5J8VPCvrmEn6Iu1E .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5J8VPCvrmEn6Iu1E .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-5J8VPCvrmEn6Iu1E .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5J8VPCvrmEn6Iu1E .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5J8VPCvrmEn6Iu1E .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5J8VPCvrmEn6Iu1E .marker.cross{stroke:#333333;}#mermaid-svg-5J8VPCvrmEn6Iu1E svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5J8VPCvrmEn6Iu1E p{margin:0;}#mermaid-svg-5J8VPCvrmEn6Iu1E .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-5J8VPCvrmEn6Iu1E .cluster-label text{fill:#333;}#mermaid-svg-5J8VPCvrmEn6Iu1E .cluster-label span{color:#333;}#mermaid-svg-5J8VPCvrmEn6Iu1E .cluster-label span p{background-color:transparent;}#mermaid-svg-5J8VPCvrmEn6Iu1E .label text,#mermaid-svg-5J8VPCvrmEn6Iu1E span{fill:#333;color:#333;}#mermaid-svg-5J8VPCvrmEn6Iu1E .node rect,#mermaid-svg-5J8VPCvrmEn6Iu1E .node circle,#mermaid-svg-5J8VPCvrmEn6Iu1E .node ellipse,#mermaid-svg-5J8VPCvrmEn6Iu1E .node polygon,#mermaid-svg-5J8VPCvrmEn6Iu1E .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5J8VPCvrmEn6Iu1E .rough-node .label text,#mermaid-svg-5J8VPCvrmEn6Iu1E .node .label text,#mermaid-svg-5J8VPCvrmEn6Iu1E .image-shape .label,#mermaid-svg-5J8VPCvrmEn6Iu1E .icon-shape .label{text-anchor:middle;}#mermaid-svg-5J8VPCvrmEn6Iu1E .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-5J8VPCvrmEn6Iu1E .rough-node .label,#mermaid-svg-5J8VPCvrmEn6Iu1E .node .label,#mermaid-svg-5J8VPCvrmEn6Iu1E .image-shape .label,#mermaid-svg-5J8VPCvrmEn6Iu1E .icon-shape .label{text-align:center;}#mermaid-svg-5J8VPCvrmEn6Iu1E .node.clickable{cursor:pointer;}#mermaid-svg-5J8VPCvrmEn6Iu1E .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-5J8VPCvrmEn6Iu1E .arrowheadPath{fill:#333333;}#mermaid-svg-5J8VPCvrmEn6Iu1E .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-5J8VPCvrmEn6Iu1E .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-5J8VPCvrmEn6Iu1E .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5J8VPCvrmEn6Iu1E .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-5J8VPCvrmEn6Iu1E .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5J8VPCvrmEn6Iu1E .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-5J8VPCvrmEn6Iu1E .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-5J8VPCvrmEn6Iu1E .cluster text{fill:#333;}#mermaid-svg-5J8VPCvrmEn6Iu1E .cluster span{color:#333;}#mermaid-svg-5J8VPCvrmEn6Iu1E div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-5J8VPCvrmEn6Iu1E .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-5J8VPCvrmEn6Iu1E rect.text{fill:none;stroke-width:0;}#mermaid-svg-5J8VPCvrmEn6Iu1E .icon-shape,#mermaid-svg-5J8VPCvrmEn6Iu1E .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5J8VPCvrmEn6Iu1E .icon-shape p,#mermaid-svg-5J8VPCvrmEn6Iu1E .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-5J8VPCvrmEn6Iu1E .icon-shape .label rect,#mermaid-svg-5J8VPCvrmEn6Iu1E .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5J8VPCvrmEn6Iu1E .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-5J8VPCvrmEn6Iu1E .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-5J8VPCvrmEn6Iu1E :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Follower-2
Follower-1
Leader
HW 10
LEO 12
Messages 1 to 12
HW 10
LEO 11
HW 10
LEO 10

  • LEO(Log End Offset):副本最后一条消息的 Offset + 1
  • HW(High Watermark):ISR 中所有副本的最小 LEO,消费者只能读取 HW 之前的消息

6. 生产者原理与优化

6.1 生产者发送流程

#mermaid-svg-ww5DuyoihgHHsAR0{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ww5DuyoihgHHsAR0 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ww5DuyoihgHHsAR0 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ww5DuyoihgHHsAR0 .error-icon{fill:#552222;}#mermaid-svg-ww5DuyoihgHHsAR0 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ww5DuyoihgHHsAR0 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ww5DuyoihgHHsAR0 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ww5DuyoihgHHsAR0 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ww5DuyoihgHHsAR0 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ww5DuyoihgHHsAR0 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ww5DuyoihgHHsAR0 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ww5DuyoihgHHsAR0 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ww5DuyoihgHHsAR0 .marker.cross{stroke:#333333;}#mermaid-svg-ww5DuyoihgHHsAR0 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ww5DuyoihgHHsAR0 p{margin:0;}#mermaid-svg-ww5DuyoihgHHsAR0 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ww5DuyoihgHHsAR0 .cluster-label text{fill:#333;}#mermaid-svg-ww5DuyoihgHHsAR0 .cluster-label span{color:#333;}#mermaid-svg-ww5DuyoihgHHsAR0 .cluster-label span p{background-color:transparent;}#mermaid-svg-ww5DuyoihgHHsAR0 .label text,#mermaid-svg-ww5DuyoihgHHsAR0 span{fill:#333;color:#333;}#mermaid-svg-ww5DuyoihgHHsAR0 .node rect,#mermaid-svg-ww5DuyoihgHHsAR0 .node circle,#mermaid-svg-ww5DuyoihgHHsAR0 .node ellipse,#mermaid-svg-ww5DuyoihgHHsAR0 .node polygon,#mermaid-svg-ww5DuyoihgHHsAR0 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ww5DuyoihgHHsAR0 .rough-node .label text,#mermaid-svg-ww5DuyoihgHHsAR0 .node .label text,#mermaid-svg-ww5DuyoihgHHsAR0 .image-shape .label,#mermaid-svg-ww5DuyoihgHHsAR0 .icon-shape .label{text-anchor:middle;}#mermaid-svg-ww5DuyoihgHHsAR0 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ww5DuyoihgHHsAR0 .rough-node .label,#mermaid-svg-ww5DuyoihgHHsAR0 .node .label,#mermaid-svg-ww5DuyoihgHHsAR0 .image-shape .label,#mermaid-svg-ww5DuyoihgHHsAR0 .icon-shape .label{text-align:center;}#mermaid-svg-ww5DuyoihgHHsAR0 .node.clickable{cursor:pointer;}#mermaid-svg-ww5DuyoihgHHsAR0 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ww5DuyoihgHHsAR0 .arrowheadPath{fill:#333333;}#mermaid-svg-ww5DuyoihgHHsAR0 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ww5DuyoihgHHsAR0 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ww5DuyoihgHHsAR0 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ww5DuyoihgHHsAR0 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ww5DuyoihgHHsAR0 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ww5DuyoihgHHsAR0 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ww5DuyoihgHHsAR0 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ww5DuyoihgHHsAR0 .cluster text{fill:#333;}#mermaid-svg-ww5DuyoihgHHsAR0 .cluster span{color:#333;}#mermaid-svg-ww5DuyoihgHHsAR0 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ww5DuyoihgHHsAR0 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ww5DuyoihgHHsAR0 rect.text{fill:none;stroke-width:0;}#mermaid-svg-ww5DuyoihgHHsAR0 .icon-shape,#mermaid-svg-ww5DuyoihgHHsAR0 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ww5DuyoihgHHsAR0 .icon-shape p,#mermaid-svg-ww5DuyoihgHHsAR0 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ww5DuyoihgHHsAR0 .icon-shape .label rect,#mermaid-svg-ww5DuyoihgHHsAR0 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ww5DuyoihgHHsAR0 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ww5DuyoihgHHsAR0 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ww5DuyoihgHHsAR0 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Producer Client
ProducerRecord
序列化器 Serializer
分区器 Partitioner
消息累加器 RecordAccumulator
Sender线程
Broker 1
Broker 2
Broker 3

6.2 分区策略

生产者发送消息时,通过 Partitioner 决定目标 Partition:

  1. 指定 Partition:直接发送到指定分区
  2. 指定 Keyhash(key) % partitionNum,保证相同 Key 的消息顺序性
  3. 未指定 Key (Sticky Partitioner 2.4+):
    • 先粘在一个分区发送一批数据
    • 批次满或超时后切换到下一个分区
    • 避免数据倾斜,提升批处理效率

6.3 ACK 机制与可靠性

acks 配置 说明 可靠性 吞吐量
acks=0 发完即忘,不等待确认 最低 最高
acks=1 等待 Leader 确认 中等 中等
acks=all 等待 ISR 中所有副本确认 最高 最低

最小副本数配置

properties 复制代码
min.insync.replicas=2  # ISR 中至少要有 2 个副本才能写入

配合 acks=all 使用,可防止写入到只有一个 Leader 的危险状态。

6.4 幂等性与事务

幂等性 Producerenable.idempotence=true):

  • 通过 PID(Producer ID)和 Sequence Number 去重
  • 保证单分区、单会话的 Exactly-Once 语义

事务 Producer

  • 支持跨 Partition 的原子写入
  • 配合 Consumer 的 isolation.level=read_committed,实现端到端 Exactly-Once

Broker Transaction Coordinator Producer Broker Transaction Coordinator Producer #mermaid-svg-rdgfW3c5davhfjCu{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-rdgfW3c5davhfjCu .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-rdgfW3c5davhfjCu .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-rdgfW3c5davhfjCu .error-icon{fill:#552222;}#mermaid-svg-rdgfW3c5davhfjCu .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-rdgfW3c5davhfjCu .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-rdgfW3c5davhfjCu .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-rdgfW3c5davhfjCu .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-rdgfW3c5davhfjCu .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-rdgfW3c5davhfjCu .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-rdgfW3c5davhfjCu .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-rdgfW3c5davhfjCu .marker{fill:#333333;stroke:#333333;}#mermaid-svg-rdgfW3c5davhfjCu .marker.cross{stroke:#333333;}#mermaid-svg-rdgfW3c5davhfjCu svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-rdgfW3c5davhfjCu p{margin:0;}#mermaid-svg-rdgfW3c5davhfjCu .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-rdgfW3c5davhfjCu text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-rdgfW3c5davhfjCu .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-rdgfW3c5davhfjCu .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-rdgfW3c5davhfjCu .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-rdgfW3c5davhfjCu .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-rdgfW3c5davhfjCu #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-rdgfW3c5davhfjCu .sequenceNumber{fill:white;}#mermaid-svg-rdgfW3c5davhfjCu #sequencenumber{fill:#333;}#mermaid-svg-rdgfW3c5davhfjCu #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-rdgfW3c5davhfjCu .messageText{fill:#333;stroke:none;}#mermaid-svg-rdgfW3c5davhfjCu .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-rdgfW3c5davhfjCu .labelText,#mermaid-svg-rdgfW3c5davhfjCu .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-rdgfW3c5davhfjCu .loopText,#mermaid-svg-rdgfW3c5davhfjCu .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-rdgfW3c5davhfjCu .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-rdgfW3c5davhfjCu .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-rdgfW3c5davhfjCu .noteText,#mermaid-svg-rdgfW3c5davhfjCu .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-rdgfW3c5davhfjCu .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-rdgfW3c5davhfjCu .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-rdgfW3c5davhfjCu .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-rdgfW3c5davhfjCu .actorPopupMenu{position:absolute;}#mermaid-svg-rdgfW3c5davhfjCu .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-rdgfW3c5davhfjCu .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-rdgfW3c5davhfjCu .actor-man circle,#mermaid-svg-rdgfW3c5davhfjCu line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-rdgfW3c5davhfjCu :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} InitTransactions PID 分配 beginTransaction 发送消息批次 1 发送消息批次 2 sendOffsetsToTransaction commitTransaction 标记事务提交 确认


7. 消费者组与 Rebalance

7.1 消费者组模型

#mermaid-svg-suKvusbGTQovQBtZ{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-suKvusbGTQovQBtZ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-suKvusbGTQovQBtZ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-suKvusbGTQovQBtZ .error-icon{fill:#552222;}#mermaid-svg-suKvusbGTQovQBtZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-suKvusbGTQovQBtZ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-suKvusbGTQovQBtZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-suKvusbGTQovQBtZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-suKvusbGTQovQBtZ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-suKvusbGTQovQBtZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-suKvusbGTQovQBtZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-suKvusbGTQovQBtZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-suKvusbGTQovQBtZ .marker.cross{stroke:#333333;}#mermaid-svg-suKvusbGTQovQBtZ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-suKvusbGTQovQBtZ p{margin:0;}#mermaid-svg-suKvusbGTQovQBtZ .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-suKvusbGTQovQBtZ .cluster-label text{fill:#333;}#mermaid-svg-suKvusbGTQovQBtZ .cluster-label span{color:#333;}#mermaid-svg-suKvusbGTQovQBtZ .cluster-label span p{background-color:transparent;}#mermaid-svg-suKvusbGTQovQBtZ .label text,#mermaid-svg-suKvusbGTQovQBtZ span{fill:#333;color:#333;}#mermaid-svg-suKvusbGTQovQBtZ .node rect,#mermaid-svg-suKvusbGTQovQBtZ .node circle,#mermaid-svg-suKvusbGTQovQBtZ .node ellipse,#mermaid-svg-suKvusbGTQovQBtZ .node polygon,#mermaid-svg-suKvusbGTQovQBtZ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-suKvusbGTQovQBtZ .rough-node .label text,#mermaid-svg-suKvusbGTQovQBtZ .node .label text,#mermaid-svg-suKvusbGTQovQBtZ .image-shape .label,#mermaid-svg-suKvusbGTQovQBtZ .icon-shape .label{text-anchor:middle;}#mermaid-svg-suKvusbGTQovQBtZ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-suKvusbGTQovQBtZ .rough-node .label,#mermaid-svg-suKvusbGTQovQBtZ .node .label,#mermaid-svg-suKvusbGTQovQBtZ .image-shape .label,#mermaid-svg-suKvusbGTQovQBtZ .icon-shape .label{text-align:center;}#mermaid-svg-suKvusbGTQovQBtZ .node.clickable{cursor:pointer;}#mermaid-svg-suKvusbGTQovQBtZ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-suKvusbGTQovQBtZ .arrowheadPath{fill:#333333;}#mermaid-svg-suKvusbGTQovQBtZ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-suKvusbGTQovQBtZ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-suKvusbGTQovQBtZ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-suKvusbGTQovQBtZ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-suKvusbGTQovQBtZ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-suKvusbGTQovQBtZ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-suKvusbGTQovQBtZ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-suKvusbGTQovQBtZ .cluster text{fill:#333;}#mermaid-svg-suKvusbGTQovQBtZ .cluster span{color:#333;}#mermaid-svg-suKvusbGTQovQBtZ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-suKvusbGTQovQBtZ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-suKvusbGTQovQBtZ rect.text{fill:none;stroke-width:0;}#mermaid-svg-suKvusbGTQovQBtZ .icon-shape,#mermaid-svg-suKvusbGTQovQBtZ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-suKvusbGTQovQBtZ .icon-shape p,#mermaid-svg-suKvusbGTQovQBtZ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-suKvusbGTQovQBtZ .icon-shape .label rect,#mermaid-svg-suKvusbGTQovQBtZ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-suKvusbGTQovQBtZ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-suKvusbGTQovQBtZ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-suKvusbGTQovQBtZ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Topic Orders 6 Partitions
Consumer Group Order-Processors
Consumer 1 分配 P0 P1
Consumer 2 分配 P2 P3
Consumer 3 分配 P4 P5
Partition 0
Partition 1
Partition 2
Partition 3
Partition 4
Partition 5

核心规则

  • 一个 Partition 只能被同一个 Consumer Group 内的一个 Consumer 消费
  • 一个 Consumer 可以消费多个 Partition
  • Consumer 数量建议不超过 Partition 数量,否则多余的 Consumer 将空闲

7.2 Rebalance 触发与协议

触发条件

  1. Consumer Group 成员发生变化(加入/离开/崩溃)
  2. Topic 的 Partition 数量发生变化
  3. 消费者主动调用 unsubscribe()

分区分配策略

策略 说明 适用场景
Range(默认) 按 Topic 范围分配,可能不均匀 Partition 数能整除 Consumer 数
RoundRobin 轮询分配,较为均匀 订阅相同 Topic 时
Sticky 尽量保持现有分配,减少迁移 频繁 Rebalance 场景
CooperativeSticky 增量 Rebalance,2.4+ 推荐 大消费组,减少停顿

7.3 Rebalance 过程图解

Group Coordinator Consumer 3 Consumer 2 Consumer 1 Group Coordinator Consumer 3 Consumer 2 Consumer 1 #mermaid-svg-bvH4vYrayawovdiT{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-bvH4vYrayawovdiT .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-bvH4vYrayawovdiT .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-bvH4vYrayawovdiT .error-icon{fill:#552222;}#mermaid-svg-bvH4vYrayawovdiT .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-bvH4vYrayawovdiT .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-bvH4vYrayawovdiT .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-bvH4vYrayawovdiT .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-bvH4vYrayawovdiT .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-bvH4vYrayawovdiT .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-bvH4vYrayawovdiT .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-bvH4vYrayawovdiT .marker{fill:#333333;stroke:#333333;}#mermaid-svg-bvH4vYrayawovdiT .marker.cross{stroke:#333333;}#mermaid-svg-bvH4vYrayawovdiT svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-bvH4vYrayawovdiT p{margin:0;}#mermaid-svg-bvH4vYrayawovdiT .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-bvH4vYrayawovdiT text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-bvH4vYrayawovdiT .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-bvH4vYrayawovdiT .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-bvH4vYrayawovdiT .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-bvH4vYrayawovdiT .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-bvH4vYrayawovdiT #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-bvH4vYrayawovdiT .sequenceNumber{fill:white;}#mermaid-svg-bvH4vYrayawovdiT #sequencenumber{fill:#333;}#mermaid-svg-bvH4vYrayawovdiT #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-bvH4vYrayawovdiT .messageText{fill:#333;stroke:none;}#mermaid-svg-bvH4vYrayawovdiT .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-bvH4vYrayawovdiT .labelText,#mermaid-svg-bvH4vYrayawovdiT .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-bvH4vYrayawovdiT .loopText,#mermaid-svg-bvH4vYrayawovdiT .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-bvH4vYrayawovdiT .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-bvH4vYrayawovdiT .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-bvH4vYrayawovdiT .noteText,#mermaid-svg-bvH4vYrayawovdiT .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-bvH4vYrayawovdiT .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-bvH4vYrayawovdiT .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-bvH4vYrayawovdiT .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-bvH4vYrayawovdiT .actorPopupMenu{position:absolute;}#mermaid-svg-bvH4vYrayawovdiT .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-bvH4vYrayawovdiT .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-bvH4vYrayawovdiT .actor-man circle,#mermaid-svg-bvH4vYrayawovdiT line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-bvH4vYrayawovdiT :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 初始状态 C1消费P0P1 C2消费P2P3 新状态 C1消费P0P1 C2消费P2P3 C3消费P4P5 JoinGroup请求 发现组成员变化触发Rebalance 通知Rebalance 通知Rebalance JoinGroup JoinGroup 选举Leader Consumer 返回成员列表 执行分区分配算法 SyncGroup分配方案 分配结果 P0 P1 分配结果 P2 P3 分配结果 P4 P5

7.4 Offset 管理

消费者通过 __consumer_offsets 内部 Topic 存储消费位移:
#mermaid-svg-gF1fk0bwT1ESFlEN{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-gF1fk0bwT1ESFlEN .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-gF1fk0bwT1ESFlEN .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-gF1fk0bwT1ESFlEN .error-icon{fill:#552222;}#mermaid-svg-gF1fk0bwT1ESFlEN .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-gF1fk0bwT1ESFlEN .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-gF1fk0bwT1ESFlEN .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-gF1fk0bwT1ESFlEN .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-gF1fk0bwT1ESFlEN .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-gF1fk0bwT1ESFlEN .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-gF1fk0bwT1ESFlEN .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-gF1fk0bwT1ESFlEN .marker{fill:#333333;stroke:#333333;}#mermaid-svg-gF1fk0bwT1ESFlEN .marker.cross{stroke:#333333;}#mermaid-svg-gF1fk0bwT1ESFlEN svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-gF1fk0bwT1ESFlEN p{margin:0;}#mermaid-svg-gF1fk0bwT1ESFlEN .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-gF1fk0bwT1ESFlEN .cluster-label text{fill:#333;}#mermaid-svg-gF1fk0bwT1ESFlEN .cluster-label span{color:#333;}#mermaid-svg-gF1fk0bwT1ESFlEN .cluster-label span p{background-color:transparent;}#mermaid-svg-gF1fk0bwT1ESFlEN .label text,#mermaid-svg-gF1fk0bwT1ESFlEN span{fill:#333;color:#333;}#mermaid-svg-gF1fk0bwT1ESFlEN .node rect,#mermaid-svg-gF1fk0bwT1ESFlEN .node circle,#mermaid-svg-gF1fk0bwT1ESFlEN .node ellipse,#mermaid-svg-gF1fk0bwT1ESFlEN .node polygon,#mermaid-svg-gF1fk0bwT1ESFlEN .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-gF1fk0bwT1ESFlEN .rough-node .label text,#mermaid-svg-gF1fk0bwT1ESFlEN .node .label text,#mermaid-svg-gF1fk0bwT1ESFlEN .image-shape .label,#mermaid-svg-gF1fk0bwT1ESFlEN .icon-shape .label{text-anchor:middle;}#mermaid-svg-gF1fk0bwT1ESFlEN .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-gF1fk0bwT1ESFlEN .rough-node .label,#mermaid-svg-gF1fk0bwT1ESFlEN .node .label,#mermaid-svg-gF1fk0bwT1ESFlEN .image-shape .label,#mermaid-svg-gF1fk0bwT1ESFlEN .icon-shape .label{text-align:center;}#mermaid-svg-gF1fk0bwT1ESFlEN .node.clickable{cursor:pointer;}#mermaid-svg-gF1fk0bwT1ESFlEN .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-gF1fk0bwT1ESFlEN .arrowheadPath{fill:#333333;}#mermaid-svg-gF1fk0bwT1ESFlEN .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-gF1fk0bwT1ESFlEN .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-gF1fk0bwT1ESFlEN .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gF1fk0bwT1ESFlEN .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-gF1fk0bwT1ESFlEN .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gF1fk0bwT1ESFlEN .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-gF1fk0bwT1ESFlEN .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-gF1fk0bwT1ESFlEN .cluster text{fill:#333;}#mermaid-svg-gF1fk0bwT1ESFlEN .cluster span{color:#333;}#mermaid-svg-gF1fk0bwT1ESFlEN div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-gF1fk0bwT1ESFlEN .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-gF1fk0bwT1ESFlEN rect.text{fill:none;stroke-width:0;}#mermaid-svg-gF1fk0bwT1ESFlEN .icon-shape,#mermaid-svg-gF1fk0bwT1ESFlEN .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gF1fk0bwT1ESFlEN .icon-shape p,#mermaid-svg-gF1fk0bwT1ESFlEN .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-gF1fk0bwT1ESFlEN .icon-shape .label rect,#mermaid-svg-gF1fk0bwT1ESFlEN .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gF1fk0bwT1ESFlEN .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-gF1fk0bwT1ESFlEN .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-gF1fk0bwT1ESFlEN :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Offset Storage Format
Offset Commit
Consumer
__consumer_offsets Topic
Key group topic partition
Value offset metadata timestamp

提交模式

  • 自动提交enable.auto.commit=true):定期提交,可能重复消费或丢失消息
  • 手动同步提交commitSync()):可靠但阻塞
  • 手动异步提交commitAsync()):非阻塞,可能提交失败
  • 带回调的异步提交:处理提交失败,实现重试

8. 性能优化与调优实践

8.1 生产者优化

properties 复制代码
# 1. 批处理优化
batch.size=32768           # 批次大小 32KB,根据消息大小调整
linger.ms=10               # 等待 10ms 攒批,提升吞吐量
compression.type=lz4       # 启用压缩,降低网络带宽

# 2. 缓冲区优化
buffer.memory=67108864     # 缓冲区 64MB,防止发送阻塞
max.in.flight.requests.per.connection=5  # 允许 5 个未确认请求

# 3. 可靠性配置
acks=1                     # 根据业务需求选择
retries=3                  # 失败重试次数
enable.idempotence=true    # 启用幂等性

8.2 消费者优化

properties 复制代码
# 1. 拉取优化
fetch.min.bytes=50000      # 至少拉取 50KB 才返回
fetch.max.wait.ms=100      # 最多等待 100ms
max.poll.records=500       # 单次拉取最大消息数

# 2. 并行处理
max.poll.interval.ms=300000 # 处理超时时间,防止 Rebalance
session.timeout.ms=10000    # 会话超时
heartbeat.interval.ms=3000  # 心跳间隔(建议为 session.timeout.ms 的 1/3)

8.3 Broker 与 OS 层面优化

properties 复制代码
# server.properties
num.network.threads=8      # 网络线程数
num.io.threads=16          # IO 线程数
log.segment.bytes=1073741824  # Segment 大小 1GB
log.retention.hours=168    # 保留 7 天
log.retention.bytes=-1     # 不限制总大小(或按磁盘容量设置)

操作系统调优

bash 复制代码
# 1. 文件描述符
ulimit -n 100000

# 2. 脏页刷新策略
vm.dirty_background_ratio=5
vm.dirty_ratio=10

# 3. 禁用交换分区或降低 Swappiness
vm.swappiness=1

# 4. 磁盘调度算法(SSD 使用 noop/deadline)
echo noop > /sys/block/sda/queue/scheduler

# 5. 开启 Transparent Huge Pages(谨慎使用)

8.4 监控关键指标

指标 说明 告警阈值建议
UnderReplicatedPartitions 副本不足的分区数 大于 0 立即告警
OfflinePartitions 离线分区数 大于 0 立即告警
ActiveControllerCount Active Controller 数量 不等于 1 立即告警
RequestHandlerAvgIdlePercent IO 线程空闲率 小于 20% 告警
NetworkProcessorAvgIdlePercent 网络线程空闲率 小于 20% 告警
MessagesInPerSec 每秒入站消息数 监控趋势
ConsumerLag 消费者延迟 根据业务 SLA 设定

9. 典型应用场景

9.1 场景对比图

#mermaid-svg-GbytWRCmigfOPLEN{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-GbytWRCmigfOPLEN .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-GbytWRCmigfOPLEN .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-GbytWRCmigfOPLEN .error-icon{fill:#552222;}#mermaid-svg-GbytWRCmigfOPLEN .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-GbytWRCmigfOPLEN .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-GbytWRCmigfOPLEN .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-GbytWRCmigfOPLEN .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-GbytWRCmigfOPLEN .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-GbytWRCmigfOPLEN .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-GbytWRCmigfOPLEN .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-GbytWRCmigfOPLEN .marker{fill:#333333;stroke:#333333;}#mermaid-svg-GbytWRCmigfOPLEN .marker.cross{stroke:#333333;}#mermaid-svg-GbytWRCmigfOPLEN svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-GbytWRCmigfOPLEN p{margin:0;}#mermaid-svg-GbytWRCmigfOPLEN .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-GbytWRCmigfOPLEN .cluster-label text{fill:#333;}#mermaid-svg-GbytWRCmigfOPLEN .cluster-label span{color:#333;}#mermaid-svg-GbytWRCmigfOPLEN .cluster-label span p{background-color:transparent;}#mermaid-svg-GbytWRCmigfOPLEN .label text,#mermaid-svg-GbytWRCmigfOPLEN span{fill:#333;color:#333;}#mermaid-svg-GbytWRCmigfOPLEN .node rect,#mermaid-svg-GbytWRCmigfOPLEN .node circle,#mermaid-svg-GbytWRCmigfOPLEN .node ellipse,#mermaid-svg-GbytWRCmigfOPLEN .node polygon,#mermaid-svg-GbytWRCmigfOPLEN .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-GbytWRCmigfOPLEN .rough-node .label text,#mermaid-svg-GbytWRCmigfOPLEN .node .label text,#mermaid-svg-GbytWRCmigfOPLEN .image-shape .label,#mermaid-svg-GbytWRCmigfOPLEN .icon-shape .label{text-anchor:middle;}#mermaid-svg-GbytWRCmigfOPLEN .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-GbytWRCmigfOPLEN .rough-node .label,#mermaid-svg-GbytWRCmigfOPLEN .node .label,#mermaid-svg-GbytWRCmigfOPLEN .image-shape .label,#mermaid-svg-GbytWRCmigfOPLEN .icon-shape .label{text-align:center;}#mermaid-svg-GbytWRCmigfOPLEN .node.clickable{cursor:pointer;}#mermaid-svg-GbytWRCmigfOPLEN .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-GbytWRCmigfOPLEN .arrowheadPath{fill:#333333;}#mermaid-svg-GbytWRCmigfOPLEN .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-GbytWRCmigfOPLEN .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-GbytWRCmigfOPLEN .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-GbytWRCmigfOPLEN .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-GbytWRCmigfOPLEN .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-GbytWRCmigfOPLEN .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-GbytWRCmigfOPLEN .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-GbytWRCmigfOPLEN .cluster text{fill:#333;}#mermaid-svg-GbytWRCmigfOPLEN .cluster span{color:#333;}#mermaid-svg-GbytWRCmigfOPLEN div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-GbytWRCmigfOPLEN .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-GbytWRCmigfOPLEN rect.text{fill:none;stroke-width:0;}#mermaid-svg-GbytWRCmigfOPLEN .icon-shape,#mermaid-svg-GbytWRCmigfOPLEN .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-GbytWRCmigfOPLEN .icon-shape p,#mermaid-svg-GbytWRCmigfOPLEN .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-GbytWRCmigfOPLEN .icon-shape .label rect,#mermaid-svg-GbytWRCmigfOPLEN .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-GbytWRCmigfOPLEN .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-GbytWRCmigfOPLEN .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-GbytWRCmigfOPLEN :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Stream Processing
Kafka
Kafka Streams Flink
Database
Log Aggregation
App Server 1
Kafka
App Server 2
App Server 3
Elasticsearch
Grafana
Event-Driven Architecture
Order Service
Kafka
Payment Service
Inventory Service
Notification Service

9.2 场景详解

1. 异步解耦

  • 订单系统下单后发送事件到 Kafka
  • 库存、支付、物流系统独立消费处理
  • 系统间解耦,提升可用性和扩展性

2. 日志聚合

  • 应用服务将日志发送到 Kafka
  • ELK(Elasticsearch + Logstash/Beat + Kibana)或 ClickHouse 消费
  • 统一日志收集、检索和分析

3. 流式处理

  • 实时数据管道:ETL 数据清洗与转换
  • 实时监控:异常检测、风控规则引擎
  • 实时推荐:基于用户行为的实时特征计算

4. 事件溯源(Event Sourcing)

  • 将系统状态变更记录为不可变事件流
  • 支持状态回放、审计追踪、系统重建

10. 总结

Kafka 的设计哲学可以概括为:以日志为中心、以分区为扩展单元、以副本为容错手段。理解以下核心要点,你就能在生产环境中游刃有余地使用 Kafka:

参考资料

  • Apache Kafka 官方文档
  • 《Kafka 权威指南》(Kafka: The Definitive Guide)
  • 《深入理解 Kafka:核心设计与实践原理》
  • Kafka Improvement Proposals (KIPs)
相关推荐
陳陈陳1 小时前
🚀 前端流式输出革命:SSE + BFF 架构从零到一实战指南
vue.js·架构·node.js
张永伟营销3 小时前
从SEO到GEO:技术人视角下的生成式引擎优化架构与实践
搜索引擎·ai·架构
小柒儿3363 小时前
AI原生架构:企业IT从“业务数字化”到“AI原生重构”
重构·架构·ai-native
千维百策6664 小时前
云服务性能下降事件分析:高可用架构与可用区疏散实践
架构
EnCi Zheng4 小时前
AI Agent(AI智能体) 记忆管理系统设计 — 从向量库边界到生产级 Memory(记忆) 架构
人工智能·架构
纵有疾風起5 小时前
从OSI到TCP/IP——分层架构的思想根源与模型之争
tcp/ip·计算机网络·架构·osi·408·体系结构·分层
byte_conn5 小时前
高压级联储能通信架构:CAN隔离与光纤中继的选型实战
网络·架构·制造·信息与通信
zcmodeltech6 小时前
智能矿井沙盘模型多系统协同控制系统设计:基于STM32与Modbus RTU的感知-传输-控制一体化方案
服务器·数据库·分布式·stm32·单片机·嵌入式硬件