Kafka消息队列

00:00
7 min Intermediate 2026/6/14

Kafka架构设计、Producer/Consumer模型、分区策略、Offset管理与Exactly-Once语义。

1. Kafka架构设计

Kafka 是一个分布式、高吞吐、持久化的消息队列系统,广泛应用于实时数据管道和流处理场景。

1.1 核心架构

┌─────────────────────────────────────────────────────┐
│                    ZooKeeper / KRaft                 │
│              元数据管理 / Controller选举              │
└─────────────────────────────────────────────────────┘
         │                    │
    ┌────┴────┐          ┌───┴────┐
    ▼         ▼          ▼        ▼
┌────────┐┌────────┐┌────────┐┌────────┐
│Broker 0││Broker 1││Broker 2││Broker 3│
│P0-L    ││P0-F    ││P1-L    ││P1-F    │
│P2-F    ││P2-L    ││P3-L    ││P3-F    │
└────────┘└────────┘└────────┘└────────┘
    ▲         ▲          ▲        ▲
    │         │          │        │
┌───┴───┐┌───┴───┐  ┌───┴───┐┌──┴────┐
│Prod-1 ││Prod-2 │  │Cons-1 ││Cons-2 │
└───────┘└───────┘  └───────┘└───────┘

1.2 核心概念

概念说明
BrokerKafka服务节点,负责消息存储和转发
Topic消息的逻辑分类
PartitionTopic的物理分片,有序、不可变日志
Offset消息在Partition中的唯一位置标识
ReplicaPartition的副本,分为Leader和Follower
Consumer Group消费者组,组内消费者共同消费Topic
ISRIn-Sync Replicas,与Leader同步的副本集合

1.3 Topic与Partition

Topic: orders
├── Partition 0: [msg0, msg1, msg2, ...]  Offset: 0, 1, 2, ...
├── Partition 1: [msg0, msg1, msg2, ...]  Offset: 0, 1, 2, ...
├── Partition 2: [msg0, msg1, msg2, ...]  Offset: 0, 1, 2, ...
└── Partition 3: [msg0, msg1, msg2, ...]  Offset: 0, 1, 2, ...
  • 每个Partition是一个有序、不可变、追加写的日志
  • Partition数量决定最大并行度
  • 消息在Partition内有序,跨Partition无序

2. Producer生产者

2.1 发送模式

// 同步发送
RecordMetadata metadata = producer.send(record).get();

// 异步发送
producer.send(record, (metadata, exception) -> {
    if (exception != null) {
        // 处理发送失败
    }
});

// 发送并忘记
producer.send(record);

2.2 分区策略

策略说明适用场景
指定分区record.partition()精确控制
Key哈希hash(key) % numPartitions保证相同Key到同一分区
轮询Round Robin均匀分布
自定义实现 Partitioner 接口业务定制

2.3 ACK确认机制

acks值说明可靠性延迟
0不等待确认最低最低
1Leader确认中等中等
all所有ISR确认最高最高

2.4 幂等生产者

props.put("enable.idempotence", "true");
// 自动设置:
// acks = all
// retries = Integer.MAX_VALUE
// max.in.flight.requests.per.connection <= 5

幂等性保证:单Partition内消息不重复(通过Producer ID + Sequence Number去重)。

3. Consumer消费者

3.1 消费者组

Topic: orders (4 Partitions)

Consumer Group A:
  Consumer-1 ← Partition 0, Partition 1
  Consumer-2 ← Partition 2, Partition 3

Consumer Group B:
  Consumer-3 ← Partition 0, Partition 2
  Consumer-4 ← Partition 1
  Consumer-5 ← Partition 3

核心规则

  • 同一Consumer Group内,一个Partition只能被一个Consumer消费
  • 不同Consumer Group之间互不影响
  • Consumer数量 > Partition数量时,多余Consumer空闲

3.2 Offset管理

策略说明适用场景
自动提交enable.auto.commit=true,定期提交允许少量重复
手动同步提交commitSync()确保提交成功
手动异步提交commitAsync()高吞吐
组合提交异步+同步生产推荐
// 组合提交模式
try {
    while (true) {
        ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
        for (ConsumerRecord<String, String> record : records) {
            process(record);
        }
        consumer.commitAsync(); // 异步提交
    }
} finally {
    consumer.commitSync(); // 关闭前同步确保
    consumer.close();
}

3.3 Rebalance机制

触发条件:Consumer加入/离开Group、订阅Topic变化、Partition变化

Rebalance流程(Consumer Protocol)

1. FindCoordinator → 找到Group Coordinator
2. JoinGroup → Consumer请求加入Group
3. SyncGroup → Leader分配Partition方案,广播给所有成员
4. Heartbeat → 维持组成员关系

分区分配策略

策略算法
Range按Partition编号范围分配可能不均匀
RoundRobin轮询分配均匀
Sticky尽量保持原有分配最小迁移
CooperativeSticky增量式Rebalance避免Stop-The-World

4. Kafka存储与复制

4.1 日志存储

Partition数据目录:
/kafka-logs/topic-0/
├── 00000000000000000000.log     ← 消息数据
├── 00000000000000000000.index   ← 偏移量索引
├── 00000000000000000000.timeindex ← 时间戳索引
├── 00000000000005367851.log
├── 00000000000005367851.index
└── 00000000000005367851.timeindex
  • Segment:每个Partition分为个Segment(默认1GB)
  • 稀疏索引:每4KB消息建立一条索引,平衡索引大小和查询
  • 零拷贝:使用 sendfile() 系统调用,数据直接从磁盘到网卡

4.2 副本与ISR

Partition 0:
  Leader: Broker-1 (ISR)
  Follower: Broker-2 (ISR)
  Follower: Broker-3 (不在ISR,落后太多)

ISR机制

  • ISR = 与Leader保持同步副本集合
  • Follower落后超过 replica.lag.time.max.ms(默认30秒)则移出ISR
  • 当Leader宕机,从ISR中选举新Leader
  • min.insync.replicas:最小ISR数量,与 acks=all 配合使用

数据一致性保证

5. Exactly-Once语义

5.1 三种语义

语义说明实现
At Most Once可能丢失简单
At Least Once可能重复中等
Exactly Once精确一次复杂

5.2 Kafka事务

// 生产者事务
producer.initTransactions();
try {
    producer.beginTransaction();
    producer.send(record1);
    producer.send(record2);
    producer.commitTransaction();
} catch (Exception e) {
    producer.abortTransaction();
}

// 消费-处理-生产 事务(Consume-Transform-Produce)
producer.sendOffsetsToTransaction(
    offsets, consumerGroupId);

5.3 Kafka Streams Exactly-Once

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

通过 Changelog Topic + Transaction 实现端到端Exactly-Once。

6. 性能调优

6.1 Producer调优

参数建议说明
batch.size16KB~64KB批量发送大小
linger.ms5~10ms等待批量填充时间
buffer.memory32MB+发送缓冲区
compression.typelz4/snappy压缩算法

6.2 Consumer调优

参数建议说明
fetch.min.bytes1MB最小拉取字节
fetch.max.wait.ms500ms最大等待时间
max.poll.records500拉取最大记录

6.3 Broker调优

参数建议说明
num.io.threadsCPU核数IO线程数
num.network.threadsCPU核数+1网络线程数
log.segment.bytes1GBSegment大小
log.retention.hours168(7天)日志保留时间

知识检测

学习进度

-- 已学文档
--% 知识覆盖率

学习推荐

专注模式