zookeeper从入门到精通

本文深入探讨Zookeeper的工作原理,包括其统一命名服务、配置管理和集群管理的应用。介绍了Zookeeper的Znode特性、数据模型、ZXID以及ZAB协议。此外,还讨论了Zookeeper集群的奇数台服务器构成原因、Watcher机制、角色(Leader、Follower、Observer)以及选举过程。同时,文章涵盖了Zookeeper如何保证CP特性并分析了CAP理论。最后,阐述了Zookeeper的选举逻辑和数据存储机制。
摘要由CSDN通过智能技术生成

1、工作原理:服务器在zk上注册(创建临时节点),客户端监听zk上的节点信息,如果某个服务器挂了,zk上节点删除,客户端就会知道某个服务器挂了
2、zk存储的数据是很小的,只是一些配置文件的数据
3、应用场景

  • 统一命名服务:如www.baidu.com对应的多个ip地址
  • 统一配置管理:将集群配置信息写到一个znode,各个节点监听这个znode
  • 统一集群管理:集群各个节点的健康状态写到一个znode,客户端监听这个znode就可以知道哪个节点是正常的

4、zk的数据模型是一个目录结构,每一个目录节点称为一个znode,znode是客户端在zk服务器上面创建的目录
znode特性

  • znode可以有子节点目录,并且每个znode可以存储数据,注意EPHEMERAL(临时的)类型的目录节点不能有子节点目录。

  • znode是有版本的,每个znode中存储的数据可以有多个版本,也就是一个访问路径中可以存储多份数据,version号自动增加。

  • znode可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个是Zookeeper的核心特性,Zookeeper的很多功能都是基于这个特性实现的

znode的类型:

  • Persistent 节点,一旦被创建,即使服务器全部重启也依然存在。每个 Persist节点即可包含数据,也可包含子节点。
  • Ephemeral (暂时)节点,创建它的客户端与服务器间断开连接后自动被删除。服务器重启会导致 Session 结束,因此Ephemeral 类型的 znode 此时也会自动删除。
  • Non-sequence 节点,多个客户端同时创建同一 Non-sequence节点时,只有一个可创建成功,其它匀失败。并且创建出的节点名称与创建时指定的节点名完全一样。
  • Sequence节点,创建出的节点名在指定的名称之后带有10位10进制数的序号。多个客户端创建同一名称的节点时,都能创建成功,只是序号不同。

5、ZXID:每次对Zookeeper的状态的改变(客户端的事务请求,比如新增,更新,删除)都会产生一个zxid(ZooKeeper Transaction Id),zxid是全局有序的,如果zxid1小于zxid2,则zxid1在zxid2之前发生。
于每个事务请求,zk都会为其分配一个全局唯一的事务ID,即ZXID,是一个64位的数字,高32位表示该事务发生的集群选举周期(集群每发生一次leader选举,值加1),低32位表示该事务在当前选择周期内的递增次序(leader每处理一个事务请求,值加1,发生一次leader选择,低32位要清0)。
6、zk工作原理
Zk工作原理的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议(ZooKeeper Atomic Broadcast protocol)。Zab协议有两种模式,它们分别是恢复模式(Recovery选主)和广播模式(Broadcast同步)

  • 当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和leader的数据同步以后,恢复模式就结束了。然后就会进入广播模式
  • 消息广播模式:如果集群中的其他节点收到客户端的事务(写)请求,那么这些非leader服务器会首先将这个事务请求转发给leader服务器。针对每个客户端的事务请求,leader服务器会为其生成对应的事务Proposal,并将其发送给集群中其余所有的follower机器,然后再分别收集各自的选票,最后进行事务提交。Leader接收到消息事务请求后,将消息赋予一个全局唯一的 64 位自增 id,叫做zxid,通过 zxid 的大小比较即可实现因果有序这一特性。Leader 通过先进先出队列(会给每个follower都创建一个队列,保证发送的顺序性)将带有 zxid 的消息作为一个提案(proposal)分发给所有 follower。当 follower 接收到 proposal,先将 proposal 写到本地事务日志,写事务成功后再向 leader 回一个 ACK,表示同意leader的写操作。当 leader 接收到过半的 ACKs 后,leader自己的事务开始commit,即提交写数据操作。然后leader 再向所有 follower 发送 COMMIT 命令。当 follower 收到消息的 COMMIT 命令时,就会执行该事务,开始从leader处同步数据,也开始写数据

7、为什么最好使用奇数台服务器构成 ZooKeeper 集群?
在Zookeeper中 Leader 选举算法采用了Zab协议。Zab核心思想是当多数 Server 写成功,则任务数据写成功。
①如果有3个Server,则最多允许1个Server 挂掉。
②如果有4个Server,则同样最多允许1个Server挂掉。
既然3个或者4个Server,同样最多允许1个Server挂掉,那么它们的可靠性是一样的,所以选择奇数个ZooKeeper Server即可,这里选择3个Server
8、Watcher(观察者模式)
Zookeeper允许客户端在指定znode上注册一些Watcher,并且在一些特定事件触发的时候,ZooKeeper服务端会将事件通知到感兴趣的客户端上去,该机制是Zookeeper实现分布式协调服务的重要特性
10、集群的角色:zk中包含Leader、Follower、Observer三个角色(注意集群的角色最好不要理解为主节点和从节点,因为zk下面会有一个“znode”的概念)

  • Leader
    一个Zookeeper集群同一时间只会有一个实际工作的Leader,它会发起并维护与各Follwer及Observer间的心跳。所有的写操作必须要通过Leader完成再由Leader将写操作广播给其它服务器。
  • Follower
    一个Zookeeper集群可能同时存在多个Follower,它会响应Leader的心跳。Follower可直接处理并返回客户端的读请求,同时会将写请求转发给Leader处理,并且负责在Leader处理写请求时对请求进行投票。
  • Observer 角色与Follower类似,但是无投票权。

注意不要和kafka中分区的副本的leader和follower混淆。zk里面的leader和follower是指机器节点

11、客户端在使用 Zookeeper 服务时会随机连接到集群中的一个节点,所有的读请求都会由当前节点处理,而写请求会被路由给主节点并由主节点向其他节点广播事务,与 2PC 非常相似,如果在所有的节点中超过一半都返回成功,那么当前写请求就会被提交。也就是写操作先在leader节点执行,然后将写操作同步到其他节点,如果其他节点大部分写成功,就可以认为这个写请求成功执行了
12、Zab 和 Paxos 协议在实现上其实有非常多的相似点,例如:

  • 主节点会向所有的从节点发出提案;

  • 主节点在接收到一组从节点中 50% 以上节点的确认后,才会认为当前提案被提交了;

  • Zab 协议中的每一个提案都包含一个 epoch 值,与 Paxos 中的 Ballot 非常相似;

    因为它们有一些相同的特点,所以有的观点会认为 Zab 是 Paxos 的一个简化版本

15、所谓集群管理无在乎两点:是否有机器退出和加入、选举master。
对于第一点,所有机器约定在父目录下创建临时目录节点,然后监听父目录节点的子节点变化消息。一旦有机器挂掉,该机器与 zookeeper的连接断开,其所创建的临时目录节点被删除,所有其他机器都收到通知:某个兄弟目录被删除,于是,所有人都知道:它死了。
对于第二点,我们稍微改变一下,所有机器创建临时顺序编号目录节点,每次选取编号最小的机器作为master就好
16、zab原理:
leader–>发送proposal给follower–>follower发送ack回给leader—>leader发送commit给follower,进行数据写入各节点

  • 1)当leader接收到写请求之后,将请求转化为事务提议(proposal),并将该proposal分别入队列(leader会为每个follower分别创建一个响应队列用来保证事务提交的顺序)。
  • 2)每个事务proposal 有一个递增的全局唯一的ID,事务ID(ZXID)
  • 3)leader 通过响应队列将proposal 分发到其他节点之后,等待反馈;follower 接收到proposal之后写入本地日志,返回 ack;
  • 4)leader 收到一半以上follower 的反馈之后,会向其他节点 发送commit,同时提交事务

17、CAP理论来分析ZooKeeper

CAP理论告诉我们,一个分布式系统不可能同时满足以下三种

  • 一致性(C:Consistency)
    在分布式环境中,一致性是指数据在多个副本之间是否能够保持数据一致的特性
  • 可用性(A:Available)
    可用性是指系统提供的服务必须一直处于可用的状态,对于用户的每一个操作请求总是能够在有限的时间内返回结果。
  • 分区容错性(P:Partition Tolerance)
    这里的分区可以理解为节点,即当一个节点挂了,集群仍能正常工作。ZooKeeper保证了分区容错性,集群中单个服务器发生故障时,只要集群中超过半数的机器还能够正常工作,整个集群就能够对外提供服务。

这三个基本需求,最多只能同时满足其中的两项,因为P是必须的,因此往往选择就在CP或者AP中。

在此ZooKeeper保证的是CP

分析:可用性(A:Available)
进行leader选举时集群都是不可用。在使用ZooKeeper获取服务列表时,当master节点因为网络故障与其他节点失去联系时,剩余节点会重新进行leader选举。问题在于,选举leader的时间太长,30 ~ 120s, 且选举期间整个zk集群都是不可用的,这就导致在选举期间注册服务瘫痪,虽然服务能够最终恢复,但是漫长的选举时间导致的注册长期不可用是不能容忍的。所以说,ZooKeeper不能保证服务可用性。
18、zk选举

  • zab的选举模式和广播模式都用到了“超过半数则胜出的逻辑”
  • 在进行zk集群配置安装时,我们会在给每台服务器配置一个MYID,ID越大则在选举算法中的权重越大
    新增myid文件数据,在三台机器分别执行
    在zookeeper-01中
    echo 1 > /usr/local/zk/data/myid
    在zookeeper-02中
    echo 2 > /usr/local/zk/data/myid
    在zookeeper-03中
    echo 3 > /usr/local/zk/data/myid
    集群选举分为两种场景:
  • 1)集群刚启动的时候(假设有5个节点,一个一个节点启动),此时集群内没有数据。
    myid=1的节点启动后,把票投给自己。myid=2节点启动后,把票投给自己,此时1和2开始通信,1看到2的myid较大,然后把票投给2。myid=3节点启动后,把票投给自己,然后1,2,3之间开始通信,发现3的myid最大,然后把票投给3,此时3的投票已经超过半数,胜出,成为leader,投票结束。myid=4,5节点启动成为follower
  • 2)领导者崩溃,需要重新选举,此时集群内是有数据的,集群节点也已经启动。
    先比较谁的数据新,即谁的zxid越大,谁胜出。zxid相同的情况下,谁的myid越大谁胜出。
    每个节点具体选举过程:
    (1)设置状态为LOOKING,初始化内部投票Vote 数据(myid,zxid)至内存,并将其广播到集群其它节点。节点首次投票都是选举自己作为leader,将自身的服务MYID、处理的最近一个事务请求的ZXID(ZXID是从内存数据库里取的,即该节点最近一个完成commit的事务id)及当前状态广播出去。然后进入循环等待及处理其它节点的投票信息的流程中。
    (2)循环等待流程中,节点每收到一个外部的Vote信息,都需要将其与自己内存Vote数据进行PK,规则为取ZXID大的,若ZXID相等,则取ID大的那个投票。若外部投票胜选,节点需要将该选票覆盖之前的内存Vote数据,并再次广播出去

19、zk底层数据存储
数据存储被分为内存数据存储和磁盘数据存储。

  • 内存数据
    Zookeeper的数据模型是树结构,在内存数据库中,存储了整棵树的内容,包括所有的节点路径、节点数据、ACL信息,Zookeeper会定时将这个数据存储到磁盘上。内存中数据是全量的,完整的。定期checkpoint到磁盘是防止宕机时候数据丢失
    DataTree:DataTree是内存数据存储的核心,是一个树结构,代表了内存中一份完整的数据。DataTree不包含任何与网络、客户端连接及请求处理相关的业务逻辑,是一个独立的组件。
    DataNode:DataNode是数据存储的最小单元,其内部除了保存了结点的数据内容、ACL列表、节点状态之外,还记录了父节点的引用和子节点列表两个属性,其也提供了对子节点列表进行操作的接口
    ZKDatabase:Zookeeper的内存数据库,管理Zookeeper的所有会话、DataTree存储和事务日志。ZKDatabase会定时向磁盘dump快照数据,同时在Zookeeper启动时,会通过磁盘的事务日志和快照文件恢复成一个完整的内存数据库

  • 磁盘数据
    用于恢复内存数据,类似于redis的rdb和aof
    事务日志
    记录每次操作。针对客户端的每一次事务操作,Zookeeper都会将他们记录到事务日志中,同时也会将数据变更应用到内存数据库中
    snapshot-数据快照
    数据快照是Zookeeper数据存储中非常核心的运行机制,数据快照用来记录Zookeeper服务器上某一时刻的全量内存数据内容,并将其写入指定的磁盘文件中。

    为什么同时包含:快照、事务日志?出于数据粒度的考虑
    如果只包含快照,那恢复现场的时候,会有数据丢失,因为生成快照的时间间隔太大,即,快照的粒度太粗了。
    事务日志,针对每条提交的事务都会 flush 到磁盘,因此粒度很细,恢复现场时,能够恢复到事务粒度上

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值