3. Kafka 集群搭建与配置:单机与集群部署、关键参数调优、JMX 监控

好,咱们进入第三章。这一章我打算聊聊 Kafka 的部署和配置。说实话,很多初学者觉得搭建 Kafka 就是下载、解压、启动,三分钟搞定。但实际在生产环境里,坑多得很。我见过不少团队,集群搭起来跑了两周,突然 broker 挂了,数据全乱套——就是因为一开始参数没调对。

所以这一章,我会从单机部署讲起,再到集群搭建,然后重点说说那些你不得不调的核心参数,最后聊聊 JMX 监控。嗯,咱们一步步来。

3.1 单机部署:快速上手

先说说单机部署。这个场景通常用于开发测试,或者你刚接触 Kafka 想练练手。

步骤其实很简单:

  1. 下载 Kafka:去官网下载二进制包,比如 kafka_2.13-3.5.0.tgz。
  2. 解压:tar -xzf kafka_2.13-3.5.0.tgz
  3. 启动 ZooKeeper:Kafka 依赖 ZooKeeper 管理元数据。Kafka 包里自带了一个单节点 ZK,可以直接用:bin/zookeeper-server-start.sh config/zookeeper.properties
  4. 启动 Kafka Broker:bin/kafka-server-start.sh config/server.properties

你看,就这么几步。但这里有个细节——server.properties 里默认的 log.dirs 是 /tmp/kafka-logs。我个人习惯,一定会改成持久化目录,比如 /data/kafka/logs。为什么?因为 /tmp 目录在系统重启后会被清空,你想想看,数据丢了多麻烦。

小提示: 单机部署时,记得把 broker.id 设为 0。这是 Kafka 集群中每个 broker 的唯一标识,不能重复。

3.2 集群部署:从单机到多节点

单机玩明白了,就该上集群了。集群部署的核心思路,就是把多个 broker 实例组成一个逻辑整体。每个 broker 负责一部分分区数据,互相备份,保证高可用。

我以三节点集群为例,讲讲具体步骤:

  1. 准备三台机器:假设 IP 分别是 192.168.1.10、192.168.1.11、192.168.1.12。
  2. 每台机器上安装 Kafka:步骤和单机一样,解压即可。
  3. 修改 server.properties:每台机器的配置略有不同,主要是 broker.id 和 listeners。

下面是一个典型的配置示例:

# broker 1 的配置
broker.id=1
listeners=PLAINTEXT://192.168.1.10:9092
log.dirs=/data/kafka/logs
zookeeper.connect=192.168.1.10:2181,192.168.1.11:2181,192.168.1.12:2181

# broker 2 的配置
broker.id=2
listeners=PLAINTEXT://192.168.1.11:9092
log.dirs=/data/kafka/logs
zookeeper.connect=192.168.1.10:2181,192.168.1.11:2181,192.168.1.12:2181

# broker 3 的配置
broker.id=3
listeners=PLAINTEXT://192.168.1.12:9092
log.dirs=/data/kafka/logs
zookeeper.connect=192.168.1.10:2181,192.168.1.11:2181,192.168.1.12:2181

配置好之后,依次启动每台机器的 Kafka 服务。启动顺序无所谓,因为 broker 之间会通过 ZooKeeper 自动发现。

注意: 集群模式下,ZooKeeper 也必须部署成集群(至少 3 节点),否则 ZK 单点故障会导致整个 Kafka 集群不可用。我曾经见过一个团队,Kafka 集群搭了 6 个 broker,ZK 却只用了 1 个节点——结果 ZK 挂了,所有 broker 全部失联,那叫一个惨。

3.3 关键参数调优:别让默认值坑了你

Kafka 的默认参数,说实话,很多都是为“能跑起来”设计的,不是为“跑得好”设计的。所以调优是必须的。我挑几个最关键的说说。

3.3.1 网络与线程

参数名 默认值 推荐值 说明
num.network.threads 3 CPU 核心数 × 2 处理网络请求的线程数。我一般设成 8 或 16,看机器配置。
num.io.threads 8 CPU 核心数 × 2 处理磁盘 I/O 的线程数。这个别设太大,否则上下文切换开销会反噬。
socket.send.buffer.bytes 102400 1048576 (1MB) 发送缓冲区大小。高吞吐场景下,默认 100KB 太小了。

3.3.2 日志与存储

参数名 默认值 推荐值 说明
log.retention.hours 168 (7天) 按业务需求定 数据保留时间。我做过一个实时指标项目,只保留 24 小时,因为数据过期就没用了。
log.segment.bytes 1073741824 (1GB) 536870912 (512MB) 单个日志段文件大小。设小一点,方便清理和压缩。
log.retention.check.interval.ms 300000 (5分钟) 60000 (1分钟) 检查过期日志的频率。设短一点,避免磁盘被撑爆。

3.3.3 副本与一致性

参数名 默认值 推荐值 说明
default.replication.factor 1 3 副本因子。默认 1 意味着没有容错,broker 挂了数据就丢了。
min.insync.replicas 1 2 最小同步副本数。配合 acks=all 使用,保证数据不丢。
unclean.leader.election.enable true false 是否允许非同步副本成为 leader。我建议关掉,否则可能丢数据。
核心原则: 调优不是一次性的。我每次上线新集群,都会先跑一周的压测,然后根据监控数据微调参数。别指望一次调好,那是骗人的。

3.4 JMX 监控:让集群状态一目了然

集群搭好了,参数调完了,然后呢?你得盯着它。JMX(Java Management Extensions)是 Kafka 内置的监控接口,通过它你可以获取 broker 的各种指标,比如消息吞吐量、请求延迟、分区状态等等。

3.4.1 开启 JMX

在启动 Kafka 之前,设置环境变量:

export JMX_PORT=9999
export KAFKA_JMX_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"
bin/kafka-server-start.sh config/server.properties

这样,JMX 就暴露在 9999 端口上了。你可以用 JConsole 或者 VisualVM 连接上去看。

小提示: 生产环境一定要开启 JMX 认证,否则任何人都能连上来查看你的集群状态,甚至执行操作。我见过有人因为没开认证,被外部工具误操作导致集群崩溃。

3.4.2 关键监控指标

JMX 暴露的指标很多,但咱们重点关注这几个:

  • BytesInPerSec / BytesOutPerSec:每秒进出流量。如果突然下降,可能是 producer 或 consumer 出了问题。
  • MessagesInPerSec:每秒消息数。这个指标能反映集群的负载情况。
  • UnderReplicatedPartitions:副本不同步的分区数。如果这个值长期不为 0,说明集群有故障。
  • RequestQueueSize:请求队列长度。如果持续增长,说明 broker 处理不过来,需要扩容。
  • TotalTimeMs:请求处理总耗时。包括网络、I/O、等待时间。如果这个值飙升,得赶紧排查。

3.4.3 集成 Prometheus + Grafana

JConsole 只能看单机,不适合生产环境。我一般用 Prometheus 采集 JMX 指标,然后用 Grafana 展示。具体做法是:

  1. 在每个 broker 上部署 JMX Exporter,它是一个 Java agent,能把 JMX 指标转成 Prometheus 格式。
  2. 配置 Prometheus 抓取这些指标。
  3. 在 Grafana 上导入 Kafka 官方仪表盘模板。

这样,你就能在一个大屏上看到所有 broker 的状态了。嗯,这才是生产级的监控。

3.5 本章知识体系图

下面这张图,把本章的核心内容串起来了。你可以对照着回顾一下。

Kafka 集群搭建与配置知识体系 单机部署 集群部署 关键参数调优 下载解压 启动 ZK 启动 Broker 多节点配置 broker.id ZK 集群 网络线程 日志存储 副本一致性 JMX 监控 开启 JMX 端口 关键指标采集 Prometheus 集成 Grafana 展示 监控是集群稳定运行的保障

这张图从左到右,从上到下,把单机部署、集群搭建、参数调优、JMX 监控串成了一条线。你可以在实际工作中,对照这张图一步步来,不容易漏掉关键环节。