签到8!
概念
zk角色:Leader、observer、follower
zk节点的角色:持久节点、持久有序节点、临时节点、临时有序节点、容器节点、带有超时时间的节点
节点数据:存储数据、状态信息
版本:保证分布式数据的原子性
Watcher:客户端向服务器注册一个事件,当发生事件时触发一次;
java调用zk:zkclient、curator
java连接zk的重试策略:1、重试指定次数,每一次调用后再延迟一定时间重试;2、指定最大重试次数;3、仅重试一次;4、一直重试到规定时间;
namespace来隔绝各个业务层的概念;
权限控制:ACL几种模式:并且可以指定它们对节点的crud权限
核心原理
分布式锁
asynchrozied和lock在单个进程中控制访问单一资源,保证线程的安全性;多进程就需要实现分布式锁;
- 利用同级节点唯一性
几个用户同时创建一个节点,只有一个创建成功,其他客户监听该节点的删除事件,再次触发写锁操作;
这个方式最简单,问题是惊群效应,如果客户很多,造成zk性能问题;
- 利用有序节点来实现分布式锁
每一个客户都在指定节点下创建一个临时有序节点,越早创建的节点越排在前面,每一个客户只需要监听比自己小的那个节点就行;
代码也是这么做的;
Leader选举
集群启动的时候、主节点挂了的时候,进行Leader选举
cuator使用两种方式:
- Leader Latch
参与选举的节点会创建一个顺序节点,最小的节点为leader,当leader进行close或者挂掉,子节点重新抢主节点
- Leader Selector
区别于LeaderLatch,它释放领导权后可以继续参与竞争
数据同步
zab:专门用于主节点崩溃后数据的恢复,zookeeper的原子广播协议;两种模式,崩溃恢复、原子广播
- 崩溃恢复
如果leader崩溃,整个集群进入崩溃恢复,1.选举新leader;2.数据同步;zab协议中添加了崩溃恢复;
根据不同的情况进行不同的抉择:
1:已经被处理的消息不能丢弃; 2:被丢弃的消息不能再次出现;
为了达到这个需求:选出来的leader如果拥有最大的zxid,那么已经处理的消息不会丢失;
zxid的前32位是朝代,后32位是消息个数;如果老的leader起来后,那么以前的提案就不会再次出现,因为需要同步新的leader数据;
- 原子广播
简化的2pc,为什么简化,就是事务不支持终止事务,要么提交、要么放弃;
leader发一个提案给follower,follower记下提案后发送ack,当ack超过半数就提交commit命令,同时自己执行该命令;
事务请求只有leader处理;非事务请求交给follower和observer去处理;
新接入进来的节点同步主节点数据;
leader选举
无论是leader挂了还是需要重启每一zk,都需要leader选举;因此在zk启动脚本中能找到相关的启动类,并进行leader选举;
如何选举?
每一个zk节点刚开始状态是Looking状态,封装(myid,zxid,epoch)数据包,也可以理解为选举包;
每一个节点有发送线程处理发送队列,接受线程处理接受队列,接受队列接受选票;
epoch>zxid>myid
先收集,怎么收集?通过zoo.cg中的配置,大的myid连接小的myid,建立连接后,进行选票交互及统计
当选票超过半数,就可以选举出leader,选举出来后,就将状态改变为leader或者follower
事件机制watcher
zk中的watcher包含:客户端注册watcher、服务器处理watcher、客户端回调watcher