3、环境准备:Kafka集群搭建与监控配置
说实话,很多人在MirrorMaker上栽跟头,不是因为工具本身多难,而是环境没搭好。源集群和目标集群的配置差异、网络不通、监控缺失——这些问题一旦埋下,后面排查起来非常痛苦。我自己的习惯是,先把环境做到“可观测、可复现”,再开始搞复制任务。
这一章,我们就一步步把两个Kafka集群搭起来,把网络打通,再把JMX监控挂上。嗯,都是基础活,但基础不牢,地动山摇。
3.1 集群规划:先想清楚再动手
我个人建议,源集群和目标集群最好用相同的Kafka版本。跨大版本复制虽然也能跑,但有些内部协议变化会带来奇怪的问题。我曾经遇到过源集群2.8、目标集群3.4的情况,结果MirrorMaker在同步Offset时频繁报错,最后统一版本才消停。
下面是我常用的一个最小化规划方案,适合实验环境或小规模生产:
| 角色 | 节点 | Broker ID | ZooKeeper | 监听端口 |
|---|---|---|---|---|
| 源集群 | node-1 | 101 | zk1:2181/source | 9092 |
| 源集群 | node-2 | 102 | zk1:2181/source | 9092 |
| 源集群 | node-3 | 103 | zk1:2181/source | 9092 |
| 目标集群 | node-4 | 201 | zk2:2181/target | 9092 |
| 目标集群 | node-5 | 202 | zk2:2181/target | 9092 |
| 目标集群 | node-6 | 203 | zk2:2181/target | 9092 |
注意ZooKeeper的chroot路径。源集群用/source,目标集群用/target,这样即使共用同一套ZK集群,数据也不会混淆。你想想看,如果两个集群的元数据写在同一个ZK路径下,那画面太美我不敢看。
3.2 搭建源集群
以node-1为例,其他节点类似。我习惯把Kafka解压到/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 -C /opt/
ln -s /opt/kafka_2.13-3.5.0 /opt/kafka
# 创建数据目录
mkdir -p /data/kafka/logs
mkdir -p /data/kafka/data
接下来是核心配置——server.properties。这里有几个关键参数,我直接贴出来:
# node-1 的 server.properties
broker.id=101
listeners=PLAINTEXT://0.0.0.0:9092
advertised.listeners=PLAINTEXT://node-1:9092
log.dirs=/data/kafka/data
num.partitions=3
default.replication.factor=2
offsets.topic.replication.factor=2
transaction.state.log.replication.factor=2
transaction.state.log.min.isr=2
zookeeper.connect=zk1:2181/source
zookeeper.connection.timeout.ms=18000
advertised.listeners 这个参数很容易被忽略。如果客户端和Broker不在同一个网段,必须用这个参数告诉客户端“你应该连哪个地址”。我在跨机房部署时吃过这个亏,客户端一直连不上,查了半天才发现是advertised.listeners没配。
配置完成后,启动ZooKeeper和Kafka:
# 启动ZooKeeper(如果单独部署)
/opt/kafka/bin/zookeeper-server-start.sh -daemon /opt/kafka/config/zookeeper.properties
# 启动Kafka
/opt/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/config/server.properties
# 验证
/opt/kafka/bin/kafka-broker-api-versions.sh --bootstrap-server node-1:9092
其他节点(node-2、node-3)重复上述步骤,只需修改broker.id和advertised.listeners即可。
3.3 搭建目标集群
目标集群的搭建流程几乎一样。区别在于:
- Broker ID从201开始
- ZooKeeper路径用
/target - 监听地址指向目标节点
我直接给一份目标集群的配置差异:
# node-4 的 server.properties(目标集群)
broker.id=201
listeners=PLAINTEXT://0.0.0.0:9092
advertised.listeners=PLAINTEXT://node-4:9092
log.dirs=/data/kafka/data
zookeeper.connect=zk2:2181/target
# 其他参数与源集群保持一致
启动后,用同样的方式验证。我个人习惯在目标集群上创建一个测试Topic,确认生产和消费都正常:
/opt/kafka/bin/kafka-topics.sh --create --topic test-target \
--bootstrap-server node-4:9092 --partitions 3 --replication-factor 2
/opt/kafka/bin/kafka-console-producer.sh --topic test-target \
--bootstrap-server node-4:9092
/opt/kafka/bin/kafka-console-consumer.sh --topic test-target \
--bootstrap-server node-4:9092 --from-beginning
3.4 网络连通性检查
集群搭好了,但MirrorMaker需要从源集群拉数据,再推到目标集群。网络不通的话,后面全是白费功夫。我一般按这个顺序检查:
- 基础连通性:用
telnet或nc测试端口 - DNS解析:确保主机名能正确解析
- 防火墙规则:检查iptables或安全组
- Kafka协议连通性:用客户端工具验证
具体命令如下:
# 1. 测试端口连通性(在MirrorMaker节点上执行)
telnet node-1 9092
telnet node-4 9092
# 2. 测试DNS解析
nslookup node-1
nslookup node-4
# 3. 检查防火墙(以CentOS为例)
iptables -L -n | grep 9092
# 如果没放行,添加规则
iptables -A INPUT -p tcp --dport 9092 -j ACCEPT
# 4. 用Kafka自带工具验证
/opt/kafka/bin/kafka-broker-api-versions.sh --bootstrap-server node-1:9092,node-4:9092
3.5 JMX监控配置
没有监控的Kafka集群,就像没有仪表盘的飞机。你飞得再高,也不知道什么时候会掉下来。JMX(Java Management Extensions)是Kafka内置的监控接口,我们可以通过它获取Broker的指标数据。
配置JMX很简单,只需要在启动Kafka前设置环境变量:
# 在启动Kafka之前,设置JMX环境变量
export JMX_PORT=9999
export KAFKA_JMX_OPTS="-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.port=9999 \
-Dcom.sun.management.jmxremote.rmi.port=9999 \
-Djava.rmi.server.hostname=node-1"
# 然后启动Kafka
/opt/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/config/server.properties
如果你用的是systemd管理Kafka服务,可以在service文件中添加Environment变量:
[Service]
Environment=JMX_PORT=9999
Environment=KAFKA_JMX_OPTS=-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.port=9999 \
-Dcom.sun.management.jmxremote.rmi.port=9999 \
-Djava.rmi.server.hostname=node-1
配置完成后,用jconsole或jmxterm验证:
# 使用jconsole连接
jconsole node-1:9999
# 或者用jmxterm(命令行工具)
java -jar jmxterm-1.0.4-uber.jar -l node-1:9999
# 进入交互模式后,输入命令查看指标
beans
get -b kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec Count
kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec— 消息流入速率kafka.server:type=BrokerTopicMetrics,name=BytesInPerSec— 字节流入速率kafka.server:type=BrokerTopicMetrics,name=BytesOutPerSec— 字节流出速率kafka.network:type=RequestMetrics,name=TotalTimeMs— 请求处理耗时kafka.log:type=LogFlushStats,name=FlushMs— 刷盘耗时
3.6 整体架构图
下面这张图展示了我们搭建好的整体环境。源集群、目标集群、MirrorMaker节点以及JMX监控的关系一目了然:
3.7 验证与测试
所有配置完成后,我习惯做一次完整的端到端验证。说白了,就是确保源集群能写、目标集群能读、网络通畅、监控能抓到数据。
# 1. 在源集群创建Topic并生产数据
/opt/kafka/bin/kafka-topics.sh --create --topic test-connect \
--bootstrap-server node-1:9092 --partitions 3 --replication-factor 2
echo "hello mirror" | /opt/kafka/bin/kafka-console-producer.sh \
--topic test-connect --bootstrap-server node-1:9092
# 2. 在目标集群验证(此时还没有MirrorMaker,所以应该没有数据)
/opt/kafka/bin/kafka-console-consumer.sh --topic test-connect \
--bootstrap-server node-4:9092 --from-beginning --timeout-ms 5000
# 预期:没有消息
# 3. 验证JMX端口是否开放
telnet node-1 9999
telnet node-4 9999
# 4. 用curl测试JMX指标(如果配置了HTTP适配器)
curl http://node-1:9999/metrics
kafka-mirror-maker.sh(旧版)或kafka-mirror-maker2.sh(新版),确认数据能正常复制。虽然这不在本章范围内,但提前验证能帮你排除环境问题。嗯,磨刀不误砍柴工。
好了,环境准备就到这里。源集群、目标集群、网络连通性、JMX监控——四件事都做扎实了,后面配置MirrorMaker的时候,你就能把精力集中在复制策略和性能调优上,而不是被环境问题搞得焦头烂额。