Docker 部署 Kafka 单/多节点
Kafka 是很成功的一个消息队列,今天和大家分享如何使用 dokcer-compose 部署单节点/多节点 Kafka,并安装 Kafka-manager 可视化工具来管理 Kafka 集群。
今天是奥地利-匈牙利帝国的作家弗朗茨·卡夫卡诞生的 140 周年。Kafka 消息队列的名字正是源自于这位伟大的作家。
生命之所以有意义,是因为它会停止 —— 弗朗茨·卡夫卡
舞台布置
在下的舞台环境如下:
- Ubuntu 22.04.2-Server
- Docker 24.0.2
- Docker-compose 2.18.1
- Kafka 镜像 wurstmeister/kafka:latest (2.13-2.81)
- Zookeeper 镜像 wurstmeister/zookeeper:latest (3.4.6)
- Kafka-manager 镜像 sheepkiller/kafka-manager
安装 docker 和 dokcer-compose 不必多说,网上有大把教程。kafka 必须依赖 zookeeper 才能正常运行,所以安装 zookeeper 必不可少,Kafka-manager 是一个可视化的 Kafka 管理工具,可装可不装。
配置 Docker 代理
如果拉取速度还可以,可以略过此步。配置代理地址:编辑 /etc/docker/daemon.json
,如果该文件不存在,需要先创建。daemon.json
内容如下:
{
"registry-mirrors": [
"https://ung2thfc.mirror.aliyuncs.com",
"https://registry.docker-cn.com",
"http://hub-mirror.c.163.com",
"https://docker.mirrors.ustc.edu.cn"
]
}
重启 docker 使配置生效:
systemctl restart docker
输入命令查看代理是否配置成功:
docker info
出现红框内容则代表配置成功。
部署单节点
创建一个 docker-compose.yml 文件,存放位置无特殊要求,笔者这里存放在 /home/docker 下,最终的效果如下:
编辑 docker-compose.yml,键入以下内容:
version: "3.7"
services:
zookeeper:
image: wurstmeister/zookeeper
ports:
- "2181:2181"
container_name: "zookeeper"
environment:
# 设置时区
TZ: CST-8
restart: always
kafka1:
image: wurstmeister/kafka
container_name: "kafka1"
ports:
- "9092:9092"
environment:
# 设置时区
TZ: CST-8
# 设置zookeeper地址,同网段的容器之间可以通过容器名访问
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
# kafka 服务对客户端的监听地址,192.168.10.43是宿主机IP
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://192.168.10.43:9092
# broker 监听地址
KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
# 关闭自动创建topic,这个配置也可以不要
KAFKA_AUTO_CREATE_TOPICS_ENABLE: false
restart: always
这里简单的说一下环境变量 KAFKA_ADVERTISED_LISTENERS
和 KAFKA_LISTENERS
,前者是 Kafka 服务对客户端提供的访问地址,后者是 Kafka 内部通讯用的。KAFKA_AUTO_CREATE_TOPICS_ENABLE
配置 topic 是否自动创建,当关闭时,生产者对未创建的 topic 发布信息会抛出错误,反之会自动创建。
docker-compose.yml 编辑成功后,进入其所在目录,执行命令:
docker-compose up -d
此时 Docker 就会自动拉取镜像并创建容器,如果拉取镜像速度慢,请参考上文配置 Docker 代理。容器创建完成后的效果:
查看服务注册
进入 Zookeeper
容器内部,查看 Kafka
的注册节点:
# 进入容器
docker exec -it zookeeper bash
# 执行 ZkCli.sh
/opt/zookeeper-3.4.13/bin/zkCli.sh
# 输入 zookeeper 命令查看注册节点
ls /brokers/ids
效果如图:
这个 1001 就是 breker id。
创建 Topic
进入 kafka 容器创建一个 topic:
docker exec -it kafka1 bash
# 进入命令行工具目录
cd /opt/kafka/bin
# 使用命令行工具创建一个名为 mytopic 的 topic
kafka-topics.sh --create --topic mytopic --bootstrap-server 192.168.10.43:9092
生产/消费信息
kafka-console-producer.sh --broker-list 192.168.10.43:9092 --topic mytopic
之后会弹出一个输入框,就可以在此向 mytopic 生成信息辣。
消费信息:
# 打开一个新的窗口,用来获取消费信息
kafka-console-consumer.sh --bootstrap-server 192.168.10.43:9092 --topic mytopic
效果图:
A窗口:
B窗口:
在 A 窗口输入的值都会在 B 窗口中显示。
UI 页面管理 Kafka
单节点部署完成后我们先不着急部署多节点,先来安装一个可视化工具来管理kafka,在 docker-compose.yml 中键入以下配置:
version: "3.7"
services:
zookeeper:
...
kafka-manager:
image: sheepkiller/kafka-manager
container_name: "kafka-manager"
ports:
- "9000:9000"
environment:
TZ: CST-8
# 指定zookeeper地址
ZK_HOSTS: zookeeper:2181
kafka1:
...
然后执行命令更新容器:
docker-compose up -d
执行完成后可以看到我们有三个容器:
容器正常运行后在浏览器输入宿主机 IP:9000,即可看到访问页面:
添加一个集群:
填写集群配置信息,zookeeper 的地址要写对,格式是 IP:Port,这里的 IP 是 zookeeper,是因为容器之间可以使用别名访问。
保存之后就可以看到集群的信息了:
部署多节点
继续编辑 docker-compose.yml 文件,加入新的 Kafka 节点,最终的 docker-compose.yml 如下:
version: "3.7"
services:
zookeeper:
image: wurstmeister/zookeeper
ports:
- "2181:2181"
container_name: "zookeeper"
environment:
TZ: CST-8
restart: always
kafka-manager:
image: sheepkiller/kafka-manager
container_name: "kafka-manager"
ports:
- "9000:9000"
environment:
TZ: CST-8
ZK_HOSTS: zookeeper:2181
kafka1:
image: wurstmeister/kafka
container_name: "kafka1"
ports:
- "9092:9092"
environment:
TZ: CST-8
KAFKA_NUM_PARTITIONS: 5
KAFKA_DEFAULT_REPLICATION_FACTOR: 3
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://192.168.10.43:9092
KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
KAFKA_AUTO_CREATE_TOPICS_ENABLE: false
restart: always
kafka2:
image: wurstmeister/kafka
container_name: "kafka2"
ports:
- "9093:9093"
environment:
TZ: CST-8
KAFKA_NUM_PARTITIONS: 5
KAFKA_DEFAULT_REPLICATION_FACTOR: 3
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://192.168.10.43:9093
KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9093
KAFKA_AUTO_CREATE_TOPICS_ENABLE: false
restart: always
kafka3:
image: wurstmeister/kafka
container_name: "kafka3"
ports:
- "9094:9094"
environment:
TZ: CST-8
KAFKA_NUM_PARTITIONS: 5
KAFKA_DEFAULT_REPLICATION_FACTOR: 3
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://192.168.10.43:9094
KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9094
KAFKA_AUTO_CREATE_TOPICS_ENABLE: false
restart: always
这里我们需要注意到 Kafka 中新增了两个环境变量:KAFKA_NUM_PARTITIONS
和 KAFKA_DEFAULT_REPLICATION_FACTOR
,前者配置了创建 Topic 时的默认分区数量,后者配置默认分区副本数,也可以在创建 Topic 时手动指定这两个参数。
Kafka 的每个 Topic 是有分区概念的,一个 Topic 的数据会分散在不同的分区中,而分区又可能落在了不同的 Broker 中。那思考一个问题:假使说某个 Broker 故障了,这个 Broker 上保存的分区也就不能访问了,数据也就丢失了。那么 Kafka 是怎么应对这个问题的呢?答案是分区副本,每一个分区都有着好几个分区副本,其中一个是领导者副本,其他是追随者副本。追随者不对外提供服务,所有的请求都由领导者副本所在的 Broker 来处理,追随者副本的唯一任务就是从领导者异步拉取消息,并写入到自己的提交日志中,以实现与领导者数据同步。当领导者副本故障后,就会重新在所有的追随者中选举一个当领导者,即使老的领导者重新上线,也只能做为追随者重新加入。分区副本数不能超出 Broker 数,否则在创建 Topic 的时候会报错。分区副本如果设置的过多会加大同步延迟,浪费储存空间,过少会降低可用性。一般认为分区副本数为 3 具有不错的可靠性和容忍性。
一个 Topic 的分布示意图:
最终效果
把上文编辑好的 docker-compose.yml 运行起来,最终的容器列表:
在浏览器打开管理页面,可以看到集群信息:
至此,我们就完成了 Kafka 多节点部署。
本文目录