Zookeeper集群有哪些角色?
有三种角色,Leader、Follower、Observer
Leader是核心,它是事务请求的唯一调度和处理者,所有写请求最终都由它处理,并保证整个集群事务处理的顺序性。
Follower会做四件事,处理客户端的非事务请求,把事务请求转发给Leader,参与事务Proposal的投票,参与Leader选举投票。
Observer只提供非事务的查询服务,既不参与Proposal投票,也不参与Leader选举投票。
ZNode特点
Zookeeper = 文件系统 + 监听通知机制
ZNode就是ZooKeeper的数据节点,
特点有四条:
- 他是一个树形结构,路径唯一,整棵树以
/为根,每个节点都用绝对路径唯一标识,一个字符串直接定位,而且ZooKeeper没有相对路径的概念,所有路径都必须以/开头。 - 它既是文件也是目录。每个节点既能存自己的数据,又能有子节点。
- 数据很小,因为它存的是状态信息、配置、位置信息这类协调数据,通常就是KB级,而且单个节点的数据量不能超过1M
- 数据是原子读写的。读就是把这个节点的所有字节读出来,写就是取代所有数据,不存在只改其中某一部分的操作。
另外,每个节点还带两样附加信息:一份 ACL ,控制谁能做什么;一个 stat 结构 ,里面有数据版本、子节点版本、权限版本 ,每次变更,对应的版本号递增,可以用来做缓存验证和协调更新。
然后就是节点一般有两种类型、每种两种状态。一个持久节点,一个短暂节点,每种又有普通和顺序编号两种形态。
持久节点是客户端和服务端断开连接后节点依然存在,短暂节点是生命周期绑定会话,会话一结束节点就自动删除
ZooKeeper的监听通知机制
该机制的核心就是Watch 。客户端可以在一个ZNode上设置Watch,当这个ZNode发生变化时,ZK会把通知异步推给客户端。事件类型有四种:NodeCreated、NodeDeleted、NodeDataChanged、NodeChildrenChanged。客户端注册监听它关心的目录节点,当节点被创建、被删除、数据改变、增加子节点或者子节点被删除的时候,ZooKeeper就会异步通知它。
这里有个关键特性,Watch触发一次就会被删除,想继续监听,就得在回调里重新注册,但是ZooKeeper3.6加了一个新特性,可以设置永久的、递归的监视。默认模式是PERSISTENT_RECURSIVE。
CAP原则以及如何选择
CAP是三个特性,一致性,更新成功后所有用户都应该读到最新值,等同于所有节点访问同一份最新数据副本,可用性,每一个操作总能在一定时间内返回结果,结果可以是成功也可以是失败,而且不保证是最新数据,分区容错性,遇到任何网络分区故障时仍然能对外提供服务。
网络故障避免不了,所以分区容错是必选的,然后看场景选择AP还是CP,CP的典型场景就是银行转账,因为涉及钱,一致性一点都不能让步,反过来,电商抢购是典型的AP,为了保证系统一直能用,会在一致性上做出牺牲。
ZooKeeper的选主过程
第一步,触发选主,一是集群启动的时候,二是运行期Leader出现网络中断、崩溃、重启,或者集群里半数的服务器跟Leader通信不上了。这时候集群会进入崩溃恢复模式,触发选主。
第二步,投票,每个节点先投自己一票,票上带着自己的事务编号ZXID和服务器编号myid,广播给所有人,收到别人的票就比一比,谁的ZXID大就改投谁,ZXID一样,就比myid,谁大投谁。
第三步,定主,谁拿到超过半数的票,谁就是Leader,状态变成Leading,剩下的变成Foller,状态变成Following。
第四步,同步。新Leader上台第一件事是把纪元加一,然后带着这个新纪元,让所有Follower跟他对齐数据。
第五步,复活,这一步必须等过半的机器都同步完,ZAB才退出崩溃恢复模式、进入原子广播模式,集群重新开始接收客户端请求,到这又回到了一主多从的正常状态,整个闭环完成。
ZooKeeper 如何帮助其他组件选主
经典做法是临时顺序节点加监听,所有候选服务在同一个持久的父节点下面,各自创建一个临时顺序节点,ZK会自动编号成000000001、000000002 这样。编号最小的那个就是 Leader。
关键在监听方式,每个节点只监听比自己小的那个前驱节点,形成一条链,接力上任,Leader一旦挂掉,它的临时节点随会话自动消失,前驱节点的监听立刻通知下一个节点,实现自动接任Leader。