赞
踩
在服务与服务的通信过程中,除了基本的http接口调用,还可以使用消息队列,比如RabbitMQ、RocketMQ及Kafka。今天介绍一下Kafa的搭建,依然还是使用docker-compose进行部署。
说到Kafka,就不得不提到ZooKeeper,两者在很长一段时间都是配合使用,但随着kafka3.0的诞生,Kafka可以脱离ZooKeeper独自使用,那我们就从这两种方式进行分析。
第一种方式,Kafka3.0之前的版本+ZooKeeper配合使用
先说明一下,为什么Kafka3.0之前的版本需要使用ZooKeeper
(1)编写docker-compose.yml文件,内容如下:
version: '3' # 指定docker-compose语法版本
services: # 从以下定义服务配置列表
zookeeper: #服务名,可自定义
image: wurstmeister/zookeeper # 指定使用的镜像名及标签
container_name: zookeeper # 指定实例化后的容器名
restart: always # 设置无论遇到什么错,重启容器
privileged: true #让docker 应用容器 获取宿主机root权限
ports: # 容器内的映射端口,本地端口:容器内端口
- 2181:2181 # zookeeper对外的端口
volumes: # 设置数据卷挂载路径,本地目录:容器内目录,挂载本地文件到容器里面目录,实现数据持久化到宿主机
- ./zk/data:/data #本地目录使用相对路径
- ./zk/datalog:/datalog
- ./zk/conf:/conf
- /etc/timezone:/etc/timezone # 指定时区
- /etc/localtime:/etc/localtime
environment: # 定义环境变量
ZOO_MY_ID: 1 # zk服务器唯一Id,不能和其它服务器myid一样
ZOO_SERVERS: server.1=zookeeper:2888:3888;2181 # zk集群的服务器
kafka:
image: wurstmeister/kafka
container_name: kafka
restart: always
privileged: true
ports:
- 9092:9092
environment:
KAFKA_ADVERTISED_HOST_NAME: kafka
KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
volumes:
- ./kafka/data:/kafka
- /var/run/docker.sock:/var/run/docker.sock
注意这里面我在volumes里面指定了时区,在执行之前,我通过命令:
echo "Asia/shanghai" > /etc/timezone
设置了时区,然后我就可以执行下面两条命令:
- /etc/timezone:/etc/timezone # 指定时区
- /etc/localtime:/etc/localtime
(2)操作命令(操作基于docker-compose.yml同级目录)
启动kafka服务:docker-compose up -d
关闭kafka服务:docker-compose down
启动之后,会在docker-compose.yml文件下生成zk和kafka两个文件夹,文件夹下是映射的内容
有人可能会问,上面部署的kafka也没标记版本,怎么知道是3.0之前的版本,我们可以使用命令来查询。先使用 docker ps 查询服务,然后进入 kafka 容器内【可以使用容器名称也可以使用容器id】,命令为:
docker exec -it kafka /bin/bash
最后使用以下命令查询版本,注意前面为scala版本,后面为kafka版本。
find / -name *kafka_* | head -1 | grep -o '\kafka[^\n]*'
可以看出kafka的版本号为2.8.1,注意前面为scala版本,后面为kafka版本。
2、集群zookeeper和kafka(单服务器)
编写docker-compose.yml文件,内容如下:
version: '3'
services:
zk1:
image: zookeeper:3.5.7
restart: always
hostname: zk1
container_name: zk1
privileged: true
ports:
- "2181:2181"
volumes:
- ./zk1/data:/data
- ./zk1/datalog:/datalog
- ./zk1/conf:/conf
- /etc/timezone:/etc/timezone # 指定时区
- /etc/localtime:/etc/localtime
environment:
ZOO_MY_ID: 1
ZOO_SERVERS: server.1=0.0.0.0:2888:3888;2181 server.2=zk2:2888:3888;2181 server.3=zk3:2888:3888;2181
networks:
net_zoo:
ipv4_address: 172.20.0.11
zk2:
image: zookeeper:3.5.7
restart: always
hostname: zk2
container_name: zk2
privileged: true
ports:
- "2182:2181"
volumes:
- ./zk2/data:/data
- ./zk2/datalog:/datalog
- ./zk2/conf:/conf
- /etc/timezone:/etc/timezone
- /etc/localtime:/etc/localtime
environment:
ZOO_MY_ID: 2
ZOO_SERVERS: server.1=zk1:2888:3888;2181 server.2=0.0.0.0:2888:3888;2181 server.3=zk3:2888:3888;2181
networks:
net_zoo:
ipv4_address: 172.20.0.12
zk3:
image: zookeeper:3.5.7
restart: always
hostname: zk3
container_name: zk3
privileged: true
ports:
- "2183:2181"
volumes:
- ./zk3/data:/data
- ./zk3/datalog:/datalog
- ./zk3/conf:/conf
- /etc/timezone:/etc/timezone
- /etc/localtime:/etc/localtime
environment:
ZOO_MY_ID: 3
ZOO_SERVERS: server.1=zk1:2888:3888;2181 server.2=zk2:2888:3888;2181 server.3=0.0.0.0:2888:3888;2181
networks:
net_zoo:
ipv4_address: 172.20.0.13
kafka1:
image: wurstmeister/kafka
restart: always
container_name: kafka1
hostname: kafka1
privileged: true
ports:
- "9092:9092"
environment:
KAFKA_ADVERTISED_HOST_NAME: kafka1
KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://192.168.1.102:9092 # 修改宿主机IP
KAFKA_ADVERTISED_PORT: 9092
KAFKA_ZOOKEEPER_CONNECT: 192.168.1.102:2181,192.168.1.102:2182,192.168.1.102:2183 # 修改宿主机IP,不要使用zk1:2181,zk2:2182,zk3:2183,kafka2和kafka3节点类似
KAFKA_BROKER_ID: 1
KAFKA_OFFSSETS_TOPIC_REPLICATION_FACTOR: 1
volumes:
- ./kafka1:/kafka
- /etc/timezone:/etc/timezone
- /etc/localtime:/etc/localtime
networks:
net_kafka:
ipv4_address: 172.23.0.11
kafka2:
image: wurstmeister/kafka
restart: always
container_name: kafka2
hostname: kafka2
privileged: true
ports:
- "9093:9092"
environment:
KAFKA_ADVERTISED_HOST_NAME: kafka2
KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://192.168.1.102:9093 # 修改宿主机IP
KAFKA_ADVERTISED_PORT: 9093
KAFKA_ZOOKEEPER_CONNECT: 192.168.1.102:2181,192.168.1.102:2182,192.168.1.102:2183 # 修改宿主机IP
KAFKA_BROKER_ID: 2
KAFKA_OFFSSETS_TOPIC_REPLICATION_FACTOR: 1
volumes:
- ./kafka2:/kafka
- /etc/timezone:/etc/timezone
- /etc/localtime:/etc/localtime
networks:
net_kafka:
ipv4_address: 172.23.0.12
kafka3:
image: wurstmeister/kafka
restart: always
container_name: kafka3
hostname: kafka3
privileged: true
ports:
- "9094:9092"
environment:
KAFKA_ADVERTISED_HOST_NAME: kafka3
KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://192.168.1.102:9094 # 修改宿主机IP
KAFKA_ADVERTISED_PORT: 9094
KAFKA_ZOOKEEPER_CONNECT: 192.168.1.102:2181,192.168.1.102:2182,192.168.1.102:2183 #修改宿主机IP
KAFKA_BROKER_ID: 3
KAFKA_OFFSSETS_TOPIC_REPLICATION_FACTOR: 1
volumes:
- ./kafka3:/kafka
- /etc/timezone:/etc/timezone
- /etc/localtime:/etc/localtime
networks:
net_kafka:
ipv4_address: 172.23.0.13
kafka-manager:
image: sheepkiller/kafka-manager:latest
restart: always
container_name: kafa-manager
hostname: kafka-manager
privileged: true
ports:
- "9002:9000"
environment:
ZK_HOSTS: 192.168.1.102:2181,192.168.1.102:2182,192.168.1.102:2183
KAFKA_BROKERS: 192.168.1.102:9092,192.168.1.102:9093,192.168.1.102:9094 # 修改宿主机IP
APPLICATION_SECRET: "random-secret"
KAFKA_MANAGER_AUTH_ENABLED: "true"
KAFKA_MANAGER_USERNAME: admin # web端账号
KAFKA_MANAGER_PASSWORD: password # web端密码
networks:
net_zoo:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.20.0.0/25
gateway: 172.20.0.1
net_kafka:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.23.0.0/25
gateway: 172.23.0.1
使用docker-compose up -d 启动容器,启动之后查看结构如下【文件夹不需要手动创建,系统会自动创建】:
在zk1、zk2、zk3这三个文件目录的conf目录下会自动生成zoo.cfg配置文件,在data目录下会生成myid文件,里面存放的是对应zk的ZOO_MY_ID的值,即zk1下面的myid里面放的是1,zk2下面的myid里面放的是2,zk3下面的myid里面放的是3。
zoo.cfg文件内容如下:
此时我们还需要验证一下zookeeper集群和kafka集群
(1)验证zookeeper集群,使用命令docker exec -it 容器名称/容器id bash,进入容器,然后使用 bin/zkServer.sh status 命令查询状态,mode 为leader或follower正常。小编第一次就遇到有两个zk正常,一个不正常,提示:Error contacting service. It is probably not running
排查这个问题,先检查你的防火墙状态,一般要是关闭状态,以下是防火墙操作的相关命令:
(a)查看防火墙状态:firewall-cmd --state 或者查看firewall服务状态:systemctl status firewalld
(b)关闭firewall:systemctl stop firewalld.service
(c)重启firewall:systemctl restart firewalld.service
(d)启动firewall:systemctl start firewalld.service
若防火墙已关闭,再检查你是否安装了jdk,因为zookeeper的运行需要JVM环境,使用java -version 查询版本即可。小编都不是这些原因,然后通过docker-compose logs -f 查看日志,发现有报错,定位问题,修改,将KAFKA_ZOOKEEPER_CONNECT 里面的配置改成宿主机IP,不要使用zk1:2181,zk2:2182,zk3:2183。重启就可以了。
(2)验证kafka集群
在docker-compose.yml中配置过了kafka-manager,他是Kafka基于web的可视化管理工具。访问平台,http://ip:9002,注意9002是我在yml映射的端口,9002映射到9000。
(a)登录系统,输入账号密码,然后创建cluster
添加成功
(b)查看kafka集群节点
(c)创建Topic
主题(Topic)是kafka消息的逻辑划分,可以理解为是一个类别的名称;kafka通过topic将消息进行分类,不同的topic会被订阅该topic的消费者消费。
当某个topic中的消息非常多时,需要足够大的空间存储,产生的文件也比较大,为了解决文件过大的问题,kafka提出了Partition分区的概念。划分了多个分区(Partition),进行分区存储,达到分段存储kafka中的消息,同时生产者可以并行的写。
问题:kafka分区数Partitions设置多少个比较合适?
虽然分区数设置不受上限,但并不是越多越好,越多的partition意味着需要更多的内存,分配多少个Partitions没有一个严格的标准,更没有一个统一的标准答案,可以参考系统的并发数。我这里设置的日志生产消费的topic,就设置了10个Partition。
在kafka3.0中已经可以将zookeeper去掉,使用kraft机制实现controller主控制器的选举。
左图(kafka2.0):一个集群所有节点都是Broker角色,利用zookeeper的选举能力从三个Broker中选举出来一个Controller控制器,同时控制器将集群元数据信息(比如主题分类、消费进度等)保存到zookeeper,用于集群各节点之间分布式交互。
右图(kafka3.0):假设一个集群有四个Broker,配置指定其中三个作为Conreoller角色(蓝色)。使用kraft机制实现controller主控制器的选举,从三个Controller中选举出来一个Controller作为主控制器(褐色),其他的2个备用。zookeeper不再被需要。相关的集群元数据信息以kafka日志的形式存在(即:以消息队列消息的形式存在)
换句话说,就是以前的kafka元数据保存在zk上,运行动态选举controller,由controller进行对kafka的集群管理。kraft模式,不在依赖zk集群,而是用三台controller节点代替zk,元数据保存在controller中,由controller直接对kafka集群进行管理。注意kafka3.0不再支持JDK8,建议安装JDK11。
目前使用kafka3.x系统的很少,相关资料也比较少,建议搭建前期拿来练手可以。
version: '3'
services:
kafka1:
image: debezium/kafka:1.7
ports:
- 19092:9092
- 19093:9093
environment:
- CLUSTER_ID=5Yr1SIgYQz-b-dgRabWx4g
- BROKER_ID=1
- KAFKA_CONTROLLER_QUORUM_VOTERS=1@kafka1:9093,2@kafka2:9093,3@kafka3:9093
kafka2:
image: debezium/kafka:1.7
ports:
- 29092:9092
- 29093:9093
environment:
- CLUSTER_ID=5Yr1SIgYQz-b-dgRabWx4g
- BROKER_ID=2
- KAFKA_CONTROLLER_QUORUM_VOTERS=1@kafka1:9093,2@kafka2:9093,3@kafka3:9093
kafka3:
image: debezium/kafka:1.7
ports:
- 39092:9092
- 39093:9093
environment:
- CLUSTER_ID=5Yr1SIgYQz-b-dgRabWx4g
- BROKER_ID=3
- KAFKA_CONTROLLER_QUORUM_VOTERS=1@kafka1:9093,2@kafka2:9093,3@kafka3:9093
version: "3"
services:
kafka1:
image: 'bitnami/kafka:latest'
user: root
ports:
- 19092:9092
- 19093:9093
environment:
- KAFKA_ENABLE_KRAFT=yes
- KAFKA_CFG_PROCESS_ROLES=broker,controller
- KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
- KAFKA_CFG_LISTENERS=PLAINTEXT://:19092,CONTROLLER://:19093
- KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
- KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://192.168.1.102:19092 #修改宿主机ip
- KAFKA_BROKER_ID=1
- KAFKA_KRAFT_CLUSTER_ID=iZWRiSqjZA1YwlKEqHFQWI
- KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=1@kafka1:9093,2@kafka2:9093,3@kafka3:9093
- ALLOW_PLAINTEXT_LISTENER=yes
volumes:
- ./kraft1:/bitnami/kafka:rw
- /etc/timezone:/etc/timezone
- /etc/localtime:/etc/localtime
networks:
net_kafka:
ipv4_address: 172.23.0.11
kafka2:
image: 'bitnami/kafka:latest'
user: root
ports:
- 29092:9092
- 29093:9093
environment:
- KAFKA_ENABLE_KRAFT=yes
- KAFKA_CFG_PROCESS_ROLES=broker,controller
- KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
- KAFKA_CFG_LISTENERS=PLAINTEXT://:29092,CONTROLLER://:29093
- KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
- KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://192.168.1.102:29092 #修改宿主机ip
- KAFKA_BROKER_ID=2
- KAFKA_KRAFT_CLUSTER_ID=iZWRiSqjZA1YwlKEqHFQWI #唯一,三个节点保持一致
- KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=1@kafka1:9093,2@kafka2:9093,3@kafka3:9093
- ALLOW_PLAINTEXT_LISTENER=yes
volumes:
- ./kraft2:/bitnami/kafka:rw
- /etc/timezone:/etc/timezone
- /etc/localtime:/etc/localtime
networks:
net_kafka:
ipv4_address: 172.23.0.12
kafka3:
image: 'bitnami/kafka:latest'
user: root
ports:
- 39092:9092
- 39093:9093
environment:
- KAFKA_ENABLE_KRAFT=yes
- KAFKA_CFG_PROCESS_ROLES=broker,controller
- KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
- KAFKA_CFG_LISTENERS=PLAINTEXT://:39092,CONTROLLER://:39093
- KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
- KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://192.168.1.102:39092 #修改宿主机ip
- KAFKA_BROKER_ID=3
- KAFKA_KRAFT_CLUSTER_ID=iZWRiSqjZA1YwlKEqHFQWI
- KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=1@kafka1:9093,2@kafka2:9093,3@kafka3:9093
- ALLOW_PLAINTEXT_LISTENER=yes
volumes:
- ./kraft3:/bitnami/kafka:rw
- /etc/timezone:/etc/timezone
- /etc/localtime:/etc/localtime
networks:
net_kafka:
ipv4_address: 172.23.0.13
networks:
net_kafka:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.23.0.0/25
gateway: 172.23.0.1
注意这里面的CLUSTER_ID是随机生成的一串,三个节点保持一致。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。