Kafka3.0之前依赖于zookeeper
zookeeper是一个开源,分布式的架构
zookeeper提供协调服务(Apache项目)
基于观察者模式设计的分布式服务管理架构。管理Apache服务
主要职责是存储和管理数据。分布式节点上的服务接受观察者的注册。一旦这些分布式节点上的数据如果发生变化,由zookeeper来负责通知分布式节点上的服务
zookeeper+Kafka架构图:
zookeeper分为领导者和追随者 leader follower组成的集群
1、 只要有一半以上的集群存货,zookeeper集群就可以正常工作
2、 适用于安装奇数台的服务集群
3、 全局数据一致,每个zookeeper每个节点都保存相同的数据。维护监控服务的数据一致
4、 数据更新的原子性。要么都成功,要么都失败
5、 实时性。只要有变化立刻同步
1、 统一命名服务,再分布式的环境下,对所有的应用和服务进行统一命名
2、 统一配置管理,配置文件同步,kafka的配置文件被修改,可以快速同步到其他节点
3、 统一集群管理,实时掌握所有节点的状态
4、 服务器动态上下线
5、 负载均衡,把访问的服务器的数据,发送到访问量最少的服务器处理客户端的请求
三台服务器:A B C
1、 A先启动,发起一次选举,会投票给自己,只有1票不满足半数。此时A的状态是looking状态
2、 B启动,再发起一次选举,A和B分别投自己一票,交换投票信息,mid,A发现B的myid比A大,A这一票转而投给B
3、 A0票 B2票,没有半数以上结果,A B会进入looking
4、 C启动 myid c的myid最大 A和B都会把票都给C。此时A0票,B0票,C3票
5、 C状态变为leader。A和B变为follower。
当A0票 B2票时,B有可能成为leader。只要leader确定,后续的服务器都是追随者。
1、 初始化的情况下会产生选举
2、 服务器之间和leader丢失连接状态
leader已经存在则建立连接即可
1、 服务器ID大的会胜出
2、 EPOCH大,直接胜出
3、 EPOCH相同,事务ID大的胜出
EPOCH每个leader任期代号,没有leader,大家的逻辑地位相同,每投票完一次之后,数据时递增。
事务ID标识服务器的每一次变更。每变更一次事务ID会变化一次。
服务器ID,zookeeper集群当中的机器都有个ID,每台机器不重复,和myid保持一致。
1、 zookeeper集群部署
实验准备:
20.0.0.11 zookeeper+Kafka1
20.0.0.12 zookeeper+Kafka2
20.0.0.13 zookeeper+Kafka3
关闭三台主机的防火墙和安全机制
cd /opt/
yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel
#安装Java环境
java -version
安装zookeeper和Kafka的软件包
解压zookeeper和Kafka软件包
tar -xf apache-zookeeper-3.5.7-bin.tar.gz
mv apache-zookeeper-3.5.7-bin zookeeper
cd zookeepe/conf/
cp zoo_sample.cfg zoo.cfg
vim zoo.cfg
第二行
tickTime=2000
#服务端与客户端之间心跳线时间,2秒检测一次服务器和客户端之间的通信。
initLimit=10
#领导者和追随者之间。初始连接时能够容忍的超时时间。10:10*tickTime=2000ms=10*2S=20S
syncLimit=5
#同步超时时间。领导者和追随者之间,同步通信超时的时间。5:5*2s=10s。如果超过这个时间。leader会认为follower丢失,会把他移除集群
dataDir=/opt/zookeeper/data
#保存数据的目录,需要单独创建
clientPort=2181
#提供的对外访问端口2181
在16行插入
dataLogDir=/opt/zookeeper/logs
#创建日志文件位置
在最后一行插入
server.1=20.0.0.11:3188:3288
#1:每个zookeeper集群的初始myid
#3188:领导者和追随者之间交换信息的端口(内部通信的端口)
#3288:一旦leader丢失响应,开启选举,3288就是用来执行选举时的服务器之间通信端口。
server.2=20.0.0.12:3188:3288
server.3=20.0.0.13:3188:3288
cd zookeeper
mkdir data logs
#创建在配置文件中定义的两个目录
开始分配myid
cd data
echo 1 > myid
#在11主机
echo 2 > myid
#在12主机
echo 3 > myid
#在13主机
三台主机同时创建:
vim /etc/init.d/zookeeper
#创建启动脚本
chmod +x /etc/init.d/zookeeper
#给脚本添加执行权限
chkconfig --add zookeeper
#给脚本添加系统服务
service zookeeper start
#三台主机分别启动zookeeper脚本文件
查看zookeeper的状态
leader和follower分配完成
此时1和3为follower
2是leader
zookeeper配置完成!
server.1=20.0.0.11:3188:3288
1:每个zookeeper集群的初始myid
3188:领导者和追随者之间交换信息的端口(内部通信的端口)
3288:一旦leader丢失响应,开启选举,3288就是用来执行选举时的服务器之间通信端口。
为什么要引入消息队列(MQ),他也是一个中间件,在高并发环境下,同步请求来不及处理。来不及处理的请求会形成阻塞。
例如:数据库就会形成行锁或者表锁
请求线程满了超标了就会出现错误:too many connection
一旦报错too many connection就会引发整个系统雪崩。
此时消息队列的作用就显得至关重要
消息队列的作用:异步处理请求,流量削峰,应用解耦。
耦合:在软件系统当中,修改一个组件需要修改其他所有组件。这就是高度耦合。
低度耦合:修改一个对其他的组件影响不大,无需修改所有
解耦:
例如:A B C
只要通信保证,其他的修改不影响整个集群。每个组件开源独立的扩展、修改。
解耦的核心作用就是降低组件之间的依赖性
只要在保证通信接口约束的情况下,可以做任何修改操作,不影响整个集群。
依赖点就是接口约束,通过不同的端口,保证集群通信。
消息队列Kafka数据流向及架构图:
手机短信验证码就是典型的Kafka异步处理消息队列
zookeeper负责保存元数据
元数据:topic的相关信息(发布在哪台主机上,指定了多少分区,以及副本数,偏移量)
zookeeper会自建一个主题:__consumer_offsets。默认50个分区只有1个副本
Kafka3.0之后不依赖zookeeper的核心在于元数据由Kafka节点自己管理
主题(topic)相当于Kafka队列的名称
生产者负责发布数据
消费者负责消费数据
分区就是存储生产者发布的数据
偏移量就是数据在分区中的位置
生产者发布数据
生产者消费数据
经纪人负责管理生产者发布的数据
Kafka的工作流程图:
1、 生产者向主题topic中发送数据。数据会按照分区依次保存在不同的分区中。分区的偏移量是从0开始
2、 消费者从开始位置消费,只能获取到test1数据
3、 消费者实时消费则会获取到最新的test2数据
4、 此时生产者写入新的数据test3。这时消费者停止消费请求。此时test3会持久化。(生产者写入topic的数据是持久化的,默认是7小时)此时消费者再次开启消费请求,则可以访问到test3。持久化时间过期后则访问不到test3数据。
Kafka也支持延时发送
至少一次语义:只要消费者进入,确保消息至少被消费一次
实验准备:
20.0.0.11 zookeeper+Kafka1
20.0.0.12 zookeeper+Kafka2
20.0.0.13 zookeeper+Kafka3
tar -xf kafka_2.13-2.7.0.tgz
mv kafka_2.13-2.7.0 kafka2.7
vim /etc/profile
source /etc/profile
#使文件立即生效
修改配置文件:
cd confing/
cp server.properties server.properties.bak
取消同步开始修改配置文件:
vim server.properties
21行
broker.id=1
#三台机器的id不能重复
28行
#声明监听端口和id。如果声明了broker.id,这一行可以默认不动
42行
num.network.threads=3
#处理网络请求的线程数量,默认即可
46行
num.io.threads=8
#处理磁盘的io线程数量,一定要比硬盘数大。默认即可
50行
socket.send.buffer.bytes=102400
#发送套接字的缓冲区大小。默认即可
54行
socket.receive.buffer.bytes=102400
#接收者的接受套接字缓冲区大小。默认即可
58行
socket.reques.max.bytes=104657600
#请求套接字的缓冲区大小。单位是字节
65行
log.idrs=/var/log/kafka
#指定日志路径
70行
num.partitions=1
#在此Kafka服务器上创建topic,如果不指定默认分区数。默认是1个如果指定了这个配置无效
75行
num.recovery.threads.per.data.dir=1
#用于恢复、回收、清理data下的数据的线程数量。Kafka默认不允许删除主题
110行
log.retention.hours=168
#生产者发布的数据文件在主题当中保存的时间
#168:单位是小时。默认是7天
130行
zookeeper.connect=20.0.0.11:2181,20.0.0.12:2181,20.0.0.13:2181
#配置连接zookeeper集群
其他两台机器修改id后
到65行修改日志信息
log.idrs=/var/log/kafka
到123行修改即可
zookeeper.connect=20.0.0.11:2181,20.0.0.12:2181,20.0.0.13:2181
三台机器同时操作
创建启动文件脚本
vim /etc/init.d/kafka
#创建标本文件
chmod +x /etc/init.d/kafka
#给脚本文件执行权限
chkconfig --add kafak
#添加到系统队列中
service kafka start
#启动Kafka
#Kafka的默认端口号9092
netstat -antp | grep 9092
#查看服务端口是否启动
开始创建主题
随机选择一台节点主机
所有Kafka命令都需要在Kafka的bin目录中执行创建
kafka-topics.sh --create --zookeeper 20.0.0.11:2181,20.0.0.12:2181,20.0.0.13:2181 --replication-factor 2 --partitions 3 --topic test1
#创建主题
#在Kafka的bin目录下使用kafka-topics.sh进行创建命令
#--zookeeper 20.0.0.11:2181,20.0.0.12:2181,20.0.0.13:2181:指定zookeeper的节点和端口。作用是来保存Kafka的元数据
#replication-factor 2:定义每个分区的副本数量。
#--partitions 3:指定该主题的分区数
#--topic test1:指定主题名称。名称可以自定义
在另外一台主机上查询刚才创建的主题,看是否可以查看到
kafka-topics.sh --describe --zookeeper 20.0.0.11:2181,20.0.0.12:2181,20.0.0.13:2181
#如果不加主题名称就可以查看有多少主题和主题的详细信息
kafka-topics.sh --describe --zookeeper 20.0.0.11:2181,20.0.0.12:2181,20.0.0.13:2181 --topic test1
#查看指定主题的详细信息
三台主机同步操作主机映射
vim /etc/hosts
20.0.0.11 test1
20.0.0.12 test2
20.0.0.13 test3
开始发布消息测试
在Kafka的bin目录下
kafka-console-producer.sh --broker-list 20.0.0.11:9092,20.0.0.12:9092,20.0.0.13:9092 --topic test1
#--broker-list:指定经纪人节点.这里使用Kafka自己的ip地址
开始测试:
>1
>2
>3
>4
>5
>6
更换节点来作为消费者测试
kafka-console-consumer.sh --bootstrap-server 20.0.0.11:9092,20.0.0.12:9092,20.0.0.13:9092 --topic test1 --from-beginning
#读取主题内的数据
#--from-beginning:指定偏移点消费。表示从头开始消费
实时获取测试:
11创建
kafka-console-producer.sh --broker-list 20.0.0.11:9092,20.0.0.12:9092,20.0.0.13:9092 --topic test1
#先不发布消息
12创建
kafka-console-consumer.sh --bootstrap-server 20.0.0.11:9092,20.0.0.12:9092,20.0.0.13:9092 --topic test1 --from-beginning
#查看实时消息是否可以获取
开启后
回到11主机开始发布信息查看12的消息是否为实时更新
12主机上创建主题
kafka-topics.sh --create --zookeeper 20.0.0.11:2181 --replication-factor 1 --partitions 1 --topic zyg1
#只要创建主题必须要创建分区,只要创建分区必须要有副本
13主机上创建主题
kafka-topics.sh --create --zookeeper 20.0.0.13:2181 --replication-factor 1 --partitions 1 --topic zyg2
使用11主机订阅主题
kafka-console-consumer.sh --bootstrap-server 20.0.0.12:9092 --topic zyg1
kafka-console-consumer.sh --bootstrap-server 20.0.0.13:9092 --topic zyg2
回到12和13开启消费
12主机
kafka-console-producer.sh --broker-list 20.0.0.12:9092 --topic zyg1
> zyg大
> zyg小
到11查看是否能看到12消息
13主机
kafka-console-producer.sh --broker-list 20.0.0.13:9092 --topic zyg2
> zyg长
> zyg短
到11查看是否能看到13消息
每个分区互相独立
消息队列互相隔离
kafka-topics.sh --create --zookeeper 20.0.0.11:2181,20.0.0.12:2181,20.0.0.13:2181 --replication-factor 2 --partitions 3 --topic test1 #创建主题 1、 在Kafka的bin目录下使用kafka-topics.sh进行创建命令 2、 --zookeeper 20.0.0.11:2181,20.0.0.12:2181,20.0.0.13:2181:指定zookeeper的节点和端口。作用是来保存Kafka的元数据 3、 replication-factor 2:定义每个分区的副本数量。 4、 --partitions 3:指定该主题的分区数 5、 --topic test1:指定主题名称。名称可以自定义
kafka-topics.sh --create --zookeeper 20.0.0.11:2181,20.0.0.12:2181,20.0.0.13:2181 --replication-factor 2 --partitions 3 --topic test1
partition:有多少分区
Leader:领导者是谁
Replicas:备份的数据在哪
Isr:表示与领导者同步的副本
Partition:分区编号
Leader:每个分区都有一个领导者(Leader),领导者负责处理分区的读写操作。 在上述输出中,领导者的编号分别为 3、1、3。
Replicas:每个分区可以有多个副本(Replicas),用于提供冗余和容错性。 在上述输出中,Replica 3、1、2 分别对应不同的 Kafka broker。
Isr:ISR(In-Sync Replicas)表示当前与领导者保持同步的副本。 ISR 3、1分别表示与领导者同步的副本。
每个分区互相独立 消息队列互相隔离
kafka-topics.sh --zookeeper 20.0.0.12:2181 --alter --topic zyg1 --partitions 3
#修改主机的分区数
kafka-topics.sh --describe --zookeeper 20.0.0.12:2181 --topic zyg1
#查看分区数是否有变化
分区数越多,存储越多,并发量越快。一个分区两个副本即可
kafka-topics.sh --delete --zookeeper 20.0.0.12:2181 --topic zyg1
#此时命令执行后,只是打赏打上删除的标记,并没有完全删除。还是保存在元数据当中
cd zookeeper/bin
./zkCli.sh -server 20.0.0.11:2181
#-server 20.0.0.11:2181:指定需要登录的IP地址
ls /brokes/topics
#保存Kafka的元数据信息的位置。
#你无法对保存的元数据进行任何信息,只可以查询
get /brokes/topics
#查看元数据信息
1、 zookeeper主要是分布式、观察者模式,统一各个服务器节点的数据。在Kafka当中,手机保存Kafka的元数据
2、 Kafka消息队列:是订阅发布模式
Kafka:速度快,资源占用量高
RABBIT MQ:轻量级
3、 Kafka的组件:
主题:topic。一个主题就相当于1个微信群。
分区:处理消息的位置
偏移量:消息产生的时间位置
生产者:产生数据
消费者:消费数据
经纪人:负责管理生产者发布的数据
创建主题一定要有分区,创建分区一定要有副本