一、ZAB一致性协议
### --- 分布式数据一致性问题
~~~ # 为什么会出现分布式数据一致性问题?
~~~ 将数据复制到分布式部署的多台机器中可以消除单点故障防止系统由于某台(些)机器宕机导致的不可用。
~~~ 通过负载均衡技术,能够让分布在不同地方的数据副本全都对外提供服务。有效提高系统性能。
~~~ 在分布式系统中引入数据复制机制后,多台数据节点之间由于网络等原因很容易产生数据不一致的情况。
二、举例
### --- 实验案例
~~~ 当客户端Client1将系统中的一个值K1由V1更新为V2,
~~~ 但是客户端Client2读取的是一个还没有同步更新的副本,K1的值依然是V1,
~~~ 这就导致了数据的不一致性。其中,常见的就是主从数据库之间的复制延时问题。
![](https://i-blog.csdnimg.cn/blog_migrate/81682694dfd3268cf3ef74b1430744b5.png)
### --- ZAB协议
~~~ ZK就是分布式一致性问题的工业解决方案,paxos是其底层理论算法(晦涩难懂著名),
~~~ 其中zab,raft和众多开源算法是对paxos的工业级实现。
~~~ ZK没有完全采用paxos算法,而是使用了一种称为ZookeeperAtomic Broadcast(ZAB,
~~~ Zookeeper原子消息广播协议)的协议作为其数据一致性的核心算法。
~~~ ZAB 协议是为分布式协调服务 Zookeeper 专门设计的一种支持崩溃恢复和原子广播协议。
### --- 主备模式保证一致性
~~~ ZK怎么处理集群中的数据?所有客户端写入数据都是写入Leader中,
~~~ 然后,由 Leader 复制到Follower中。
~~~ ZAB会将服务器数据的状态变更以事务Proposal的形式广播到所有的副本进程上,
~~~ ZAB协议能够保证了事务操作的一个全局的变更序号(ZXID)。
![](https://i-blog.csdnimg.cn/blog_migrate/eb90f2a5e18bfa913378f2ad1e36504e.png)
三、广播消息
### --- 广播消息
~~~ ZAB 协议的消息广播过程类似于 二阶段提交过程。对于客户端发送的写请求,
~~~ 全部由 Leader 接收,Leader 将请求封装成一个事务 Proposal(提议),
~~~ 将其发送给所有 Follwer ,如果收到超过半数反馈ACK,则执行 Commit 操作(先提交自己,
~~~ 再发送 Commit 给所有 Follwer)。
发送Proposal到Follower
![](https://i-blog.csdnimg.cn/blog_migrate/b75017c3187719bfc4a5b80f2775c72e.png)
Leader接收Follower的ACK
![](https://i-blog.csdnimg.cn/blog_migrate/af71ecf84744a846653793f565269d47.png)
### --- 超过半数ACK则Commit
~~~ 不能正常反馈Follower恢复正常后会进入数据同步阶段最终与Leader保持一致!!
![](https://i-blog.csdnimg.cn/blog_migrate/a24d4437535ae5daa5357de6ed22337c.png)
四、细节
### --- leader接收
~~~ # Leader接收到Client请求之后,会将这个请求封装成一个事务,
~~~ 并给这个事务分配一个全局递增的唯一 ID,称为事务ID(ZXID),
~~~ ZAB 协议要求保证事务的顺序,因此必须将每一个事务按照 ZXID进行先后排序然后处理。
~~~ # ZK集群为了保证任何事务操作能够有序的顺序执行,只能是 Leader 服务器接受写请求,
~~~ 即使是Follower 服务器接受到客户端的请求,也会转发到 Leader 服务器进行处理。
~~~ # zk提供的应该是最终一致性的标准。
~~~ zk所有节点接收写请求之后可以在一定时间内保证所有节点都能看到该条数据!!
五、Leader 崩溃问题
### --- Leader 崩溃问题
~~~ Leader宕机后,ZK集群无法正常工作,ZAB协议提供了一个高效且可靠的leader选举算法。
~~~ Leader宕机后,被选举的新Leader需要解决的问题
~~~ ZAB 协议确保那些已经在 Leader 提交的事务最终会被所有服务器提交。
~~~ ZAB 协议确保丢弃那些只在 Leader 提出/复制,但没有提交的事务。
~~~ 基于上面的目的,ZAB协议设计了一个选举算法:能够确保已经被Leader提交的事务被集群接受,丢弃还没有提交的事务。
~~~ 这个选举算法的关键点:保证选举出的新Leader拥有集群中所有节点最大编号(ZXID)的事务!!