Chlins' Blog

Hi, nice to meet you.

  1. 1. 介绍
  2. 2. 应用场景
  3. 3. Zab协议
    1. 3.1. 集群状态
  4. 4. Reference

介绍

ZooKeeper is a centralized service for maintaining configuration information, naming, providing distributed synchronization, and providing group services. All of these kinds of services are used in some form or another by distributed applications. Each time they are implemented there is a lot of work that goes into fixing the bugs and race conditions that are inevitable. Because of the difficulty of implementing these kinds of services, applications initially usually skimp on them ,which make them brittle in the presence of change and difficult to manage. Even when done correctly, different implementations of these services lead to management complexity when the applications are deployed.

以上摘自官方文档对zookeeper的定义和主要功能的介绍,简单的来说,可以将它定义为一个分布式的协调器,本身它也是Google chubby框架的开源实现,可以用它来实现分布式锁,配置中心等功能。zookeeper的文件存储模型本身也是非常的友好的,是一种类似标准文件系统的树形结构,如:

1
2
3
4
5
6
7
8
/------
/Services-------
/Service1
/Service2

/Groups---------
/Group1
/Group2

数据结构特征:

  1. 目录项称为znode,唯一标识
  2. znode下可以创建子znode,每个znode可以存储数据,类似redis中的key-value
  3. znode可以定义版本
  4. znode可以通过session与server之间创建临时节点,即当session失效后,自动删除znode
  5. 顺序节点,即zk提供自动向后编号节点,例如 app1, app2, app3 ……
  6. 提供watch机制,可以对znode进行监控

应用场景

👆介绍了zk的存储的数据结构,现在我们看看可以用它来实现哪些功能

  • 分布式锁

​ zk可以实现跨主机之间的锁,实现的方法其实就是创建一个临时的目录节点,查看该目录下的子目录中节点编号最小的那个节点,如果是自己创建的,则拿到了锁,否则对比自己小的中最大的那个节点建立监听器,注意这里为什么不是对最小的那个建立监听器是为了避免一旦最小节点的锁释放,而导致需要向所有监听节点发送事件而导致的羊群效应,当自己为集群中最小的节点时,即拿到锁,释放锁只要删除自己创建的znode就可以了。

  • 队列

​ 创建顺序节点,每次返回节点编号数最小的那个,即实现了FIFO。

  • 命名服务

​ 通过znode间的层次关系以及顺序节点的特效可以实现更加方便快捷的服务命名。

  • 配置中心

​ 集群中如果某个配置变更,需要所有运行的app切换至新的配置,如果手工去操作,当集群规模很大时,无异于是非常繁琐的一个工作,这时候我们可以让所有的app的去监控配置目录,由应用自主重启。

  • 集群管理

​ 集群的管理主要是两个核心功能,即新机器的上线和旧机器的下线,我们可以很方便的通过watch机制来实现。

Zab协议

zookeeper之所以能够实现分布式,保障数据的一致性,是通过zookeeper atomic broadcast来保障的,即zookeeper原子广播协议,在分布式领域,有一个非常经典的理论,即CAP理论,也同样有一个非常经典的分布式算法,即Paxos算法,不过Paxos算法的工程实现较为复杂,所以后来出现了Multi Paxos算法,例如zab和raft等。

集群状态

  1. 崩溃恢复状态

进入情况:

  • 服务启动
  • leader服务崩溃或者网络故障
  • 新节点加入集群且集群处于广播状态

此时集群异常,需要开始新的一轮选主,节点状态又可分为以下四种:

  • looking 集群无leader,准备选主
  • following 集群存在leader
  • leading 即唯一leader
  • observing 观察者

数据模型:

  • sid server id标识机器
  • zxid 事务id 递增

选主规则:

  • 初始状态会给自己投票
  • 接收到其他服务器的投票后,优先检查zxid,zxid比较大的优先作为leader,若相同,则比较sid,大的优先作为leader
  • 超过集群半数的机器投了一个node,则投票结束,node设置各自为leader或者follower
  1. 消息广播状态

进入情况:

集群已有leader,且超过半数的机器状态同步完成

这个状态就是集群的正常工作态,也就是数据同步的状态

  • 读请求由follower或observer直接返回给client
  • 写请求统一都会被转发给leader,leader分配唯一的事务id,然后向follower发起proposal,follower收到后首先以事务日志的形式写到磁盘上,防止丢失,然后在写入成功后,向leader发送成功写入的Ack,leader收到半数以上的follower的Ack后,广播commit消息通知follower进行事务提交,同时自身也会进行commit

Reference

感谢广大网友的热心分享

https://mp.weixin.qq.com/s/DjYEreC-5ADiZXKdlzpnxw

http://zookeeper.apache.org/

https://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/index.html

https://www.cnblogs.com/felixzh/p/5869212.html

本文最后更新于 天前,文中所描述的信息可能已发生改变