4. Kafka入门:核心概念与实战启动

好,咱们进入实时指标层最核心的传输层——Kafka。很多初学者觉得Kafka是个消息队列,其实它远不止于此。我个人的理解是:Kafka是一个分布式、可持久化、高吞吐的日志系统。说白了,它把数据当成日志文件来存,只不过这个日志可以同时被很多人读。

这一章,咱们不扯太深的理论。我会带你从三个核心概念入手,然后亲手装一个Kafka,最后用命令行发几条消息试试。你跟着做一遍,Kafka就不再神秘了。

4.1 三个核心概念:Topic、Partition、Consumer Group

这三个词,你以后每天都会跟它们打交道。我刚开始学的时候,总觉得它们很绕。其实用一个比喻就能说清楚。

一句话总结:

  • Topic = 一个文件夹(数据分类)
  • Partition = 文件夹里的多个小本子(并行写、并行读)
  • Consumer Group = 一组人一起读这些小本子,每人负责读其中几本

4.1.1 Topic(主题)

Topic就是数据的类别。比如你有个电商系统,订单数据发到 order_topic,用户行为发到 user_click。每个Topic可以独立设置数据保留时间、副本数等。我见过不少新手把所有数据塞到一个Topic里,结果后面想隔离权限、调整保留策略时,非常痛苦。所以,Topic的粒度要提前规划好。

4.1.2 Partition(分区)

Partition是Kafka实现高吞吐的关键。一个Topic可以分成多个Partition,每个Partition是一个有序的、不可变的日志文件。数据写入时,可以指定key,Kafka根据key的哈希值决定写到哪个Partition。如果没有key,就轮询写入。

为什么要分区?你想想看,如果只有一个Partition,那所有读写请求都压在一个节点上,吞吐量就受限了。分区之后,多个Partition可以分布在不同的Broker(Kafka节点)上,并行读写。我在项目中遇到过,一个Topic的Partition数从3个扩到12个,吞吐量直接翻了3倍多。

经验之谈:Partition数不是越多越好。每个Partition对应一个日志文件,太多Partition会增加文件句柄开销和Leader选举时间。我一般建议:Partition数 = 目标吞吐量(MB/s) / 单个Partition吞吐量(MB/s)。单个Partition的写吞吐量大约在10-20MB/s(机械盘)或50-100MB/s(SSD)。

4.1.3 Consumer Group(消费者组)

Consumer Group是Kafka实现点对点和发布订阅两种模式的核心机制。一个Group内的消费者共同消费一个Topic,每条消息只会被Group内的一个消费者处理。这就是点对点模式。如果多个Group同时消费同一个Topic,每个Group都能收到全量消息,这就是发布订阅模式。

举个例子:订单Topic被「实时风控Group」和「数据仓库Group」同时消费。风控Group有3个消费者,每人负责一部分Partition;数仓Group有5个消费者,也各自负责一部分Partition。两个Group互不干扰。

注意:Consumer Group的消费者数量不能超过Topic的Partition数。如果消费者数 > Partition数,多余的消费者会闲置,不干活。我曾经犯过这个错,加了10个消费者,结果只有3个在工作,排查了半天才发现是Partition数不够。

4.2 核心概念关系图

下面这张图,把Topic、Partition、Consumer Group的关系画清楚了。你可以保存下来,以后忘了就看看。

Kafka 核心概念关系图 Topic: order_topic Partition 0 Leader: Broker-1 Follower: Broker-2,3 Partition 1 Leader: Broker-2 Follower: Broker-1,3 Partition 2 Leader: Broker-3 Follower: Broker-1,2 Consumer Group: realtime_risk_group Consumer-1 负责 Partition 0 Consumer-2 负责 Partition 1 Consumer-3 负责 Partition 2 每个 Consumer 负责一个或多个 Partition,Consumer 数不能超过 Partition 数

4.3 Kafka安装与启动

好,概念讲完了,咱们动手装一个。Kafka依赖ZooKeeper来管理集群元数据(新版本Kafka可以用KRaft模式替代ZooKeeper,但咱们先学经典的)。

4.3.1 环境准备

你需要一台Linux/Mac机器,或者Windows的WSL。确保已经安装了JDK 8+。

# 检查Java版本
java -version
# 输出类似:openjdk version "1.8.0_302"

4.3.2 下载与解压

我习惯把软件统一放在 /opt 目录下。你也可以放自己习惯的位置。

# 下载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
mv kafka_2.13-3.5.0 /opt/kafka

# 进入目录
cd /opt/kafka

4.3.3 启动ZooKeeper

Kafka自带了ZooKeeper脚本,方便开发测试。生产环境建议用独立的ZooKeeper集群。

# 启动ZooKeeper(默认端口2181)
bin/zookeeper-server-start.sh config/zookeeper.properties

看到输出 binding to port 0.0.0.0/0.0.0.0:2181 就说明启动成功了。这个窗口不要关,保持运行。

4.3.4 启动Kafka Broker

新开一个终端窗口,启动Kafka服务。

# 启动Kafka Broker(默认端口9092)
cd /opt/kafka
bin/kafka-server-start.sh config/server.properties

看到 started (kafka.server.KafkaServer) 就说明启动成功了。同样,这个窗口保持运行。

小技巧:如果你不想一直开着两个终端,可以用 nohup 后台启动:

nohup bin/zookeeper-server-start.sh config/zookeeper.properties > /tmp/zookeeper.log 2>&1 &
nohup bin/kafka-server-start.sh config/server.properties > /tmp/kafka.log 2>&1 &

4.4 命令行生产消费消息

服务跑起来了,咱们来验证一下。Kafka提供了命令行工具,非常方便。

4.4.1 创建Topic

先创建一个名为 test_topic 的Topic,3个分区,1个副本。

bin/kafka-topics.sh --create \
  --bootstrap-server localhost:9092 \
  --replication-factor 1 \
  --partitions 3 \
  --topic test_topic

输出 Created topic test_topic 就成功了。

4.4.2 查看Topic列表

bin/kafka-topics.sh --list --bootstrap-server localhost:9092

你会看到刚才创建的 test_topic。

4.4.3 查看Topic详情

bin/kafka-topics.sh --describe --bootstrap-server localhost:9092 --topic test_topic

输出类似这样:

Topic: test_topic  PartitionCount: 3  ReplicationFactor: 1
  Topic: test_topic  Partition: 0  Leader: 0  Replicas: 0  Isr: 0
  Topic: test_topic  Partition: 1  Leader: 0  Replicas: 0  Isr: 0
  Topic: test_topic  Partition: 2  Leader: 0  Replicas: 0  Isr: 0

可以看到3个Partition,Leader都是0(因为只有一个Broker)。

4.4.4 启动生产者发送消息

新开一个终端,启动生产者控制台。

bin/kafka-console-producer.sh --bootstrap-server localhost:9092 --topic test_topic

然后输入消息,每行一条:

> hello kafka
> this is my first message
> 实时指标层,我来了

输入完按 Ctrl+C 退出。

4.4.5 启动消费者接收消息

再新开一个终端,启动消费者控制台。

bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test_topic --from-beginning

你会看到刚才发送的三条消息都显示出来了:

hello kafka
this is my first message
实时指标层,我来了

注意:如果消费者收不到消息,检查一下 --bootstrap-server 的地址和端口是否正确。我遇到过好几次,Kafka启动在9092,但消费者连到了别的端口。另外,--from-beginning 表示从Topic的最早消息开始消费,不加的话只消费新消息。

4.5 常用命令速查表

下面这个表,你以后会经常用到。建议收藏。

操作 命令
创建Topic kafka-topics.sh --create --bootstrap-server localhost:9092 --topic my_topic --partitions 3 --replication-factor 1
查看Topic列表 kafka-topics.sh --list --bootstrap-server localhost:9092
查看Topic详情 kafka-topics.sh --describe --bootstrap-server localhost:9092 --topic my_topic
删除Topic kafka-topics.sh --delete --bootstrap-server localhost:9092 --topic my_topic
生产消息 kafka-console-producer.sh --bootstrap-server localhost:9092 --topic my_topic
消费消息 kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic my_topic --from-beginning
查看消费者组 kafka-consumer-groups.sh --bootstrap-server localhost:9092 --list
查看消费者组详情 kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group my_group

4.6 本章小结

这一章,咱们干了三件事:

  • 理解了Topic、Partition、Consumer Group这三个核心概念
  • 亲手安装并启动了Kafka和ZooKeeper
  • 用命令行生产并消费了几条消息

你可能会觉得,就这?别急,Kafka的威力在于它的生态和配置。下一章咱们会深入Kafka的存储机制和可靠性保证,到时候你就知道为什么Kafka能扛住百万级TPS了。

嗯,现在你可以关掉终端,休息一下。但别忘了,Kafka服务还在后台跑着呢。