4. Kafka基础操作:创建Topic、生产消息、消费消息、理解Partition与Offset
好,咱们正式开始动手了。
前面几章聊了Kafka是什么、能干什么、架构长什么样。说实话,光看理论容易犯困。我当年学Kafka的时候,也是对着文档看了半天,感觉懂了,一敲命令就懵。所以这一章,咱们直接上手。
我会带你走一遍最核心的几个操作:创建Topic、生产消息、消费消息。然后咱们再深入聊聊两个绕不开的概念——Partition和Offset。这两个东西搞不明白,后面做实时通道一定会踩坑。
4.1 创建Topic
Topic是Kafka里最基本的数据组织单元。你可以把它理解成一个「消息队列」的名字。生产者往Topic里写数据,消费者从Topic里读数据。
创建Topic最常用的方式是用命令行工具 kafka-topics.sh。我个人习惯在开发环境里先手动创建,生产环境则交给自动化脚本。
# 创建一个名为 "test-topic" 的Topic,3个分区,1个副本
bin/kafka-topics.sh --create \
--bootstrap-server localhost:9092 \
--replication-factor 1 \
--partitions 3 \
--topic test-topic
这里有几个参数你得留意:
- --bootstrap-server:指定Kafka集群地址。单机玩就写 localhost:9092。
- --partitions:分区数。这个数字决定了Topic的并行处理能力。
- --replication-factor:副本数。生产环境至少设2或3,保证高可用。
--describe 参数查看详情:
bin/kafka-topics.sh --describe --bootstrap-server localhost:9092 --topic test-topic
你会看到每个分区的Leader、Replicas、IsR等信息。嗯,这些后面章节会细讲。
4.2 生产消息
Topic建好了,接下来往里写消息。Kafka自带了一个命令行生产者工具 kafka-console-producer.sh,非常适合测试。
# 启动生产者,往 test-topic 发送消息
bin/kafka-console-producer.sh \
--bootstrap-server localhost:9092 \
--topic test-topic
> hello kafka
> this is my first message
> 按 Ctrl+C 退出
每输入一行,按回车,就是一条消息。简单吧?
但这里有个细节:消息是发到哪个分区的? 默认情况下,如果没有指定key,Kafka会使用轮询(round-robin)的方式把消息均匀分布到各个分区。如果你指定了key,Kafka会对key做哈希,相同key的消息永远进同一个分区。
我在项目中遇到过一个问题:某个业务场景需要保证同一用户的消息有序,结果忘了设key,消息散到不同分区,消费端顺序全乱了。后来加了个用户ID作为key,问题解决。你想想看,这个坑其实很容易踩。
4.3 消费消息
有生产就有消费。Kafka同样提供了命令行消费者工具 kafka-console-consumer.sh。
# 启动消费者,从 test-topic 读取消息
bin/kafka-console-consumer.sh \
--bootstrap-server localhost:9092 \
--topic test-topic \
--from-beginning
加上 --from-beginning 参数,消费者会从Topic最早的可用消息开始读。不加的话,默认只消费启动之后产生的新消息。
运行上面命令后,你会看到刚才生产的那几条消息依次打印出来。嗯,感觉还不错吧?
4.4 理解Partition
好,操作部分先告一段落。咱们来聊聊核心概念。
Partition(分区) 是Kafka实现水平扩展和并行处理的关键。一个Topic可以分成多个Partition,每个Partition是一个有序的、不可变的消息序列。
为什么要分区?说白了,就是为了扛住海量数据。单台机器的存储和吞吐是有限的,分区之后,不同分区可以分布在不同的机器上,读写压力也就分散了。
我用一张图帮你理解:
每个分区内部,消息都有一个唯一的编号,叫 Offset。Offset从0开始,每条新消息追加到分区尾部,Offset就加1。所以,分区内的消息是严格有序的。
但要注意:不同分区之间的消息没有全局顺序。如果你需要全局有序,只能设1个分区。但那样吞吐量就上不去了。所以实际项目中,我们通常只保证「局部有序」——比如同一用户的消息有序,就够了。
4.5 理解Offset
Offset是Kafka里一个极其重要的概念。它本质上是一个整数,表示消息在分区内的位置。
消费者读取消息时,会记录自己消费到了哪个Offset。下次重启时,从上次记录的Offset继续消费,就不会重复读,也不会漏读。
Offset的保存方式有两种:
| 方式 | 说明 | 适用场景 |
|---|---|---|
| 自动提交 | 消费者每隔一段时间自动提交Offset | 开发测试、对数据一致性要求不高的场景 |
| 手动提交 | 业务代码里显式调用提交方法 | 生产环境,需要精确控制「至少一次」语义 |
还有一个常见问题:Offset可以重置吗? 可以。Kafka支持将消费者的Offset重置到最早或最新的位置,这在数据回溯或修复时非常有用。
# 将消费者组 "my-group" 的Offset重置到最早
bin/kafka-consumer-groups.sh \
--bootstrap-server localhost:9092 \
--group my-group \
--reset-offsets \
--to-earliest \
--execute \
--topic test-topic
这个命令我用的不多,但每次用都是救急——比如数据管道出了bug,需要重新消费历史数据修复。
4.6 小结
这一章我们干了三件事:创建Topic、生产消息、消费消息。然后深入理解了Partition和Offset这两个核心概念。
Partition让Kafka能水平扩展,Offset让消费者能精准定位消息位置。两者配合,才有了Kafka高吞吐、高可靠的基础。
下一章,咱们会聊消费者组和再均衡——这是Kafka实现「弹性消费」的关键机制。到时候你会发现,理解了Partition和Offset,后面的内容就顺理成章了。
公众号:蓝海资料掘金营,微信deep3321