【zookeeper】zookeeper架构原理
zookeeper 顺序一致性
Zookeeper的写请求其实具备了原子性。
原子性的意思就是要么全部机器都成功,要么全部机器都别成功。
负责写的那一台Zookeeper机器收到了写请求之后都会同步给其他机器,保证数据的强一致。
如果你熟悉CAP的话,Zookeeper的这种操作,明显就是符合了CP的特点了。
有人问我,这种一致性是强一致,还是最终一致?
我的回答是如果真要在这二者选一个的话,应该是最终一致。
其实准确的说,Zookeeper官方给出的就是顺序一致性,是比最终一致性更好一点的一致性,因为它保证了顺序写。
因为这种一致性主要是根据两阶段提交2PC的ZAB协议实现的。
当之后你研究了ZooKeeper的ZAB协议之后,你会发现,其实过半Zookeeper返回ack,负责写的Zookeeper就会发送commit给其他所有机器了,只要Zookeeper进行了commit,这个数据就会被客户端读取到了。
那么有没有可能此时有的Zookeeper已经commit了,但是有的Zookeeper还没有commit?
绝对会的!但是最后当所有的commit提交后,所有Zookeeper还是会最终一致的。
image.png image.png
“原子”可以理解为事务,在Zookeeper收到一个数据写请求后,对其分配一个全局唯一且递增的Zxid,然后将该请求转化为事务Proposal,严格按照请求的接收次序放到针对每个Follower的FIFO队列中,即向集群中所有Follower广播该数据,Follower成功收到数据后,会发送Ack给Leader,当Leader收到的Ack超过半数,则向Follower发送commit命令,完成事务的提交。
可以看出在这个分布式事务的提交过程中是遵循了2PC协议的,即事务的预处理请求和事务提交是分成两阶段进行的,不同之处在于2PC要求所有副本应答,而ZAB只要求超过半数的副本应答即可,这样也避免了2PC单点超时造成阻塞的问题。
zookeeper持久化机制
Zookeeper除了内存数据,磁盘数据一般分为快照和事务日志。
快照(snapshot):记录了整个内存中的数据,即datatree的Node数据,这个过程一般是异步的。
事务日志(log):实时记录了所有访问zookeeper的事务请求,包括create、setdata、setacl、delete等等操作;
你如果类比下其他中间件,几乎所有中间件持久化都是类似的,都增量操作的日志和快照两种。比如redis的aof和rdb,hdfs的fsimage和editLog。
你可以想下,这两个文件的作用是什么?肯定是为了保障数据不丢,保障可以快速恢复数据。
日志和快照不可能无限大,无限多。所以Zookeeper会创建一个异步线程,定时清理无用文件。
image.png
参考
Zookeeper架构原理的浅尝就止(上)
https://mp.weixin.qq.com/s/rg-lBWjkyPYhzIb9MFyyyQ
Zookeeper架构原理的浅尝就止(下)
https://mp.weixin.qq.com/s/Oi5hRITyXTiBxM9zfEK8LQ
分布式系统之ZAB协议
https://mp.weixin.qq.com/s/rZ9d0wyjT3ZI5O-1DC9zMw
Zookeeper的部署和运维小记
https://mp.weixin.qq.com/s/tefvX_uibf3DKKoocbxVrw