一、什么是 Kafka

Apache Kafka 是一个开源的分布式流处理平台,最初由 LinkedIn 开发,2011 年开源。它不仅仅是一个消息队列,更是一个集消息发布/订阅、持久化存储、实时流处理于一体的分布式系统。

简单来说,Kafka 就像是分布式系统的"数据高速公路"——各个系统通过它传输数据,既能异步解耦,又能保证高吞吐和可靠性。

Kafka 的三大核心能力:

能力 说明
发布与订阅 类似消息队列,生产者发送消息,消费者订阅消费
持久化存储 消息持久化到磁盘,可回溯、可重放,不会消费即删除
实时流处理 通过 Kafka Streams / ksqlDB 实现实时计算

核心设计目标:

  • 高吞吐:单集群轻松支持百万级消息/秒
  • 低延迟:毫秒级端到端延迟
  • 可扩展:水平扩展,增加 Broker 即可提升容量
  • 持久化:消息可保留数天甚至永久,支持重复消费
  • 容错性:副本机制保证数据不丢失

二、核心概念

理解 Kafka,首先要理解以下核心概念:

概念 说明
Broker Kafka 集群中的一个节点,负责消息的存储和转发
Topic 消息的逻辑分类,生产者按 Topic 发布消息,消费者按 Topic 订阅
Partition Topic 的物理分区,是分布式存储和并行处理的基本单元
Replica Partition 的副本,分为 Leader(处理读写)和 Follower(同步数据)
Offset 消息在 Partition 中的唯一偏移量,标识消费进度
Consumer Group 消费者组,组内消费者共同消费一个 Topic 的不同 Partition
ISR In-Sync Replicas,与 Leader 保持同步的副本集合

关键理解:

  • 一个 Topic 可以有多个 Partition,分布在不同的 Broker 上
  • 每个 Partition 内部消息有序,跨 Partition 无序
  • 一个 Partition 只能被同一个 Consumer Group 内的一个 Consumer 消费
  • 不同的 Consumer Group 之间互不影响,可以独立消费同一个 Topic

三、架构原理

3.1 数据流转过程

Kafka 的数据流转非常清晰:

Producer → Broker 集群 → Consumer Group
  1. 生产者发送消息:Producer 将消息发送到指定 Topic,Kafka 根据分区策略(如 Key Hash)将消息路由到具体的 Partition
  2. Broker 存储消息:消息被追加写入 Partition 的日志文件(顺序写入),同时 Follower 副本从 Leader 同步数据
  3. 消费者拉取消息:Consumer 从 Partition 的 Leader 副本拉取消息,处理完成后提交 Offset

3.2 分区机制

Partition 是 Kafka 实现水平扩展并行处理的核心:

Topic: order-topic
├── Partition-0 (Broker-1)
├── Partition-1 (Broker-2)
└── Partition-2 (Broker-3)

分区的关键特性:

特性 说明
分区内有序 同一 Partition 的消息按 Offset 严格有序
分区间无序 不同 Partition 之间没有顺序保证
水平扩展 增加 Partition 数量可线性提升吞吐量
并行消费 多个 Consumer 可并行消费不同 Partition

分区数与消费者数的关系:

  • 消费者数 ≤ Partition 数:部分消费者消费多个 Partition
  • 消费者数 = Partition 数:最佳并行度
  • 消费者数 > Partition 数:部分消费者空闲(浪费资源)

3.3 副本机制与 ISR

每个 Partition 可以有多个副本(Replica),分布在不同的 Broker 上:

Partition-0
├── Leader (Broker-1)      ← 处理所有读写请求
├── Follower-1 (Broker-2)  ← 同步 Leader 数据
└── Follower-2 (Broker-3)  ← 同步 Leader 数据

ISR(In-Sync Replicas):

  • ISR 是与 Leader 保持同步的副本集合
  • 同步判定标准:在 replica.lag.time.max.ms(默认 30s)内未落后 Leader
  • 只有 ISR 中的副本才有资格在 Leader 故障时被选举为新 Leader

数据写入流程:

1. Producer 发送消息到 Leader
2. Leader 写入本地日志
3. Follower 从 Leader 拉取并写入本地
4. Follower 向 Leader 返回 ACK
5. Leader 收到 ISR 中过半副本的 ACK 后,向 Producer 返回成功

3.4 Leader 选举

当 Leader 副本所在 Broker 宕机时,Kafka 会从 ISR 中选举新的 Leader:

  1. Controller 检测到 Leader 失效
  2. 从 ISR 中选择一个新的副本作为 Leader
  3. 通知所有相关 Broker 更新元数据
  4. Producer 和 Consumer 自动重定向到新 Leader

四、为什么 Kafka 这么快

Kafka 能够实现百万级 TPS,依赖以下核心设计:

4.1 顺序写入

Kafka 将消息追加写入磁盘(Append-Only),避免了随机 I/O:

磁盘顺序写入速度 ≈ 内存随机写入速度 >> 磁盘随机写入速度

4.2 零拷贝(Zero-Copy)

传统数据传输:磁盘 → 内核缓冲区 → 用户空间 → Socket 缓冲区 → 网卡(4次拷贝)

Kafka 使用 sendfile() 系统调用:磁盘 → 内核缓冲区 → 网卡(2次拷贝)

4.3 页缓存(Page Cache)

Kafka 不自己管理内存,而是利用操作系统的 Page Cache:

  • 消息写入时直接进入 Page Cache,由 OS 异步刷盘
  • 消息读取时优先从 Page Cache 读取,命中率高

4.4 批量与压缩

  • 批量发送:Producer 可以攒一批消息后一次性发送
  • 批量压缩:支持 Snappy、LZ4、Zstd 等压缩算法,减少网络传输

4.5 分段存储

每个 Partition 由多个 Log Segment 组成:

partition-0/
├── 00000000000000000000.log      ← 第 0 ~ 1000 条消息
├── 00000000000000000000.index    ← 偏移量索引
├── 00000000000000000000.timeindex← 时间戳索引
├── 00000000000000368769.log      ← 第 1001 ~ 2000 条消息
└── ...
  • 每个 Segment 默认 1GB,便于管理和清理
  • 通过稀疏索引快速定位消息

五、消费者组与 Rebalance

5.1 消费者组机制

Consumer Group 是 Kafka 实现并行消费消息广播的核心:

Topic: order-topic (3 Partitions)

Consumer Group A (订单处理):
├── Consumer-A1 → Partition-0
├── Consumer-A2 → Partition-1
└── Consumer-A3 → Partition-2

Consumer Group B (数据分析):
├── Consumer-B1 → Partition-0
├── Consumer-B2 → Partition-1
└── Consumer-B3 → Partition-2
  • 同一个 Group 内:一个 Partition 只能被一个 Consumer 消费(负载均衡)
  • 不同 Group 之间:每个 Group 都能消费完整的 Topic(消息广播)

5.2 Rebalance(再平衡)

当 Consumer Group 中的成员发生变化时,会触发 Rebalance:

触发条件:

  • 新 Consumer 加入 Group
  • Consumer 宕机或主动退出
  • Consumer 心跳超时(session.timeout.ms
  • 消费处理超时(max.poll.interval.ms
  • Topic 分区数变化

分区分配策略:

策略 说明
Range 按分区序号范围分配(默认)
RoundRobin 轮询分配所有分区
Sticky 粘性分配,最小化重平衡时的分区移动
CooperativeSticky 协作式粘性分配,避免全量停止

注意:Rebalance 期间 Consumer 无法消费消息,频繁 Rebalance 会影响性能。

六、常见应用场景

6.1 日志收集

Kafka 最初就是为日志收集而生的。将各个服务的日志统一发送到 Kafka,再由下游系统处理:

App Logs → Kafka (log-topic) → Elasticsearch → Kibana
                                    ↓
                                  Hive (离线分析)

优势:

  • 解耦日志产生与存储
  • 高吞吐应对突发流量
  • 日志可重放(修复 ETL 逻辑后重新导入)

6.2 异步解耦与削峰填谷

将耗时操作异步化,主流程无需等待:

用户下单 → 订单服务 → Kafka (order-topic)
                        ├── 库存服务(扣减库存)
                        ├── 积分服务(发放积分)
                        └── 通知服务(发送短信/邮件)

优势:

  • 主流程响应时间缩短
  • 下游系统按需消费,避免被流量冲垮
  • 系统间完全解耦,独立扩展

6.3 实时数据管道(ETL)

Kafka 作为数据管道的中心,连接各个数据源和数据目的地:

MySQL (CDC) → Debezium → Kafka → Kafka Streams → ClickHouse / S3
                                        ↓
                                    Flink (实时计算)

优势:

  • 统一的数据入口和出口
  • 支持多种数据源和数据目的地
  • 数据可回溯、可重放

6.4 流式处理

结合 Kafka Streams 或 Flink,实现实时数据处理:

// 实时统计每小时订单金额
KStream<String, OrderEvent> orders = builder.stream("db.orders");
KTable<Windowed<String>, Double> hourlyRevenue = orders
    .filter((k, v) -> v.getStatus().equals("PAID"))
    .groupBy((k, v) -> v.getStoreId())
    .windowedBy(TimeWindows.of(Duration.ofHours(1)))
    .aggregate(() -> 0.0,
        (storeId, order, total) -> total + order.getAmount());

典型应用:

  • 实时排行榜
  • 实时风控
  • 实时监控告警
  • 实时用户画像

6.5 事件驱动架构

在微服务架构中,服务间通过事件通信:

订单服务 → [订单创建事件] → Kafka
    ├── 库存服务 → [库存扣减事件]
    ├── 支付服务 → [支付完成事件]
    └── 物流服务 → [发货事件]

优势:

  • 服务间完全解耦
  • 支持事件溯源(Event Sourcing)
  • 最终一致性保证

七、分布式安装部署

1. 集群规划

在已有的hadoop1、hadoop2、hadoop3上部署 kafka_2.12-3.5.1

2. 下载安装

  1. 下载地址:https://kafka.apache.org/community/downloads/#351

在这里插入图片描述

  1. 下载完后上传到 /opt/software目录,再 tar 解压到 /opt/module

    cd /opt/software
    tar -zxvf kafka_2.12-3.5.1.tgz -C /opt/module/
    

在这里插入图片描述

3. 配置和分发

  1. 进入解压目录,修改配置文件 server.properties
cd /opt/module/kafka_2.12-3.5.1/config/
vim server.properties
  1. 输入下面内容,注意先注释掉已有的同名配置
#broker的全局唯一编号,不能重复,只能是数字。
broker.id=1

#broker对外暴露的IP和端口 (每个节点单独配置)
advertised.listeners=PLAINTEXT://hadoop1:9092
#处理网络请求的线程数量
num.network.threads=3
#用来处理磁盘IO的线程数量
num.io.threads=8
#发送套接字的缓冲区大小
socket.send.buffer.bytes=102400
#接收套接字的缓冲区大小
socket.receive.buffer.bytes=102400
#请求套接字的缓冲区大小
socket.request.max.bytes=104857600
#kafka运行日志(数据)存放的路径,路径不需要提前创建,kafka自动帮你创建,可以配置多个磁盘路径,路径与路径之间可以用","分隔
log.dirs=/opt/module/kafka_2.12-3.5.1/datas
#topic在当前broker上的分区个数
num.partitions=1
#用来恢复和清理data下数据的线程数量
num.recovery.threads.per.data.dir=1
# 每个topic创建时的副本数,默认时1个副本
offsets.topic.replication.factor=1
#segment文件保留的最长时间,超时将被删除
log.retention.hours=168
#每个segment文件的大小,默认最大1G
log.segment.bytes=1073741824
# 检查过期数据的时间,默认5分钟检查一次是否数据过期
log.retention.check.interval.ms=300000
#配置连接Zookeeper集群地址(在zk根目录下创建/kafka,方便管理)
zookeeper.connect=hadoop1:2181,hadoop2:2181,hadoop3:2181/kafka
  1. 分发安装包

    cd /opt/module
    xsync kafka_2.12-3.5.1
    
  2. 分别在其它hadoop2、hadoop3修改配置文件 server.properties 中的 broker.idadvertised.listeners ,不能重复

在这里插入图片描述
6. 配置环境变量

sudo vim /etc/profile.d/my_env.sh

在文件末尾增加如下内容:

#KAFKA_HOME
export KAFKA_HOME=/opt/module/kafka_2.12-3.5.1
export PATH=$PATH:$KAFKA_HOME/bin

分发环境变量文件,再刷新环境变量

sudo /home/hadoop/bin/xsync /etc/profile.d/my_env.sh
source /etc/profile

4. 集群启停脚本

  1. /home/hadoop/bin 目录下创建脚本
cd ~/bin
vim kf.sh

输入如下内容:

#! /bin/bash

case $1 in
"start"){
    for i in hadoop1 hadoop2 hadoop3
    do
        echo " --------启动 $i Kafka-------"
        ssh $i "/opt/module/kafka_2.12-3.5.1/bin/kafka-server-start.sh -daemon /opt/module/kafka_2.12-3.5.1/config/server.properties"
    done
};;
"stop"){
    for i in hadoop1 hadoop2 hadoop3
    do
        echo " --------停止 $i Kafka-------"
        ssh $i "/opt/module/kafka_2.12-3.5.1/bin/kafka-server-stop.sh "
    done
};;
esac
  1. 增加执行权限,起停集群,kafka依赖zookeeper服务,必须先启动zookeeper
chmod +x kf.sh
zk.sh start
kf.sh start
kf.sh stop
zk.sh stop

在这里插入图片描述

八、 常用终端命令

1. 服务启停命令

脚本名称 完整示例命令 功能作用
kafka-server-start.sh bin/kafka-server-start.sh config/server.properties 前台启动 Kafka Broker 服务
kafka-server-stop.sh bin/kafka-server-stop.sh 优雅关闭 Kafka 服务
zookeeper-server-start.sh bin/zookeeper-server-start.sh config/zookeeper.properties 启动内置 Zookeeper(KRaft 版本无需)
zookeeper-server-stop.sh bin/zookeeper-server-stop.sh 关闭内置 Zookeeper

2. Topic 主题管理

脚本名称 完整示例命令 功能作用
kafka-topics.sh 创建 Topicbin/kafka-topics.sh --create --bootstrap-server 127.0.0.1:9092 --topic test_topic --partitions 3 --replication-factor 2 创建主题,指定分区、副本数
kafka-topics.sh 查看所有 Topicbin/kafka-topics.sh --list --bootstrap-server 127.0.0.1:9092 列出集群全部主题
kafka-topics.sh 查看 Topic 详情bin/kafka-topics.sh --describe --bootstrap-server 127.0.0.1:9092 --topic test_topic 查看分区 Leader、副本、ISR 同步列表
kafka-topics.sh 扩容分区bin/kafka-topics.sh --alter --bootstrap-server 127.0.0.1:9092 --topic test_topic --partitions 5 增加分区(不支持减少分区)
kafka-topics.sh 删除 Topicbin/kafka-topics.sh --delete --bootstrap-server 127.0.0.1:9092 --topic test_topic 删除主题,需开启delete.topic.enable=true

3. 控制台生产者(发送消息)

脚本名称 完整示例命令 功能作用
kafka-console-producer.sh bin/kafka-console-producer.sh --bootstrap-server 127.0.0.1:9092 --topic test_topic 简易控制台发送普通消息
kafka-console-producer.sh 带 Key 发送bin/kafka-console-producer.sh --bootstrap-server 127.0.0.1:9092 --topic test_topic --property parse.key=true --property key.separator=, 发送带消息 Key 的数据,逗号分隔 key/value

4. 控制台消费者(消费消息)

脚本名称 完整示例命令 功能作用
kafka-console-consumer.sh bin/kafka-console-consumer.sh --bootstrap-server 127.0.0.1:9092 --topic test_topic 实时消费新产生消息
kafka-console-consumer.sh bin/kafka-console-consumer.sh --bootstrap-server 127.0.0.1:9092 --topic test_topic --from-beginning 从头消费该 Topic 所有历史消息
kafka-console-consumer.sh 指定消费组bin/kafka-console-consumer.sh --bootstrap-server 127.0.0.1:9092 --topic test_topic --group test_group 使用自定义消费组,持久化 offset
kafka-console-consumer.sh 打印 Key+Valuebin/kafka-console-consumer.sh --bootstrap-server 127.0.0.1:9092 --topic test_topic --from-beginning --property print.key=true --property key.separator=: 消费时同时输出消息 Key 与 Value

5. 消费组 & Offset 偏移量管理

脚本名称 完整示例命令 功能作用
kafka-consumer-groups.sh 查看全部消费组bin/kafka-consumer-groups.sh --bootstrap-server 127.0.0.1:9092 --list 列出集群内所有消费组名称
kafka-consumer-groups.sh 查看消费组详情bin/kafka-consumer-groups.sh --bootstrap-server 127.0.0.1:9092 --group test_group --describe 查看分区 offset、消息堆积 LAG、分配节点
kafka-consumer-groups.sh 重置 offset 到最早bin/kafka-consumer-groups.sh --bootstrap-server 127.0.0.1:9092 --group test_group --topic test_topic --reset-offsets --to-earliest --execute 偏移量重置至分区第一条消息(需停消费程序)
kafka-consumer-groups.sh 重置 offset 到最新bin/kafka-consumer-groups.sh --bootstrap-server 127.0.0.1:9092 --group test_group --topic test_topic --reset-offsets --to-latest --execute 偏移量重置至最新消息,跳过历史数据
kafka-consumer-groups.sh 删除消费组bin/kafka-consumer-groups.sh --bootstrap-server 127.0.0.1:9092 --group test_group --delete 删除无活跃消费者、无 offset 的空消费组

九、Kafka 与其他消息队列对比

对比维度 Kafka RabbitMQ RocketMQ
定位 分布式流平台 传统消息队列 金融级消息队列
吞吐量 百万级/秒 万级/秒 十万级/秒
延迟 毫秒级 微秒级 毫秒级
消息留存 支持(可配置保留时间) 消费即删除 支持
顺序保证 Partition 内有序 单队列有序 队列内有序
协议 自定义二进制 AMQP 自定义
适用场景 日志、事件流、流处理 任务队列、RPC 金融、电商

选型建议:

  • 要高吞吐、可重放、流处理 → Kafka
  • 要低延迟、复杂路由、AMQP → RabbitMQ
  • 要金融级可靠、事务消息 → RocketMQ

十、总结

Kafka 的核心价值可以用一句话概括:高吞吐 + 持久化 + 流处理

核心能力 支撑的应用场景
高吞吐、低延迟 日志收集、实时数据管道
持久化存储 消息重放、事件溯源
分区并行 水平扩展、并行消费
副本机制 数据可靠性、高可用
消费者组 负载均衡、消息广播
Kafka Streams 实时流处理

Kafka 已经成为现代分布式系统的标配基础设施,尤其在大数据、实时计算、微服务架构中扮演着核心角色。


参考资源:

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐