Kafka 基础介绍

Kafka 基础介绍

一、Kafka 核心概念

1. 整体定位

Apache Kafka 是一个分布式流式平台,最初由 LinkedIn 开发,后成为 Apache 顶级项目。其核心特性包括:

  • 高吞吐:每秒百万级消息处理能力;
  • 持久化:基于磁盘顺序写入,支持 TB 级数据回溯;
  • 高可用:多副本机制 + 自动故障转移;
  • 可扩展:水平扩展 Broker 节点即可提升容量;
  • 实时性:毫秒级端到端延迟。

典型应用场景

  • 日志收集与聚合(替代 Flume/ELK);
  • 用户行为追踪(点击流、埋点);
  • 微服务解耦与事件驱动架构;
  • 实时监控与告警;
  • 数据湖/仓的实时入湖(CDC 场景)。

2. 核心组件

组件 核心作用
Topic 消息的逻辑分类容器,所有消息必须属于某个 Topic。命名建议:业务域.实体.动作(如 order.payment.success)。
Partition(分区) Topic 的物理拆分单元。分区是 Kafka 并行度的核心 :• 每个 Partition 是一个有序、不可变的日志序列;• 分区内消息严格有序;• 分区数决定最大消费并发度;• 只能增加不能减少
Broker Kafka 服务器节点。一个集群由多个 Broker 组成,每个 Broker 可托管多个 Topic 的多个 Partition。
Producer(生产者) 消息发送方。可指定 Key 决定分区路由,支持异步发送、幂等、事务等高级特性。
Consumer(消费者) 消息接收方。从指定 Topic 拉取消息,维护消费位移(offset)。
Consumer Group(消费者组) 多个消费者的逻辑分组:• 同一组内,每个 Partition 仅被一个 Consumer 消费(负载均衡);• 不同组可独立消费同一 Topic(广播模式)。
ZooKeeper / KRaft 元数据协调服务 :• Kafka 2.8 之前 :依赖 ZooKeeper 存储 Broker/Topic/Controller 等元数据;• Kafka 2.8+ :支持 KRaft 模式(Kafka Raft Metadata mode)完全去 ZooKeeper;• 截至 2026 年,新项目推荐评估 KRaft,存量系统多仍用 ZK 模式。

3. 消息结构(Record)

每条 Kafka 消息(Record)包含以下字段:

字段 说明
Key 可选。用于分区路由(相同 Key 进同一 Partition),保证局部顺序。
Value 必填。实际业务数据(如 JSON、Protobuf)。
Timestamp 消息时间戳,可由 Producer 设置或 Broker 自动生成。
Headers 元数据键值对(Kafka 0.11+),常用于传递 traceId、版本号等上下文。
Offset 分区内唯一递增 ID,由 Broker 分配,用于定位消息位置。

4. 分区主从(Leader/Follower)机制

  • Leader Partition :每个 Partition 有且仅有一个 Leader,所有读写请求都通过 Leader
  • Follower Partition:多个副本,仅同步 Leader 数据,不对外提供服务。
  • ISR(In-Sync Replicas)
    • 包含 Leader 和所有与 Leader 同步延迟在阈值内的 Follower;
    • 由参数 replica.lag.time.max.ms(默认 30s)控制;
    • 只有 ISR 中的副本才有资格被选为新 Leader
  • Unclean Leader Election
    • 参数 unclean.leader.election.enable(默认 false);
    • 若设为 true,允许非 ISR 副本成为 Leader → 可能丢数据
    • 生产环境务必保持 false

5. 消息持久化与日志管理

  • Kafka 将每个 Partition 存储为一组 Log Segment 文件(默认 1GB 或 7 天滚动);
  • 利用 顺序 I/O + 零拷贝(sendfile) 实现高吞吐;
  • 支持两种日志清理策略:
    • Delete(默认):按时间或大小删除旧消息;
    • Compact:保留每个 Key 的最新值(适用于状态变更场景,如用户资料更新)。

二、Kafka 基础配置(server.properties)

以下为 config/server.properties 中的关键参数,生产环境务必显式配置

参数 作用 默认值 生产建议
broker.id Broker 唯一标识(整数) 0 集群内唯一
listeners Broker 监听地址 PLAINTEXT://:9092 PLAINTEXT://192.168.1.10:9092
zookeeper.connect ZooKeeper 地址(ZK 模式) localhost:2181 zk1:2181,zk2:2181/kafka
num.partitions 新建 Topic 默认分区数 1 ≥3
default.replication.factor 新建 Topic 默认副本数 1 ≥3(≤ Broker 数)
auto.create.topics.enable 是否自动创建 Topic true false(防误操作)
log.dirs 数据存储目录 /tmp/kafka-logs 使用专用磁盘,如 /data/kafka
offsets.topic.replication.factor __consumer_offsets 副本数 1 ≥3
min.insync.replicas 最小同步副本数 1 2(当 replication.factor=3)
log.retention.hours 消息保留时间(小时) 168(7天) 按业务需求调整
delete.topic.enable 是否允许删除 Topic true true(确保可清理)

可靠性三要素(Producer + Broker):

  • acks=all
  • replication.factor≥3
  • min.insync.replicas=2

三、Kafka 命令行实操

启动集群(ZooKeeper 模式)

bash 复制代码
# 1. 启动 ZooKeeper
bin/zookeeper-server-start.sh config/zookeeper.properties

# 2. 启动 Kafka Broker
bin/kafka-server-start.sh config/server.properties

注意 :KRaft 模式启动方式不同,需使用 kafka-storage.shkafka-server-start.sh --config ...


1. Topic 管理

(1)创建 Topic
bash 复制代码
bin/kafka-topics.sh --create \
  --topic user_events \
  --bootstrap-server localhost:9092 \
  --partitions 6 \
  --replication-factor 3
(2)查看 Topic 列表
bash 复制代码
bin/kafka-topics.sh --list --bootstrap-server localhost:9092
(3)查看 Topic 详情
bash 复制代码
bin/kafka-topics.sh --describe --topic user_events --bootstrap-server localhost:9092
# 输出包含:Partition、Leader、Replicas、ISR
(4)增加分区( 仅能增加)
bash 复制代码
bin/kafka-topics.sh --alter \
  --topic user_events \
  --bootstrap-server localhost:9092 \
  --partitions 9

警告 :扩容后,相同 Key 可能被路由到新分区,破坏顺序性!

(5)删除 Topic
bash 复制代码
bin/kafka-topics.sh --delete --topic user_events --bootstrap-server localhost:9092

2. 消息生产与消费

(1)生产者(Console)
bash 复制代码
bin/kafka-console-producer.sh --topic user_events --bootstrap-server localhost:9092
> {"userId":"1001","event":"login"}
> {"userId":"1002","event":"logout"}
(2)消费者(Console)
bash 复制代码
# 从最新开始
bin/kafka-console-consumer.sh --topic user_events --bootstrap-server localhost:9092

# 从头开始(含历史)
bin/kafka-console-consumer.sh --topic user_events --bootstrap-server localhost:9092 --from-beginning

# 指定消费者组
bin/kafka-console-consumer.sh --topic user_events --bootstrap-server localhost:9092 --group my-group --from-beginning

3. 消费者组管理

(1)列出所有消费者组
bash 复制代码
bin/kafka-consumer-groups.sh --list --bootstrap-server localhost:9092
(2)查看组消费状态(含 Lag)
bash 复制代码
bin/kafka-consumer-groups.sh --describe --group my-group --bootstrap-server localhost:9092
# 关注:CURRENT-OFFSET, LOG-END-OFFSET, LAG
(3)重置消费位移(运维必备)
bash 复制代码
# 重置到最早
bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
  --group my-group --reset-offsets --to-earliest --execute --topic user_events

# 重置到指定时间
bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
  --group my-group --reset-offsets --to-datetime "2026-03-01T00:00:00.000" --execute --topic user_events

4. 集群元信息查看(ZooKeeper 模式)

bash 复制代码
# 查看活跃 Broker
bin/zookeeper-shell.sh localhost:2181 ls /brokers/ids

# 查看 Controller Broker
bin/zookeeper-shell.sh localhost:2181 get /controller

四、SpringBoot 集成 Kafka

1. Maven 依赖(pom.xml)

xml 复制代码
<dependency>
    <groupId>org.springframework.kafka</groupId>
    <artifactId>spring-kafka</artifactId>
    <!-- Spring Boot 2.7+ 对应 spring-kafka 2.9+ -->
</dependency>

2. 核心配置(application.yml)

yaml 复制代码
spring:
  kafka:
    producer:
      bootstrap-servers: localhost:9092
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      value-serializer: org.apache.kafka.common.serialization.StringSerializer
      retries: 2147483647          # Integer.MAX_VALUE,配合幂等
      enable-idempotence: true     # 幂等生产者(防重复)
      acks: all                    # 所有 ISR 副本确认
      batch-size: 16384
      linger-ms: 5
    consumer:
      bootstrap-servers: localhost:9092
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      group-id: user-event-consumer
      auto-offset-reset: earliest
      enable-auto-commit: false    # 关闭自动提交
      max-poll-records: 500        # 单次拉取最大记录数
    listener:
      ack-mode: manual_immediate   # 手动立即提交
      concurrency: 6               # ≈ 分区数

3. 生产者代码(带 Key 与回调)

java 复制代码
@Component
public class KafkaProducer {

    @Resource
    private KafkaTemplate<String, String> kafkaTemplate;

    // 按 userId 分区,保证同一用户事件有序
    public void sendUserEvent(String userId, String eventJson) {
        kafkaTemplate.send("user_events", userId, eventJson)
            .addCallback(
                success -> log.info("发送成功: partition={}, offset={}",
                    success.getRecordMetadata().partition(),
                    success.getRecordMetadata().offset()),
                failure -> log.error("发送失败", failure)
            );
    }
}

4. 消费者代码(手动提交 + DLQ)

java 复制代码
@Component
public class KafkaConsumer {

    @Resource
    private KafkaTemplate<String, String> kafkaTemplate;

    @KafkaListener(topics = "user_events", groupId = "user-event-consumer")
    public void consume(ConsumerRecord<String, String> record, Acknowledgment ack) {
        try {
            // 业务处理
            processEvent(record.key(), record.value());
            ack.acknowledge(); // 成功则提交
        } catch (BusinessException e) {
            // 永久错误:发往死信队列
            kafkaTemplate.send("user_events.dlq", record.key(), record.value());
            ack.acknowledge(); // 避免阻塞
        } catch (Exception e) {
            // 瞬时错误:不 ack,下次重试(需配合 retry)
            log.warn("消费异常,将重试", e);
            throw e; // 触发 listener retry
        }
    }

    private void processEvent(String userId, String event) {
        // 业务逻辑
    }
}

5. 批量消费(高吞吐场景)

java 复制代码
@KafkaListener(topics = "user_events")
public void consumeBatch(List<ConsumerRecord<String, String>> records, Acknowledgment ack) {
    // 批量处理
    records.forEach(this::processEvent);
    ack.acknowledge();
}

需配置 max-poll-records: 1000 控制批量大小。


五、关键原则与最佳实践

1. 可靠性三原则

目标 实现方式
不丢消息 Producer: acks=all + 幂等Broker: replication.factor≥3, min.insync.replicas=2Consumer: 手动提交 offset
不重复消费 Consumer 业务幂等 或 使用 Kafka 事务(Exactly-Once)
顺序性 仅保证单分区内有序;全局有序需单分区(牺牲吞吐)

2. 分区设计建议

  • 初始分区数 ≥ 3;
  • 预估未来 1~2 年吞吐,避免频繁扩容;
  • 使用有意义的 Key(如 userId)保证局部顺序。

3. 监控指标(必看)

  • BrokerUnderReplicatedPartitions(应为 0)
  • Consumerrecords-lag-max(积压量)
  • Producerrecord-error-rate

六、KRaft 模式简介(Kafka 2.8+)

  • 目标:完全移除 ZooKeeper 依赖;
  • 优势:简化架构、提升元数据一致性、更快启动;
  • 状态 :自 Kafka 3.3 起 KRaft 成为默认模式
  • 迁移建议
    • 新项目:直接使用 KRaft;
    • 老项目:谨慎评估迁移成本,可长期运行 ZK 模式。

总结

  1. 核心模型:Topic(逻辑)→ Partition(物理)→ Leader/Follower(高可用);
  2. 可靠性基石acks=all + 多副本 + 手动提交 offset;
  3. 顺序性边界:仅单分区内有序,Key 决定路由;
  4. 生产规范:关闭自动创建 Topic、显式设置副本/分区、监控 Lag;
  5. 未来方向:关注 KRaft 模式演进,逐步去 ZooKeeper。
相关推荐
用户8307196840821 小时前
spring ai alibaba + nacos +mcp 实现mcp服务负载均衡调用实战
spring boot·spring·mcp
Java水解3 小时前
SpringBoot3全栈开发实战:从入门到精通的完整指南
spring boot·后端
初次攀爬者6 小时前
RocketMQ 消息可靠性保障与堆积处理
后端·消息队列·rocketmq
初次攀爬者1 天前
RocketMQ 集群介绍
后端·消息队列·rocketmq
初次攀爬者1 天前
RocketMQ在Spring Boot上的基础使用
java·spring boot·rocketmq
花花无缺1 天前
搞懂@Autowired 与@Resuorce
java·spring boot·后端
初次攀爬者1 天前
RocketMQ 基础学习
后端·消息队列·rocketmq
Derek_Smart1 天前
从一次 OOM 事故说起:打造生产级的 JVM 健康检查组件
java·jvm·spring boot
Nyarlathotep01131 天前
SpringBoot Starter的用法以及原理
java·spring boot