浅谈Zookeeper
zookeeper是什么
由来:
Zookeeper最早起源于雅虎研究院的一个研究小组。在当时,研究人员发现,在雅虎内部很多大型系统基本都需要依赖一个类似的系统来进行分布式协调,但是这些系统往往都存在分布式单点问题。所以,雅虎的开发人员就试图开发一个通用的无单点问题的分布式协调框架,以便让开发人员将精力集中在处理业务逻辑上。
概述:
ZooKeeper 是一个开源的分布式协调服务,最初是在“Yahoo!"上构建的,用于以简单而稳健的方式访问他们的应用程序。主要服务于分布式系统,ZooKeeper可以被用来做:统一配置管理、统一命名服务、分布式锁、集群管理等。ZK 一个最常用的使用场景就是用于担任服务生产者和服务消费者的注册中心(提供发布订阅服务)。 服务生产者将自己提供的服务注册到Zookeeper中心,服务的消费者在进行服务调用的时候先到Zookeeper中查找服务,获取到服务生产者的详细信息之后,再去调用服务生产者的内容与数据。在 Dubbo架构中 Zookeeper 就担任了注册中心这一角色。
特点:
-
顺序一致性: 从同一客户端发起的事务请求,最终将会严格地按照顺序被应用到 ZooKeeper 中去。
-
原子性: 所有事务请求的处理结果在整个集群中所有机器上的应用情况是一致的,也就是说,要么整个集群中所有的机器都成功应用了某一个事务,要么都没有应用。
-
单一系统映像 : 无论客户端连到哪一个 ZooKeeper 服务器上,其看到的服务端数据模型都是一致的。
-
可靠性: 一旦一次更改请求被应用,更改的结果就会被持久化,直到被下一次更改覆盖。
Zookeeper数据模型
是提供一个多层级的节点命名空间(节点称为znode),每个节点都用一个以斜杠(/)分隔的路径表示,而且每个节点都有父节点(根节点除外),非常类似于文件系统。与文件系统不同的是,这些节点都可以设置关联的数据。Zookeeper为了保证高吞吐和低延迟,在内存中维护了这个树状的目录结构,这种特性使得Zookeeper不能用于存放大量的数据,每个节点的存放数据上限为1M

# ZNode 节点类型:
1)临时节点(EPHEMERAL):客户端与zookeeper断开连接后,该节点被删除 。Zookeeper 的客户端和服务器通信采用长连接方式(TCP),每个客户端和服务器通过心跳来保持连接,这个连接状态称为 session,如果 znode 是临时节点,这个 session 失效,znode 也就删除了。
2)临时顺序节点(EPHEMERAL_SEQUENTIAL):客户端与zookeeper断开连接后,该节点被删除,且Zookeeper给该节点名称进行顺序编号(有序自增)
3)持久化节点(PERSISTENT ):客户端与zookeeper断开连接后,该节点依旧存在;
4)持久化顺序节点(PERSISTENT_SEQUENTIAL):客户端与zookeeper断开连接后,该节点依旧存在,且Zookeeper给该节点名称进行顺序编号(有序自增)
会话(session):
Session 指的是 ZooKeeper 服务器与客户端会话。在 ZooKeeper 中,一个客户端连接是指客户端和服务器之间的一个 TCP 长连接。客户端启动的时候,首先会与服务器建立一个 TCP 连接,从第一次连接建立开始,客户端会话的生命周期也开始了。通过这个连接,客户端能够通过心跳检测与服务器保持有效的会话,也能够向Zookeeper 服务器发送请求并接受响应,同时还能够通过该连接接收来自服务器的Watch事件通知。 Session 的 sessionTimeout 值用来设置一个客户端会话的超时时间。当由于服务器压力太大、网络故障或是客户端主动断开连接等各种原因导致客户端连接断开时,只要在sessionTimeout规定的时间内能够重新连接上集群中任意一台服务器,那么之前创建的会话仍然有效。在为客户端创建会话之前,服务端首先会为每个客户端都分配一个sessionID。由于 sessionID 是 Zookeeper 会话的一个重要标识,许多与会话相关的运行机制都是基于这个 sessionID 的,因此,无论是哪台服务器为客户端分配的 sessionID,都务必保证全局唯一。
监听通知机制(Watcher):
Zookeeper允许客户端在指定节点上注册一些Watcher,并且在一些特定事件(数据变更、被删除、子目录节点增加删除等)触发的时候,ZooKeeper服务端会将事件通知到感兴趣的客户端上去,该机制是Zk实现分布式协调服务的重要特性。
ZK实现分布式锁:

- 创建一个锁节点下的一个接一个的临时顺序节点
- 如果自己不是第一个节点,就对自己上一个节点加监听器
- 只要上一个节点释放锁,自己就排到前面去了,相当于是一个排队机制。
- 尝试加锁,判断自己节点序号是不是最小的。
- 是,则加锁成功。
zookeeper选举机制
集群角色
leader(领导者):为客户端提供读和写的功能,集群里面只有leader才能接受写的服务。
follower(跟随者):为客户端提供读服务,如果是写的服务则转发给leader。在选举过程中参与投票。
observer(观察者):为客户端提供读服务,如果是写服务就转发个leader。不参与leader的选举投票。也不参与写的过半原则机制。在不影响写的前提下,提高集群读的性能。

服务器启动时期的Leader选举
当第一台服务器(Server1)启动的时候,是无法进行Leader选举的,当第二台服务器(Server2)启动后,此时两台服务器可以相互通讯,于是便进入Leader选举流程。
1.每个Server会发出一个投票。(初始情况下,对Server1和Server2来说,都会将自己作为Leader服务器进行投票,每次投票的最基本元素包括myid和ZXID(事务id),以(myid,ZXID)的形式标表示),即Server1的投票为(1,0),
Server2的投票为(2,0),然后各自将这个投票发送给集群中其他所有机器;
2.接收来自各个服务器的投票。(判断投票的有效性,是否来自Looking状态的服务器,是否是本轮投票)
3.处理投票。服务器都需要将别人的投票与自己的投票进行PK,PK规则:
- 优先检查ZXID,ZXID较大的优先作为Leader服务器;(运行期间,每个服务器上的ZXID可能不同)
- 如果ZXID相同的话,则比较myid,myid较大的作为Leader服务器;
4.统计投票。每次投票后,服务器都将统计所有投票,判断是否已有过半的机器接收到相同的投票信息。
5.改变服务器状态。一旦确定了Leader,每个服务器就会更新自己的状态(若是Fllower,就更新为FOLLOWING;若是leader,就更新为LEADEIING);
服务器运行时期的Leader选举
1.变更状态。(leader挂了后,非observer服务器都会将自己的服务器状态变更为LOOKING)
2.每个Server发出一个投票。
3.接收来自各个服务器的投票。
4.处理投票。
5.统计投票。
6.改变服务器状态。
ZK数据一致性保证
ZooKeeper保证数据一致性用的是ZAB协议。通过这个协议来进行ZooKeeper集群间的数据同步,保证数据的一致性。

ZooKeeper写数据的机制是客户端把写请求发送到leader节点上(如果发送的是follower节点,follower节点会把写请求转发到leader节点),leader节点会把数据通过proposal请求发送到所有节点(包括自己),所有到节点接受到数据以后都会写到自己到本地磁盘上面,写好了以后会发送一个ack请求给leader,leader只要接受到过半的节点发送ack响应回来,就会发送commit消息给各个节点,各个节点就会把消息放入到内存中(放内存是为了保证高性能),该消息就会用户可见了。那么这个时候,如果ZooKeeper要想保证数据一致性,就需要考虑如下两个情况,情况一:leader执行commit了,还没来得及给follower发送commit的时候,leader宕机了,这个时候如何保证消息一致性?情况二:客户端把消息写到leader了,但是leader还没发送proposal消息给其他节点,这个时候leader宕机了,leader宕机后恢复的时候此消息又该如何处理?
ZAB的崩溃恢复机制
针对情况一,当leader宕机以后,ZooKeeper会选举出来新的leader,新的leader启动以后要到磁盘上面去检查是否存在没有commit的消息,如果存在,就继续检查看其他follower有没有对这条消息进行了commit,如果有过半节点对这条消息进行了ack,但是没有commit,那么新对leader要完成commit的操作。
ZAB恢复中删除数据机制
针对情况二,客户端把消息写到leader了,但是leader还没发送portal消息给其他节点,这个时候leader宕机了,这个时候对于用户来说,这条消息是写失败的。假设过了一段时间以后leader节点又恢复了,不过这个时候角色就变为了follower了,它在检查自己磁盘的时候会发现自己有一条消息没有进行commit,此时就会检测消息的编号,消息是有编号的,由高32位和低32位组成,高32位是用来体现是否发生过leader切换的,低32位就是展示消息的顺序的。这个时候当前的节点就会根据高32位知道目前leader已经切换过了,所以就把当前的消息删除,然后从新的leader同步数据,这样保证了数据一致性。
参考:https://cloud.tencent.com/developer/article/1596883
https://www.cnblogs.com/ysw-go/p/11444993.html

浙公网安备 33010602011771号