Zookeeper整理-节点、集群数据一致性问题ZAB协议

1. zookeeper解决的问题

1 地址管理,协议地址维护,n个节点n个地址
2 负载均衡机制,请求转发
3 服务动态上下线感知

服务提供者在启动时,将其提供的服务名称、服务器地址注册到服务配置中心,服务消费者通过服 务配置中心来获得需要调用的服务的机器列表。
通过相应 的负载均衡算法,选取其中一台服务器进行调用
服务消费者只有在第一次调用服务时需要查询 服务配置中心,然后将查询到的信息缓存到本地,后面的 调用直接使用本地缓存的服务地址列表信息,而不需要重 新发起请求道服务配置中心去获取相应的服务地址列表, 直到服务的地址列表有变更
服务发布到zookeeper,客户端拿到地址簿

2. 节点特性

1 同级节点唯一性
2 临时节点和持久化节点
3 有序节点
4 临时节点下不能存在子节点

3.zk集群

集群方案(leader,follower)
集群搭建
server.1 = ip:port1:port2 端口1 通信端口,端口2 选举端口
server.2 = ip:port1:port2
server.3 = ip:port1:port2
vim /tmp/zookeeper/myid 1,2,3 在data目录下创建myid,id和上面id对应的ip对应

4.节点的数据一致性

每个节点都能接收到请求,并且每个节点的数据都必须要保持一致。要 实现各个节点的数据一致性
1 各个节点数据一致性
只在一个节点上执行,数据库数据只有一次修改,则数据一致
2 怎么保证任务只在一个节点执行
集群注册到zookeeper上,通过zookeeper上节点的大小(有顺序),选择最小的节点,在这个节点上执行任务
3 如果orderService挂了,其他节点如何发现并接替任务
当服务 器宕机或者下线时,相应的机器需要能够动态地从服务配 置中心里面移除,并通知相应的服务消费者,否则服务消费者就有可能因为调用到已经失效服务而发生错误,
4 存在共享资源,互斥性 安全性、
缺少一个分布式协调机制
Zookeeper整理-节点、集群数据一致性问题ZAB协议

5.跨节点事务的数据一致性

2pc (二阶提交)
Zookeeper整理-节点、集群数据一致性问题ZAB协议
协调者提交请求,两个节点都回应yes可以执行,协调者发送commit,参与者发送ack
有一个回应为no,则回滚操作
Zookeeper整理-节点、集群数据一致性问题ZAB协议
1 如果是读请求可在任意节点
2 如果是写请求,需要转发到leader操作
leader根据2pc保证数据一致性
客户端request请求leader,leader告知follower,follower响应是否能执行事务,过半ack同意,会提交事务

6. 集群主从配置时崩溃时的数据一致性(ZAB协议)

leader分发消息 消息广播
1 对每个消息生成一个zxid(64位自增id)
2 把带有zxid的消息作为一个propose分发给集群中每一个follower节点
3 把propose这个事务写入磁盘,返回ack
4 leader收到合法数量的ack后,在发起commit请求

两种情况导致崩溃
1 当leader丢失了过半的follower节点的联系
2 当leader挂了

集群进入崩溃恢复阶段
1 已经被处理的请求不能丢失
当leader收到合法数量的follower的ack以后,就会想各个follower广播消息(commit命令),同时自己也会commit这条事务消息,如果follower节点收到commit命令之前leader挂了,倒是部分节点收到commit,部分没有收到,那么ZAB协议需要保证已被处理的消息不能丢失(收到commit消息的zxid最大, 会成为leader,这个事务会同步)
2 被丢失的消息不能再次出现
当leader收到事务请求,并未发起事务投票之前,这个事务直接返回失败,不能再出现

1 新leader zxid最大(数据被提交)
commit给follower则zxid最大(数据最新)
2 epoch概念
每产生一个新的leader,那么新的leader的epoch+1
zxid是64位自增数据,低32位表示为消息计数器,高32位存储epoch编号(老leader的epoch比新leader小,则不会再成为leader)
Zookeeper整理-节点、集群数据一致性问题ZAB协议
leader选举
指标: zxid最大的会设置位leader
myid(服务器id,sid):myid越大,在leader选举中权重越大
epoch 每一轮投票,epoch会递增
启动时如何初始化leader
myid,zxid,epoch发布给每个节点,投票
1 检查zxid 2 myid 3 统计投票

leader选举,广播数据流程,最终确定leader

7.ZK使用

导包
new Zookeeper(集群地址)
用watcher收到服务端响应则连接成功
zookeeper.create 添加节点
zookeeper.setData version 用version保证值不会被其他客户端修改,当前传入的version是最新的,则可以成功,如果数据已被其他修改,则version过期修改失败
(zookeeper server)

8 事件机制

watcher特性:当数据发生变化时,zookeeper会产生一个watcher事件,并且会发送到客户端,但客户端只会收到一次通知,如果后续节点再次发生变化,那么之前设置watcher的客户端不会再次收到消息(watcher时一次性操作),可以通过循环监听达到永久监听(对watcher绑定事件)

如何注册事件机制
绑定事件 getData,Exists,getChilder–>watch监听
触发事件 :事务操作 create/delete/setData

watcher事件类型
None(-1) 客户端连接状态发生改变时,会收到none事件
NodeCreate(1)
NodeDeleted(2)
NodeDataChanged(3)
NodeChildrenChanged(4)

9.使用zookeeper原生api实现分布式锁

进程中实现锁用 redis zookeeper 数据库
实现1 :三个客户端都去zookeeper创建节点,只有一个会成功,其他失败的会监听/locks节点的变化,子节点发生变化时会通知其他节点再去抢锁
缺点:会造成惊群效应,一个触发会产生所有客户端都去争抢

实现2 利用有序节点的特性,每个客户端都能注册上去,但只让最小节点操作,节点间监听比自己小的节点,收到事件,判断当前是否为比自己小的节点完成,是则可以操作
Zookeeper整理-节点、集群数据一致性问题ZAB协议