zookeeper 概念

zookeeper的设计目的

  • 最终一致性:无论连接哪个server,得到的视图相同
  • 可靠性:如果消息被一台server接收,将被所有视图可见
  • 实时性:在一定的时间段内能收到更新消息,调用sync()可以手动获取最新消息
  • 等待无关:慢的client不会干扰处理较快的client
  • 原子性:数据更新要么成功要么失败
  • 顺序性:
    • 全局有序是指如果在一台服务器上消息a在消息b前发布,则在所有Server上消息a都将在消息b前被发布
    • 偏序是指如果一个消息b在消息a后被同一个发送者发布,a必将排在b前面。

数据结构

  • zk的数据结构设计成类似于文件系统树的结构
  • zk的数据放在内存中保证了它的高效
  • 每个节点都是一个znode,既是文件也是文件夹,可以存储数据
  • 在zk的命名空间中,用path路径定义一个节点

znode

  • znode中包含的数据
    • 消息版本
    • 时间戳
    • acl(Access Control List 权限列表)
    • 数据(一般数据很小1k以内)
  • 读写操作都是原子性的(要么成功要么失败)
  • 四种类型的znode节点:
    • PERSISTENT:持久节点
    • PERSISTENT_SEQUENTIAL:持久节点,同时自动排序
    • EPHEMERAL:临时节点,创建session 时创建节点,断开session 时删除节点
    • EPHEMERAL_SEQUENTIAL:临时节点,同时自动排序
  • 监听:可以监听znode的变化,数据改变、被删除、子目录节点增加删除

分布式zookeeper

  • 在所有机器间进行数据复制:
    • 容错
    • 提高系统的吞吐能力,提高负载能力
    • 所有客服端就近访问,降低延时
  • 保持最终一致性

角色


  • leader:更新时发起投票(所有的写请求都会发到leader上),更新系统状态
    • 恢复数据
    • 维持和follower和observer的心跳
    • 接收follower和observer的请求:心跳、写请求和同步、对提议(COMMIT)的回复、延长session有效时间
  • follower:响应客户端的请求,参与投票;
    • 向Leader发送请求(心跳、写请求和同步、对提议的回复(投票)、延长session有效时间)
    • 接收Leader消息并进行处理(PING,对提案投票、COMMIT、UPTODATE完成同步、延长session的请求结果、返回SYNC结果)
    • 接收client写请求,则发给leader
    • 接收client读请求,返回结果
    • 接收client同步请求,发给leader
  • observer:作用和follower一样,只是不参与投票
    • 区别于follower:随着机器的添加,因为网络消耗等原因必定导致投票成本添加,从而导致写性能的下降。

Observer的意义:https://www.cnblogs.com/EasonJim/p/7488484.html
三种角色: https://blog.csdn.net/mayp1/article/details/52026797

工作原理

  • zab协议包括恢复模式(选主)和广播模式(同步)
    • 恢复模式:leader崩溃后,开始选择leader,然后同步数据
    • 广播模式:保证leader和server间数据一致
  • 保证事务顺序一致:使用递增的事务id来表示数据
  • 工作状态:
    • looking:搜索leader
    • leading:作为leader
    • following:作为follower

客户端请求

  • 一个客户端连接是指客户端和 ZooKeeper 服务器之间的TCP长连接,通过这个连接,客户端能够通
    过心跳检测和服务器保持有效的会话。
  • 客户端向zk发送读请求,直接返回值。每个zk节点上的数据都是完整的
  • 客户端向zk发送写请求
    • 发送到leader:leader生成事务Proposal,广播给所有的follower,follower收到后进行入库,同时反馈ack。当过半follower反馈ack后,leader发送消息提交Proposal。
      • 广播事务Proposal之前,leader会分配一个全局唯一的事务id(ZXID)
    • 发送到follower或者observer,转发到leader上

zxid

  • 高32位是Leader的epoch,从1开始,每次选出新的Leader,epoch加一;每个leader的epoch唯一
  • 低32位为该epoch内的序号,每次epoch变化,都将低32位的序号重置;

leader和observer、follower通信

  • leader和follower、observer使用tcp进行通信,tcp本身fifo,对广播消息的接受和发送保序
  • leader崩溃或者leader丢失过半follower,进入崩溃恢复模式(leader选举)

leader选举

  • 进行leader选举时,选票包括:
    • logicClock 表示这是该服务器发起的第多少轮投票,从1开始计数。ZooKeeper规定所有有效的投票都必须在同一轮次中
    • state 当前服务器的状态
    • self_id 当前服务器的唯一ID
    • self_zxid 当前服务器上所保存的数据的最大事务ID,从0开始计数
    • vote_id 被推举的服务器的唯一ID
    • vote_zxid 被推举的服务器上所保存的数据的最大事务ID,从0开始计数
  • 在leader的选择上,应该确保被提交的事务不丢失,同时丢弃未提交的事务。基于这个目标:使用集群中节点的zxid作为选举依据(尽量选择zxid最大的节点)
  • 每个节点都有一个投票箱,开始投票的时候需要先清空投票箱,该投票箱记录了所收到的选票,只记录每个投票者最新的选票
  • 整体思路:每个节点选择自己认为最优节点,广播给全网,剩余节点收到经过比较整理;不断重复上面步骤,选出超半数节点认可的节点作为leader
选举步骤
  • 每个服务器最开始都是通过广播把票投给自己。
  • 接收其它服务器的投票,记入自己的投票箱内
  • 选票按logicClock -> vote_zxid -> vote_id依次判断
  • 外部投票的logicClock > 自己的logicClock:该服务器的选举轮次落后于其它服务器的选举轮次,清空自己的投票箱,将自己的logicClock更新为收到的logicClock
  • 外部投票的logicClock < 自己的logicClock: 忽略该投票,继续处理下一个投票;
  • 外部投票的logickClock = 自己的
    • self_zxid < vote_zxid:将自己的票中的vote_zxid与vote_myid更新为收到的票,将收到的票及自己更新后的票放入自己的票箱
    • self_zxid = vote_zxid
      • self_id < vote_id:将自己的票中的vote_myid更新为收到的票中的vote_myid并广播出去,将收到的票及自己更新后的票放入自己的票箱
  • 过半服务器认可一台服务器作为leader,则终止投票.
  • 若过半的票投给了自己,则将自己的服务器状态更新为LEADING,否则将自己的状态更新为FOLLOWING。
  • 成为Leader的服务器要主动向Follower发送心跳包,Follower做出ACK回应,以维持他们之间的长连接。

同步流程

  • leader等待链接
  • follower和observer链接后将zxid(事务id)发给leader
  • leader确定同步点后进行同步
  • 同步完成后通知follower,状态改为uptodate,follower可以接收client请求

应用场景

命名服务

  • 在znode上创建一个目录,该目录下的所有节点都是唯一的path

配置中心

  • 将配置信息放到一个znode上,所有相关应用程序对这个目录节点进行监听,一旦配置信息发生变化,每个应用程序就会收到 Zookeeper 的通知

集群管理

  • 机器退出和加入:约定在指定目录下创建临时节点,同时监听该节点的子节点变化
  • 选举master:所有的临时节点都是有序的,选择序号最小的为master

分布式锁

  • 保持锁定:所有服务在指定节点下创建节点,成功创建者获取锁,失败者监听该节点,用完后销毁。
  • 控制顺序:所有服务在指定节点下创建有序节点,获取最小的节点,如果该节点是自己,则获得锁,用完后删除;否则监听比自己小的节点

参考:
前16条写的不错:https://www.cnblogs.com/felixzh/p/5869212.html https://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/
zab协议:https://www.jianshu.com/p/3fec1f8bfc5f

猜你喜欢

转载自blog.csdn.net/designer01/article/details/82225990