Zookeeper 详解

本贴最后更新于 1253 天前,其中的信息可能已经时过境迁

1、 概述

  Zookeeper 是一个开源的分布式协调服务,从设计模式角度来理解:是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生变化,Zookeeper 就将负责通知已经在 Zookeeper 上注册的那些观察者做出相应的反应。

01.png

  1. 服务端启动时去注册信息(创建都是临时节点)
  2. 获取到当前在线服务器列表,并且注册监听
  3. 服务器节点下线
  4. 服务器节点上下线事件通知
  5. 重新再去获取服务器列表,并注册监听

ZooKeeper = 文件系统 + 通知机制

2、特点

02.png

  1. Zookeeper:一个领导者(Leader),多个跟随者(Follower)组成的集群。
  2. 集群中只要有半数以上节点存活,Zookeeper 集群就能正常服务(节点多为奇数)。
  3. 全局数据一致:每个 Server 保存一份相同的数据副本,Client 无论连接到哪个 Server,数据都是一致的。
  4. 更新请求顺序进行,来自同一个 Client 的更新请求按其发送顺序依次执行。
  5. 数据更新原子性,一次数据更新要么成功,要么失败。
  6. 实时性,在一定时间范围内,Client 能读到最新数据。

3、数据结构

  Zookeeper 数据模型的结构与 Unix 文件系统很类似,整体上可以看作是一棵树, 每个节点称做一个 ZNode。每一个 ZNode 默认能够存储 1MB 的数据, 每个 ZNode 都可以通过其路径唯一标识。

03.png

  和文件系统一样,我们能够自由的增加、删除 znode,在一个 znode 下增加、删除子 znode,唯一的不同在于 znode 是可以存储数据的。

  有四种类型的 znode:

  • PERSISTENT-持久化目录节点
    客户端与 zookeeper 断开连接后,该节点依旧存在
  • PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点
    客户端与 zookeeper 断开连接后,该节点依旧存在,只是 Zookeeper 给该节点名称进行顺序编号
  • EPHEMERAL-临时目录节点
    客户端与 zookeeper 断开连接后,该节点被删除
  • EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点
    客户端与 zookeeper 断开连接后,该节点被删除,只是 Zookeeper 给该节点名称进行顺序编号

**说明:**创建 znode 时设置顺序标识,znode 名称后会附加一个值,顺序号是一个单调递增的计数器,由父节点维护

**注意:**在分布式系统中,顺序号可以被用于为所有的事件进行全局排序, 这样客户端可以通过顺序号推断事件的顺序

4、应用场景

4.1 统一命名服务

  在分布式环境下,经常需要对应用/服务进行统一命名,便于识别。

  例如:IP 不容易记住,而域名容易记住。

04.png

4.2 统一配置管理

  1. 分布式环境下,配置文件同步非常常见

    (1)一般要求一个集群中,所有节点的配置信息是一致的,比如 Kafka 集群

    (2)对配置文件修改后,希望能够快速同步到各个节点上

  2. 配置管理可交由 ZooKeeper 实现

    (1)可将配置信息写入 ZooKeeper 上的一个 Znode

    (2)各个客户端服务器监听这个 Znode

    (3)一旦 Znode 中的数据被修改, ZooKeeper 将通知各个客户端服务器

  假设我们的程序是分布式部署在多台机器上,如果我们要改变程序的配置文件,需要逐台机器去修改,非常麻烦,现在把这些配置全部放到 zookeeper 上去,保存在 zookeeper 的某个目录节点中,然后所有相关应用程序对这个目录节点进行监听,一旦配置信息发生变化,每个应用程序就会收到 zookeeper 的通知,然后从 zookeeper 获取新的配置信息应用到系统中。

05.png

4.3 统一集群管理

  1. 分布式环境中,实时掌握每个节点的状态是必要的

    (1)可根据节点实时状态做出一些调整

  2. ZooKeeper 可以实现实时监控节点状态变化

    (1)可将节点信息写入 ZooKeeper 上的一个 ZNode

    (2)监听这个 ZNode 可获取它的实时状态变化

06.png

4.4 软负载均衡

  在 Zookeeper 中记录每台服务器的访问数, 让访问数最少的服务器去处理最新的客户端请求。

07.png

5、选举机制

  1. 半数机制:集群中半数以上机器存活,集群可用。所以 Zookeeper 适合安装奇数台服务器。例如,5 台服务器有 3 台存活,集群可用,而只有 2 台存活,集群不可用。
  2. Zookeeper 虽然在配置文件中并没有指定 Master 和 Slave。 但是, Zookeeper 工作时,是有一个节点为 Leader,其他则为 Follower, Leader 是通过内部的选举机制临时产生的。

  假设有五台服务器组成的 Zookeeper 集群,它们的 id 从 1-5,同时它们都是最新启动的,也就是没有历史数据,在存放数据量这一点上,都是一样的。假设这些服务器依序启动:

08.png

  1. 服务器 1 启动, 发起一次选举。服务器 1 投自己一票。此时服务器 1 票数一票,不够半数以上(3 票),选举无法完成,服务器 1 状态保持为 LOOKING;
  2. 服务器 2 启动, 再发起一次选举。服务器 1 和 2 分别投自己一票并交换选票信息:此时服务器 1 发现服务器 2 的 ID 比自己目前投票推举的(服务器 1)大,更改选票为推举服务器 2。此时服务器 1 票数 0 票,服务器 2 票数 2 票,没有半数以上结果,选举无法完成,服务器 1, 2 状态保持 LOOKING
  3. 服务器 3 启动, 发起一次选举。此时服务器 1 和 2 都会更改选票为服务器 3。此次投票结果:服务器 1 为 0 票,服务器 2 为 0 票,服务器 3 为 3 票。此时服务器 3 的票数已经超过半数,服务器 3 当选 Leader。服务器 1, 2 更改状态为 FOLLOWING,服务器 3 更改状态为 LEADING;
  4. 服务器 4 启动, 发起一次选举。此时服务器 1, 2, 3 已经不是 LOOKING 状态,不会更改选票信息。交换选票信息结果:服务器 3 为 3 票,服务器 4 为 1 票。此时服务器 4 服从多数,更改选票信息为服务器 3,并更改状态为 FOLLOWING;
  5. 服务器 5 启动,同 4 一样更改状态为 FOLLOWING。

6、监听器原理

  1. 首先要有一个 main()线程
  2. 在 main 线程中创建 Zookeeper 客户端, 这时就会创建两个线程, 一个负责网络连接通信( connet ), 一个负责监听( listener )。
  3. 通过 connect 线程将注册的监听事件发送给 Zookeeper。
  4. 在 Zookeeper 的注册监听器列表中将注册的监听事件添加到列表中。
  5. Zookeeper 监听到有数据或路径变化, 就会将这个消息发送给 listener 线程。
  6. listener 线程内部调用了 process()方法。

10.png

常见的监听:

  1. 监听节点数据的变化 get path [watch]
  2. 监听子节点增减的变化 ls path [watch]

7、写数据流程

11.png

  1. Client 向 ZooKeeper 的 Server1 上写数据,发送一个写请求。
  2. 如果 Server1 不是 Leader,那么 Server1 会把接受到的请求进一步转发给 Leader,因为每个 ZooKeeper 的 Server 里面有一个是 Leader。这个 Leader 会将写请求广播给各个 Server, 比如 Server1 和 Server2,各个 Server 会将该写请求加入待写队列,并向 Leader 发送成功信息。
  3. 当 Leader 收到半数以上 Server 的成功信息, 说明该写操作可以执行。Leader 会向各个 Server 发送提交信息,各个 Server 收到信息后会落实队列里的写请求, 此时写成功
  4. Server1 会进一步通知 Client 数据写成功了,这时就认为整个写操作成功。
  • ZooKeeper

    ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现,是 Hadoop 和 HBase 的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

    59 引用 • 29 回帖 • 18 关注
1 操作
wlgzs-sjl 在 2020-11-19 20:44:33 更新了该帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...