Zookeeper集群 + Kafka集群
1.Zookeeper 概述
Zookeeper 简称 ZK ,分布式协调服务
用来解决分布式应用集群中应用系统的数据一致性问题。能让分布式应用集群的每个实例同时获取到同一份信息的服务。
(1)Zookeeper工作机制
注册中心+文件系统+通知机制
用于注册各种分布式应用,存储和管理这些分布式应用的元数据,如果应用数据或服务状态发生变化就会通知并同步给分布式应用集群中的其它实例。
(2)Zookeeper数据结构
ZooKeeper数据模型的结构与Linux文件系统很类似,整体上可以看作是一棵树,每个节点称做一个ZNode。每一个ZNode默认能够存储1MB的数据,每个ZNode都可以通过其路径唯一标识。
(3)Zookeeper选举机制
服务器数量要求至少大于等于3的奇数台。
第一次leader选举:先比较服务器的myid,谁的myid最大就能获取到其它服务器的选票,当选票超过服务器数量的半数时则当选leader,其它服务器则为follower。即使以后再有其它myid更大的服务器加入集群也不会影响之前的选举结果。
非第一次选举:
1)如果是follower故障,替换的新服务器继续作为follower,与现存的leader建立连接并同步数据
2)如果是leader故障,则需要重新选举新的leader,先比较当前存活服务器的epoch(参与选举的次数),如有epoch最大的服务器则直接当选leader
若epoch有相同的服务器,再比较zxid(写操作的事务id),如有zxid最大的服务器则直接当选leader
若zxid也有相同的服务器,继续比较sid(等同于myid),最后由sid最大的服务器当选leader
2.部署 Zookeeper 集群
准备 3 台服务器做 Zookeeper 集群
20.0.0.100
20.0.0.110
20.0.0.130
(1)安装前准备
关闭防火墙
systemctl disable --now firewalld
setenforce 0
vim /etc/selinux/config
disabled
安装 JDK
java -version
#yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel 没安装yum安装
下载安装包
官方下载地址:https://archive.apache.org/dist/zookeeper/
cd /opt/
wget https://archive.apache.org/dist/zookeeper/zookeeper-3.6.4/apache-zookeeper-3.6.4-bin.tar.gz
(2)安装 Zookeeper
cd /opt/
rz -E 上传apache-zookeeper-3.6.4-bin.tar.gz
ls
tar xf apache-zookeeper-3.6.4-bin.tar.gz
mv apache-zookeeper-3.6.4-bin /usr/local/zookeeper
修改配置文件
cd /usr/local/zookeeper/
ls
cd conf/
ls
cp zoo_sample.cfg zoo.cfg
ls
vim zoo.cfg
注:server.A=B:C:D
●A是一个数字,表示这个是第几号服务器。集群模式下需要在zoo.cfg中dataDir指定的目录下创建一个文件myid,这个文件里面有一个数据就是A的值,Zookeeper启动时读取此文件,拿到里面的数据与zoo.cfg里面的配置信息比较从而判断到底是哪个server。
●B是这个服务器的地址。
●C是这个服务器Follower与集群中的Leader服务器交换信息的端口。
●D是万一集群中的Leader服务器挂了,需要一个端口来重新进行选举,选出一个新的Leader,而这个端口就是用来执行选举时服务器相互通信的端口。
20.0.0.100
在每个节点上创建数据目录和日志目录
mkdir data logs
拷贝配置好的 Zookeeper 配置文件到其他机器上
scp -r zookeeper/ 20.0.0.110:/usr/local/
scp -r zookeeper/ 20.0.0.130:/usr/local/
20.0.0.110
20.0.0.130
在每个节点的dataDir指定的目录下创建一个 myid 的文件
cd /usr/local/zookeeper/
echo 1 > data/myid
cat data/myid
vim conf/zoo.cfg
20.0.0.110
20.0.0.130
启动脚本
cd /usr/local/zookeeper/bin/
vim zkServer.sh
./zkServer.sh start
netstat -lntp | grep 2181
./zkServer.sh status ##查看状态
3.Kafka 概述
中间件作用:实现应用解耦、异步处理
消息队列型(MQ):Redis、Kafka、RabbitMQ、RocketMQ、ActiveMQ
Web应用型(代理):Nginx、HAProxy、Tomcat、PHP
(1)为什么需要消息队列(MQ)
主要原因是由于在高并发环境下,同步请求来不及处理,请求往往会发生阻塞。比如大量的请求并发访问数据库,导致行锁表锁,最后请求线程会堆积过多,从而触发 too many connection 错误,引发雪崩效应。
消息队列的好处:应用解耦、异步处理、数据缓冲、流量削峰、可恢复 等
MQ传统应用场景之异步处理
(2)消息队列的两种模式
(1)点对点模式(一对一,消费者主动拉取数据,消息收到后消息清除)
(2)发布/订阅模式(一对多,又叫观察者模式,消费者消费数据之后不会清除消息)
(3)Kafka组件
Broker kafka服务器
Producer 生产者,发布消息到broker中的topic
Consumer 消息者
Consumer Group 简称GC,消费者组,是消息的时间订阅者,一个消费者组可包含一个或多个消费者,一个组内的成员不能重复消费同一个Partition数据
Topic 主题,一个消息队列的分类,存储在Broker中
Partition 分区,Topic可以包含一个或多个Partition,可以提高数据的扩展和并发读写能力
kafka只能保证Partition分区内的消息顺序,消费时无法保证Partition之间的顺序
Replica 副本,一个Partition可以有多个副本,用来保证Partition数据的高可用,分 leader 和 follower 两种角色
leader:一个Partition的副本有且只有一个leader,负责Partition数据的读写
follower:仅负责备份的leader数据,不负责数据的读写
offset 偏移量,记录消费者上一次消费的消息位置
Zookeeper 存储和管理kafka集群的元数据,并同步数据给集群中的其它实例,生产者和消费者的动作也需要zookeeper的管理和支持。
比如生产者推送数据到kafka集群需要先通过zk寻找到kafka集群服务器的位置,消费者可以从zk获取offset记录的上一次消费的位置再继续往后消费。
Producer -> Topic -> 一个或多个Partition分区 -> 一个或多个replica副本(leader,follower)
(4)Kafka 的特性
高吞吐量、低延迟
可扩展性
持久性、可靠性
容错性
高并发
(5)Kafka 系统架构
(1)Broker
(2)Topic
(3)Partition
(6)kafka如何保证数据的可靠性?
kafka是通过 ack 应答机制来保证数据的可靠性。
在生产者配置文件producer.properties中设置ack应答机制参数 request.required.ack
ack 参数值设置为:
0,表示生产者不等待kafka确认就会继续发送下一条消息。此机制性能最高,但可靠性最低,当leader的broker故障可能会导致数据丢失
1(默认值),表示生产者会等待leader接收数据并确认后才会发送下一条数据。此机制性能其次,可靠性一般,当follower同步备份完成前leader故障可能会导致数据丢失
-1或all,表示生产者需要等待所有的follower都同步备份完成并确认后才会发送下一条数据。此机制性能最低,可靠性最高。
(7)问你们公司用的kafka是如何部署的?
先说明kafka的版本,
1)如果是 2.X 版本,则要先部署 3或5 个服务器的zookeeper集群,然后在每个zookeeper服务器上部署kafka应用。
2)如果是 3.X 版本,kafka不再依赖zookeeper,所以可以直接在java17的环境上部署 3或5 个服务器的kafka集群。
4.部署 kafka 集群
20.0.0.100
安装 Kafka
cd /opt/
rz -E 上传kafka_2.13-2.8.2.tgz
tar xf kafka_2.13-2.8.2.tgz
mv kafka_2.13-2.8.2 /usr/local/kafka
修改配置文件
cd /usr/local/kafka/config/
cp server.properties{,.bak}
vim server.properties
kafka文件存储机制
index文件和log文件的结构示意图
cd /usr/local/
scp -r kafka/ 20.0.0.110:/usr/local/
scp -r kafka/ 20.0.0.130:/usr/local/
20.0.0.110
20.0.0.130
分别启动 Kafka
cd /usr/local/kafka/bin/
ls
./kafka-server-start.sh -daemon /usr/local/kafka/config/server.properties
netstat -lntp | grep 9092
修改环境变量
vim /etc/profile
export JAVA_HOME=/usr/local/jdk1.8.0_391
export JRE_HOME=$JAVA_HOME/jre
export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
Kafka 命令行操作
创建topic
ln -s /usr/local/kafka/bin/* /usr/local/bin/
./kafka-topics.sh --create --zookeeper 20.0.0.100:2181,20.0.0.110:2181,20.0.0.130:2181 --replication-factor 2 --partitions 3 --topic test
注:
--zookeeper:定义 zookeeper 集群服务器地址,如果有多个 IP 地址使用逗号分割,一般使用一个 IP 即可
--replication-factor:定义分区副本数,1 代表单副本,建议为 2
--partitions:定义分区数
--topic:定义 topic 名称
kafka/bin/kafka-topics.sh --zookeeper IP1:2181,IP2:2181,IP3:2181 --create --topic 主题名 --partitions 分区数 --replication-factor 副本数 #创建topic
kafka/bin/kafka-topics.sh --zookeeper IP1:2181,IP2:2181,IP3:2181 --list #查看topic列表
kafka/bin/kafka-topics.sh --zookeeper IP1:2181,IP2:2181,IP3:2181 --describe --topic 主题名 #查看topic详细信息
kafka/bin/kafka-topics.sh --zookeeper IP1:2181,IP2:2181,IP3:2181 --delete --topic 主题名 #删除topic
kafka/bin/kafka-topics.sh --zookeeper IP1:2181,IP2:2181,IP3:2181 --alter --topic 主题名 --partitions 分区数 #修改topic的分区数(只能增不能减)
kafka/bin/kafka-console-producer.sh --broker-list IP1:9092,IP2:9092,IP3:9092 --topic 主题名 #向topic推送数据
kafka/bin/kafka-console-consumer.sh --bootstrap-server IP1:9092,IP2:9092,IP3:9092 --topic 主题名 [--from-beginning] #从topic拉取数据
5.Kafka 架构深入
部署 Zookeeper+Kafka 集群
部署 Filebeat
20.0.0.140
cd /usr/local/filebeat/
vim filebeat.yml
output.kafka:
enabled: true
hosts: ["20.0.0.100:9092","20.0.0.110:9092","20.0.0.130:9092"] #指定 Kafka 集群配置
topic: "nginx" #指定 Kafka 的 topic
#启动 filebeat
./filebeat -e -c filebeat.yml
部署 ELK,在 Logstash 组件所在节点上新建一个 Logstash 配置文件
20.0.0.150
cd /etc/logstash/conf.d/
vim kafka.conf
#启动 logstash
logstash -t -f kafka.conf
logstash -f kafka.conf