回到Zookeeper
1. 藕花深处
平时会花时间学习Redis, RocketMQ, Motan, Dubbo, Kafka等中间件,它们各有各的概念,各有各的用途。我自认为自己在编程学习上并没有什么天分,这些繁杂的概念也是经常忘记,过些时间再看的时候,会有明显的陌生感。今天在复习RocketMQ的一些概念的时候,突然有了一种误入藕花深处的茫然。我到底在学什么,学了忘,忘了学。在一阵反思后,我决定回到Zookeeper,从哪里重新出发。
2.故事的原点
我们知道Zookeeper是雅虎的团队开发,他们发现他们很多项目都在花费一些精力在处理分布式场景下的数据一致性和正确性问题,于是他们把这一部分功能抽离出来,独立成了Zookeeper。由此,我们也回到了故事的原点,即为了应对分布式系统中存在的数据一致性问题。
3.唠一唠数据一致性
现在系统架出于三高(高性能,高并发,高可用)的考虑会采用分布式架构,即由一组服务来一起对外提供服务。zookeeper为了这些目的,一般也会集群部署。为了讨论的更精确,现在我们把相同服务之间的数据一致性称为横向数据一致性,把不同服务之间的数据一致性称为纵向数据一致性。那么一组Zookeeper之间的数据一致性就是横向数据一致性。假设现在存在两台Zookeeper服务,分别为za和zb,并且有两个客户端c1和c2。c1把za上的一个数据k 从1改为了2,然后c2去访问zb,那么它读取k的值是多少?当然是2。那么zookeeper是怎么做到这一点的呢?他用了Paxos的简化形式,ZAB算法。
4.ZAB算法
ZAB算法是 Zookeeper Atomic Broadcast 的简称,即原子广播协议。在该算法中,数据节点可分为两种类型
- Leader : 主节点,系统中只有一个主节点,主节点能提供读和写的服务
- Follower : 从节点,只能读取,当接受到写请求时会转发给主节点
在该算法中,系统会处于两种模式,一个是恢复模式,一个是广播模式
4.1 广播模式
当主节点收到写请求后,会先给该请求赋一个Zxid的单调递增编号。并在本地预写一条日志,紧接着把该请求发给其他的从节点,当整个集群中超过半数的节点都预写日志成功并返回ACK后,主节点会提交本地事务,并向其他节点发送commit消息。我们通过上面的描述,可以看出它很像分布式事务中讲的2PC,但是有区别,表现在两个方面,1是主节点发送消息的过程是异步的,2是主节点不需要等待所有从节点确认。
4.2 恢复模式
zookeeper是如何应对单点故障的呢?假设集群中的leader挂了怎么办?
当主节点挂了后,从节点会重新选举出一个新的主节点,且会保证这个主节点已提交的Zxid是整个集群中最大的。当其它从节点连上主节点后,会把自己的Zxid与新的主节点的Zxid做比较,来决定数据的回滚和同步。从而重新进入广播模式。
这让我想起了三体中,汪淼在游戏中问,什么时候是乱纪元,NPC回答,除了恒纪元都是乱纪元,他们互为对方的间隙。这里的广播模式就是恒纪元,恢复模式就是乱纪元,在恢复模式中,集群不能向外提供服务。
5. 重新出发
希望我们从纷繁复杂的中间件以及各种技术框架中跳出来,从一些最根本的问题重新出发,把对这些技术的理解统一起来。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)