ZooKeeper总结以及应用场景和集群搭建
ZooKeeper简介
- ZooKeeper主要服务于分布式系统,可以用ZooKeeper来做:统一配置管理、统一命名服务、分布式锁、集群管理。
- 使用分布式系统就无法避免对节点管理的问题(需要实时感知节点的状态、对节点进行统一管理等等),而由于这些问题处理起来可能相对麻烦和提高了系统的复杂性,ZooKeeper作为一个能够通用解决这些问题的中间件就应运而生了。
典型应用场景和实现
https://zhuanlan.zhihu.com/p/59669985
利用 ZooKeeper 可以非常方便构建一系列分布式应用中都会涉及到的核心功能。
- 数据发布/订阅
- 负载均衡
- 命名服务
- 分布式协调/通知
- 集群管理
- Master 选举
- 分布式锁
- 分布式队列
- 多个开源项目中都应用到了 ZooKeeper,例如 HBase, Spark, Flink, Storm, Kafka, Dubbo 等等。
ZooKeeper的数据结构
ZooKeeper的数据结构,跟文件系统非常类似,可以看做是一颗树,每个数据节点叫做ZNode。每一个节点可以通过路径来标识。
Linux下可以通过sh zkCli.sh命令进入使用ls 查看相应节点。
Znode分为2种类型:
- 临时节点:当客户端和服务端断开连接后(Session会话时效时),所创建的Znode(节点)会自动删除,临时节点不可再拥有子节点。
- 持久节点:当客户端和服务端断开连接后,所创建的Znode(节点)不会删除
创建节点命令:
create [-s] [-e] path data acl
-s:创建的是带序列号的节点,序列号用0填充节点路径。
-e:创建的是临时节点。
path:znode的路径,ZooKeeper中没有相对路径,所有路径都必须以'/'开头。
data:znode携带的数据。
acl:这个节点的ACL。
acl权限设置
认证模式有四种,实际常用digest加密认证:
digest 权限示例:
语法:
- setAcl /lock digest::用户名:密钥:权限位
- addauth digest 用户名:密码
- 注1:密钥 通过sha1与base64组合加密码生成,可通过以下命令生成:
echo -n 用户名:密码 | openssl dgst -binary -sha1 | openssl base64
会话Session
会话自然就是指Zookeeper客户端和服务端之间的通信,他们使用TCP长连接的方式保持通信,通常,肯定会有心跳检测的机制,同时他可以接受来自服务器的Watch事件通知。
Wather监听机制和它的原理
主要流程:
- 客户端向服务端注册Wather监听
- 保存Wather对象到客户端本地的WatherManager中
- 服务端Wather事件触发后,客户端收到服务端通知,从WatherManager中取出对应Wather对象执行回调逻辑
特性:
- 一次性:一旦一个Wather触发之后,Zookeeper就会将它从存储中移除
- 客户端串行:客户端的Wather回调处理是串行同步的过程,不要因为一个Wather的逻辑阻塞整个客户端
- 轻量:Wather通知的单位是WathedEvent,只包含通知状态、事件类型和节点路径,不包含具体的事件内容,具体的时间内容需要客户端主动去重新获取数据
集群角色
- leader: 负责进行投票的发起和决议,更新系统状态。Zookeeper中通常只有Leader节点可以写入。
- follower:用于接收客户端请求并向客户端返回结果以及在选举过程中参与投票。
- observer:也可以接收客户端连接,将写请求转发给leader节点,但是不参与投票过程,只同步leader的状态。通常对查询操作做负载。
集群服务状态
- LOOKING:当节点认为群集中没有Leader,服务器会进入LOOKING状态,目的是为了查找或者选举Leader;
- FOLLOWING:follower角色;
- LEADING:leader角色;
- OBSERVING:observer角色;
zxid(事务ID)
ZooKeeper 状态的每次变化都接收一个 ZXID(ZooKeeper 事务 id)形式的标记。ZXID 是一个 64 位的数字,由 Leader 统一分配,全局唯一,不断递增。ZXID 展示了所有的ZooKeeper 的变更顺序。每次变更会有一个唯一的 zxid,如果 zxid1 小于 zxid2 说明 zxid1 在 zxid2 之前发生。
集群搭建
https://www.cnblogs.com/ysocean/p/9860529.html
ZAB协议(ZooKeeper原子广播协议)
https://mp.weixin.qq.com/s/k0zAExTvMsrugCaNJxs7hQ
https://www.jianshu.com/p/2bceacd60b8a
zab协议投票比较规则:
- 先比较zxid,zxid 比较大的服务器优先作为 Leader
- zxid相同时,比较myid(服务器id),myid大的选做 Leader
注意:所以我们配置zookeeper集群的时候可以把服务性能更高的集群的myid配置大些,让性能好的机器担任leader角色。
zab协有序性
zab协议要保障有序性,因为zookeeper是以类似目录结构的数据结构存储数据的,必须要求命名的有序性。
比如一个命名a创建路径为/test,然后命名b创建路径为/test/123,如果不能保证有序性b命名在a之前,b命令会因为父节点不存在而创建失败。
客户端的写请求步骤
- Leader收到客户端的写请求,生成一个事务(Proposal),其中包含了zxid;
- Leader开始广播该事务,需要注意的是所有节点的通讯都是由一个FIFO的队列维护的;
- Follower接受到事务之后,将事务写入本地磁盘,写入成功之后返回Leader一个ACK;
- Leader收到过半的ACK之后,开始提交本事务,并广播事务提交信息
- 从节点开始提交本事务。
zookeeper的数据并不是强一致性
zookeeper通过二阶段提交来保证集群中数据的一致性,因为只需要收到过半的ACK就可以提交事务,所以zookeeper的数据并不是强一致性。
选举发生的时机
Leader发生选举有两个时机:
- 一个是服务启动的时候当整个集群都没有leader节点会进入选举状态,如果leader已经存在就会告诉该节点leader的信息,自己连接上leader,整个集群不用进入选举状态。
- 还有一个就是在服务运行中,可能会出现各种情况,服务宕机、断电、网络延迟很高的时候leader都不能再对外提供服务了,所有当其他follower通过心跳检测到leader失联之后,集群也会进入选举状态。
选举机制(机制)
zookeeper默认使用majority quorums(过半机制)选举leader:可用节点数量 > 总节点数量/2
选举流程
- 所有节点第一票先选举自己当leader,将投票信息广播出去;
- 从队列中接受投票信息;
- 按照规则判断是否需要更改投票信息,将更改后的投票信息再次广播出去;
- 判断是否有超过一半的投票选举同一个节点,如果是选举结束根据投票结果设置自己的服务状态,选举结束,否则继续进入投票流程。
选举后怎么进行数据同步
脑裂
在集群中,由于网络分区节点之间通信不可达的情况时,集群中出现两个或多个master(leader)的情况。
zk官网判断集群是否可用的文章:
http://zookeeper.apache.org/doc/r3.3.5/zookeeperInternals.html
集群搭建-------Zookeeper集群节点数量为什么要是奇数个?
https://www.cnblogs.com/ysocean/p/9860529.html
zookeeper选举的规则:leader选举,要求 可用节点数量 > 总节点数量/2
- 1、防止由脑裂造成的集群不可用。
- 2、在容错能力相同的情况下,奇数台更节省资源。
Zookeeper 实现分布式锁
https://mp.weixin.qq.com/s/ZqQHWLfVD1Rz1agmH3LWrg
https://blog.csdn.net/crazymakercircle/article/details/85956246
https://juejin.cn/post/6844903729406148622#comment
Zookeeper FQA
https://mp.weixin.qq.com/s/YawG0GqznDHaiHXZuTsCjA
https://www.w3cschool.cn/zookeeper/
https://www.cnblogs.com/felixzh/p/5869212.html
主流微服务注册中心浅析和对比
https://my.oschina.net/yunqi/blog/3040280
分布式一致性算法-Paxos、Raft、ZAB、Gossip
https://zhuanlan.zhihu.com/p/130332285
https://zhuanlan.zhihu.com/p/147691282
https://www.jianshu.com/p/2bd30b3ac5f7