2. Kafka核心概念与集群搭建

Kafka 是什么?说白了,就是一个高性能的消息队列系统。但它的设计思路,跟传统的 RabbitMQ、ActiveMQ 不太一样。我刚开始接触 Kafka 时,也被它的 Topic、Partition、Consumer Group 这些概念绕晕过。今天咱们就把这些核心概念掰开揉碎,再搭一个能跑起来的集群。

2.1 核心概念详解

2.1.1 Topic(主题)

Topic 是 Kafka 中消息的逻辑分类。你可以把它理解成数据库里的“表”,或者文件系统里的“文件夹”。生产者往 Topic 里写数据,消费者从 Topic 里读数据。

举个例子,我在项目中处理用户行为日志,会建三个 Topic:click_log、purchase_log、search_log。每个 Topic 只存一类消息,互不干扰。

关键特性:

  • 一个 Topic 可以被多个消费者订阅
  • Topic 内的消息不直接删除,而是根据配置的保留策略(如 7 天或 1GB)自动清理
  • Topic 的名字在集群内必须唯一

2.1.2 Partition(分区)

Partition 是 Kafka 实现高吞吐的核心。一个 Topic 可以分成多个 Partition,每个 Partition 是一个有序的、不可变的消息序列。

我习惯把 Partition 比作“日志文件”。每个 Partition 内部的消息都有唯一的偏移量(Offset),消费者通过记录 Offset 来知道自己读到哪了。

特性 说明
顺序性 单个 Partition 内消息有序,但跨 Partition 不保证全局有序
并行度 Partition 数量决定了消费的并行度上限
存储 每个 Partition 对应磁盘上的一个目录
副本 Partition 可以设置副本数,保证高可用

我曾经踩过的坑:Partition 数量不是越多越好。太多 Partition 会导致文件句柄占用过多、Leader 选举变慢。我一般建议 Partition 数不超过 Broker 数的 10 倍。

2.1.3 Consumer Group(消费者组)

Consumer Group 是 Kafka 实现点对点与发布订阅两种模式的关键。同一个 Group 内的消费者,共同消费一个 Topic 的消息,每条消息只会被 Group 内的一个消费者处理。

你想想看,如果多个消费者属于不同 Group,那每条消息会被每个 Group 都消费一次——这就是发布订阅模式。

个人经验:我在做实时数仓时,同一个 Topic 的数据会同时被两个 Group 消费:一个 Group 做实时 ETL 写入 ClickHouse,另一个 Group 做数据备份写入 HDFS。互不影响,非常灵活。

2.2 核心概念关系图

下面这张图,把 Topic、Partition、Consumer Group 的关系画清楚了。我每次给团队新人讲 Kafka,都会先画这张图。

Kafka 核心概念关系图 Producer Topic: user_click 逻辑分类 Partition 0 [0,1,2,3,...] Partition 1 [0,1,2,3,...] Partition 2 [0,1,2,3,...] Consumer Group A Consumer A1 Consumer A2 Consumer Group B Consumer B1 说明: Producer 写入 Topic → Topic 分散到多个 Partition → 每个 Consumer Group 独立消费所有 Partition → Group 内消费者分摊 Partition

2.3 单机/伪分布式 Kafka 集群搭建

搭建 Kafka 集群,我建议先从单机版开始,再扩展到伪分布式。伪分布式就是在一台机器上启动多个 Broker 进程,模拟多台机器的效果。

2.3.1 环境准备

Kafka 依赖 ZooKeeper,所以要先启动 ZooKeeper。Kafka 2.8+ 虽然支持 KRaft 模式(不依赖 ZooKeeper),但生产环境还是 ZooKeeper 模式更成熟。我个人习惯用 ZooKeeper。

# 1. 下载 Kafka(以 3.5.0 为例)
wget https://downloads.apache.org/kafka/3.5.0/kafka_2.13-3.5.0.tgz
tar -xzf kafka_2.13-3.5.0.tgz
cd kafka_2.13-3.5.0

# 2. 启动 ZooKeeper(Kafka 内置了一个)
bin/zookeeper-server-start.sh config/zookeeper.properties &

# 3. 验证 ZooKeeper 是否启动
echo ruok | nc localhost 2181
# 返回 imok 表示成功

2.3.2 单机版 Kafka

单机版最简单,一个 Broker 搞定。适合本地开发和测试。

# 修改配置文件 config/server.properties
# 关键参数:
broker.id=0
listeners=PLAINTEXT://localhost:9092
log.dirs=/tmp/kafka-logs
num.partitions=3
default.replication.factor=1

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

# 验证:创建一个测试 Topic
bin/kafka-topics.sh --create --topic test-topic \
  --bootstrap-server localhost:9092 \
  --partitions 3 --replication-factor 1

# 查看 Topic 列表
bin/kafka-topics.sh --list --bootstrap-server localhost:9092

我常用的验证方式:启动一个控制台生产者和一个控制台消费者,手动发几条消息看看通不通。

# 终端1:启动生产者
bin/kafka-console-producer.sh --topic test-topic --bootstrap-server localhost:9092
> hello kafka
> this is a test

# 终端2:启动消费者
bin/kafka-console-consumer.sh --topic test-topic --bootstrap-server localhost:9092 --from-beginning
hello kafka
this is a test

2.3.3 伪分布式集群

伪分布式就是在一台机器上启动 3 个 Broker,模拟 3 台机器。我在项目中经常用这种方式做功能验证,省机器又接近真实环境。

# 1. 复制三份配置文件
cp config/server.properties config/server-1.properties
cp config/server.properties config/server-2.properties
cp config/server.properties config/server-3.properties

# 2. 修改每个配置文件的 broker.id、listeners、log.dirs、端口
# server-1.properties
broker.id=1
listeners=PLAINTEXT://localhost:9093
log.dirs=/tmp/kafka-logs-1

# server-2.properties
broker.id=2
listeners=PLAINTEXT://localhost:9094
log.dirs=/tmp/kafka-logs-2

# server-3.properties
broker.id=3
listeners=PLAINTEXT://localhost:9095
log.dirs=/tmp/kafka-logs-3

# 3. 依次启动三个 Broker
bin/kafka-server-start.sh config/server-1.properties &
bin/kafka-server-start.sh config/server-2.properties &
bin/kafka-server-start.sh config/server-3.properties &

# 4. 创建一个带副本的 Topic
bin/kafka-topics.sh --create --topic replicated-topic \
  --bootstrap-server localhost:9093 \
  --partitions 3 --replication-factor 3

# 5. 查看 Topic 详情
bin/kafka-topics.sh --describe --topic replicated-topic \
  --bootstrap-server localhost:9093

2.3.4 验证集群状态

启动完成后,用 --describe 命令看看 Partition 的 Leader 和副本分布情况。

bin/kafka-topics.sh --describe --topic replicated-topic \
  --bootstrap-server localhost:9093

# 输出示例:
# Topic: replicated-topic  Partition: 0  Leader: 1  Replicas: 1,2,3  Isr: 1,2,3
# Topic: replicated-topic  Partition: 1  Leader: 2  Replicas: 2,3,1  Isr: 2,3,1
# Topic: replicated-topic  Partition: 2  Leader: 3  Replicas: 3,1,2  Isr: 3,1,2

看到 Leader 分布在不同的 Broker 上,说明集群正常工作。Leader 负责读写,Follower 负责同步。如果某个 Broker 挂了,Kafka 会自动从 ISR(In-Sync Replicas)中选举新的 Leader。

我曾经踩过的坑:伪分布式集群的端口和日志目录一定要分开,否则 Broker 启动时会报端口冲突或数据目录被占用。另外,ZooKeeper 的 dataDir 也要注意,多个 Broker 共用同一个 ZooKeeper 实例没问题,但数据目录不能混。

2.4 本章小结

Topic 是逻辑分类,Partition 是物理分片,Consumer Group 是消费隔离单元。这三者配合,让 Kafka 既能高吞吐写入,又能灵活扩展消费能力。

搭建集群时,单机版适合入门,伪分布式适合功能验证。生产环境建议至少 3 台机器,副本数设为 2 或 3,Partition 数根据业务流量估算。嗯,这些经验都是我在实际项目中一点点积累出来的,希望对你有帮助。