一 ZooKeeper简介
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。
二 Zookeeper 主要解决什么问题
在分布式多节点组成的集群环境中,所面临的三个常见的挑战。
第一种:集群管理。为了保证集群的高可用,每个节点都会创建一个数据副本,那么在这种情况下,要保证客户端访问集群中任意一个节点都要是最新的数据;
第二种:分布式锁,对于分布式系统来说,如何去保证共享资源的并发安全性,也是一个比较大的挑战,为了达到这样一个目的,我们必须使用一个跨进程的锁,也就是分布式锁来实现。
第三种:Master选举,在多个节点的集群中,为了去降低集群数据同步的复杂度,一般会将节点设置成两个角色,分别是Master和Slave。Master一般是负责数据的读写等事务性操作,而Slave只负责数据的读操作,如何去确定某个节点是 Master 还是 Salve,也是一件比较复杂的工作。
Zookeeper 的出现,主要是为了满足分布式环境中,以上三种常见的场景的需求。作为一个分布式的中间件而存在,它相当于一个分布式的开源的协调组件,协调和解决分布式系统中的各类问题。
三 Zookeeper分布式协调的基本原理
Zookeeper的基本原理是通过维护一份类似文件系统的树状数据结构(Znode树),并提供监听这些数据变化的机制,来实现分布式系统的协调。它提供了一种 CP 模型,来保证集群中的每个节点的数据一致性,当然Zookeeper的本身的集群并不是强一致性的,而是一个顺序一致性的一个模型,如果我们需要去保证CP特性的话,我们需要 调用“sync”同步方法来进行同步。
四 Zookeeper分布式锁基本原理
在我们进行单机应用开发,涉及并发同步的时候,我们往往采用synchronized或者Lock的方式来解决多线程间的代码同步问题,这时多线程的运行都是在同一个JVM之下,没有任何问题。但当我们的应用是分布式集群工作的情况下,属于多JVM下的工作环境,跨JVM之间已经无法通过多线程的锁解决同步问题。那么就需要一种更加高级的锁机制,来处理种跨机器的进程之间的数据同步问题——这就是分布式锁。
Zookeeper分布式锁的基本原理主要基于其提供的临时有序节点(Ephemeral Sequential Nodes)和Watch机制来实现。以下是详细的基本原理:
★临时节点:在Zookeeper中,临时节点是在客户端会话期间创建的。一旦客户端与Zookeeper服务器的会话结束(如客户端崩溃、断开连接等),这些临时节点会被自动删除。这一特性确保了如果持有锁的客户端出现问题,锁能够被自动释放,避免了死锁的发生。
★有序节点:每次在相同父节点下创建临时节点时,Zookeeper都会为这些节点添加一个自增的数字作为后缀,以保证节点的有序性。这种有序性使得节点可以按照创建的顺序进行排序。
★在Spring cloud 中可以用curator框架实现分布式锁,见下:
在Curator中有五种锁方案:
InterProcessSemaphoreMutex:分布式排它锁(非可重入锁)
InterProcessMutex:分布式可重入排它锁
InterProcessReadWriteLock:分布式读写锁
InterProcessMultiLock:将多个锁作为单个实体管理的容器
InterProcessSemaphoreV2:共享信号量
五 、 Master选举原理
ZooKeeper的Master选举原理主要基于其提供的节点特性和集群中的投票机制,具体原理如下:
1、选举机制概述
ZooKeeper集群中的每个服务器(节点)都有可能成为Master(也称为Leader),但集群在任何给定时间点只能有一个Master,以确保数据的一致性和服务的稳定性。当集群中的某个节点想要成为Master时,它会通过特定的机制进行选举。
2、基于节点的选举方式
ZooKeeper提供了两种基于节点的选举方式:
★基于临时节点的选举:
所有参与选举的节点会尝试在ZooKeeper中创建一个具有唯一名称的临时节点,如/master-election。
由于ZooKeeper保证同一层级下节点名称的唯一性,因此只有一个节点能够成功创建该临时节点。
成功创建临时节点的节点即被选为Master。
如果Master节点出现故障(如宕机),它创建的临时节点会自动从ZooKeeper中删除,其他节点通过注册Watcher监听该节点的变化,并在监听到变化后重新尝试创建临时节点,从而触发新一轮的选举。
★基于临时有序节点的选举:
所有参与选举的节点在同一父节点下(如/master-election)创建临时有序节点。
ZooKeeper会给这些节点分配一个全局递增的编号,如/master-election/lock-00000001、/master-election/lock-00000002等。
编号最小的节点成为Master。
其他节点会监听编号比自己小的节点的变化。如果Master节点宕机,它创建的临时有序节点会被删除,监听该节点的下一个节点会收到通知,并检查自己是否成为新的编号最小的节点,如果是,则成为新的Master。
3、集群投票与ZAB协议
ZooKeeper的选举机制还依赖于ZAB(ZooKeeper Atomic Broadcast)协议,该协议保证了集群中数据的一致性。在选举过程中,每个节点会进行投票,投票基于过半数原则:
一个节点想要成为Master时,会向其他节点发送一个提议,并等待超过一半的节点同意这个提议。
如果超过一半的节点同意,那么这个节点就会成为Master;否则,它会被否决并继续等待下一次选举。
投票时,节点会考虑其他节点的最新事务ID(zxid)和服务器ID。zxid是一个逻辑时钟,用于标识数据更新的顺序,确保新选出的Master具有最新的数据状态。如果两个节点的zxid相同,则服务器ID更大的节点会获得优先权。
4、选举的公平性和高效性
公平性:通过临时有序节点的编号分配和集群投票机制,确保了选举的公平性,即请求创建节点的顺序与选举结果的顺序基本一致。
高效性:通过Watcher机制和节点编号的有序性,减少了不必要的选举竞争和网络通信开销,提高了选举的效率。
综上所述,ZooKeeper的Master选举原理是一个复杂但高效的过程,它充分利用了ZooKeeper的节点特性和集群中的投票机制,确保了分布式环境下Master节点的选举和切换的高效性和一致性。
目前主流的kfaka,HBase、hadoop 都是用Zookeeper 来实现集群节点的主从选择。