写点什么

Zookeeper 详细解析!分布式架构中的协调服务框架的最佳选型

发布于: 2021 年 05 月 17 日
Zookeeper详细解析!分布式架构中的协调服务框架的最佳选型

Zookeeper 概念

  • Zookeeper 是分布式协调服务,用于管理大型主机,在分布式环境中协调和管理服务是很复杂的过程,Zookeeper 通过简单的架构和 API 解决了这个问题

Zookeeper 实现分布式锁

分布式锁三要素:      加锁      解锁      锁超时
复制代码


  • Zookeeper 数据结构类似树结构,由节点 Znode 组成

  • Znode 分为四种类型:

  • 持久节点(PERSISTENT): 默认节点类型,创建节点的客户端与 Zookeeper 断开连接后,节点依旧存在

  • 持久节点顺序节点(PERSISTENT_SEQUENTIAL): 持久节点顺序节点就是在创建持久节点时,Zookeeper 根据创建节点的时间顺序给节点进行编号

  • 临时节点(EPHEMERAL): 创建节点的客户端与 Zookeeper 断开连接后,临时节点会被删除

  • 临时节点顺序节点(EPHEMERAL_SEQUENTIAL): 临时节点顺序节点就是在创建临时节点时,Zookeeper 根据创建节点的时间顺序给节点进行编号

  • 应用 Zookeeper 的临时顺序节点,实现分布式锁


Zookeeper 与 Redis 分布式锁比较:


Zookeeper 的数据模型

  • 类似数据结构中的树,文件系统中的目录

  • Zookeeper 的数据存储基于节点 Znode

  • Znode 的引用方式是路径引用,每一个 Znode 节点拥有唯一的路径

Znode 中的元素

  • data: Znode 存储的数据信息

  • ACL: 记录 Znode 的访问权限,即哪些进程和 IP 可以访问本节点

  • stat: Znode 的各种元数据(数据的数据)

  • child: 当前节点的子节点引用 Zookeeper 的应用场景是读多写少的应用场景:Znode 不用来存储大规模的业务数据,用于存储少量的状态和配置信息(Znode 存储数据不能超过 1MB)

Zookeeper 基本操作

  • 创建节点:create

  • 删除节点:delete

  • 判断节点是否存在:exists

  • 获得一个节点的数据:getData

  • 设置一个节点的数据:setData

  • 获取节点下的所有子节点:getChildrenexists,getData,getChildren 属于读操作,Zookeeper 客户端在请求读操作时,可以选择是否设置 watch

Zookeeper 事件通知

  • Watch 可以理解成注册在特定 Znode 上的触发器

  • 当 Znode 发生改变的时候,调用 create,delete,setData 方法,将会触发 Znode 上注册的对应事件,请求的 Watch 的客户端会接收到异步通知

  • Zookeeper 事件通知的交互过程:

  • 客户端调用 getData 方法,watch 的参数是 true,服务端接收到请求,返回节点数据,在对应的 Hash 表中插入被 Watch 的 Znode 路径以及 Watcher 列表

  • 当被 Watch 的 Znode 删除,服务端会查找 Hash 表,找到该 Znode 对应的所有 Watcher,异步通知客户端,并且删除 Hash 表中对应的 key-value

Zookeeper 的一致性

  • Zookeeper Service 集群是一主多从结构

  • 在更新数据时,首先更新到主服务器,再同步到从服务器

  • 在读数据时,直接读取任意节点

  • 采用 ZAB 协议,为了保证主从节点数据的一致性

ZAB 协议

  • ZAB(Zookeeper Automic Broadcast): 解决 Zookeeper 集群崩溃恢复,主从数据同步问题

  • ZAB 三种节点状态:

  • Looking:选举状态

  • Following:Following 节点(从节点)所处的状态

  • Leading:Leading(主节点)所处的状态

  • 最大 ZXID: 节点本地的最新事务编号,包含 epoch 计数两部分

ZAB 集群崩溃恢复

  • 当 Zookeeper 的主节点服务器宕机后,集群就会进行崩溃恢复,分成三个阶段:

  • Leader election(选举阶段):

  • 集群中的节点处于 Looking 状态,各自向其它节点发起投票,投票当中包含自己服务器的 ID 和最新事务 ID(ZXID)

  • 节点用自身的 ZXID 和其它节点收到的 ZXID 作比较,如果发现其它节点的 ZXID 比自身大,即数据比自己新,就重新发起投票,投票给目前已知最大 ZXID 所属节点

  • 每次投票后,服务器都会统计投票数量,判断是否某个节点得到半数以上的投票,这样的节点将会成为准 Leader,状态变为 Leading,其它节点状态变为 Following

  • Discovery(发现阶段):

  • 在从节点发现最新的 ZXID 和事务日志,目的是为了防止在意外情况,选举产生多个 Leader

  • Leader 接收所有 Follower 发送的最新的 epoch 值,Leader 从中选出最大的 epoch,基于此值+1,生成新的 epoch 分发给各个 Follower

  • 各个 Follower 接收到最新的 epoch,返回 ACK(响应码)给 Leader,带上各自最大的 ZXID 和历史事务日志,Leader 选出最大的 ZXID,并更新自身历史日志

  • Synchronization(同步阶段):

  • 将 Leader 收集得到的最新历史事务日志,同步给集群中的所有 Follower,只有当半数 Follower 同步成功,这个准 Leader 才能成为正式 Leader.集群崩溃恢复正式完成

ZAB 主从数据同步

  • BroadcastZookeeper 常规情况下更新数据的时候,由 Leader 广播到所有的 Follower:

  • 客户端发出写入数据请求给任意的 Follower

  • Follower 把写入数据请求转发给 Leader

  • Leader 采取二阶段提交方式:(先保留提交日志,再提交数据)先发送 Propose 广播给 Follower

  • Follower 接收到 Propose 消息,写入日志成功后,返回 ACK 消息给 Leader

  • Leader 接收到半数以上的 ACK 消息,返回成功给客户端,并且广播 commit 请求给 Follower


数据一致性:    强一致性    弱一致性    顺序一致性:Zookeeper,依靠事务ID和版本号,保证数据的更新和读取是有序的
复制代码

Zookeeper 应用场景

  • 分布式锁: 应用 Zookeeper 的临时顺序节点,实现分布式锁

  • 服务注册与发现: 利用 Znode 和 Watcher,实现分布式服务注册与发现,如 Dubbo

  • 共享配置和状态信息: Redis 的分布式解决方案 Codls,利用 Zookeeper 存放数据路由表和 codls-proxy 节点元信息,同时 colds-config 发起的命令都会通过 Zookeeper 同步到各个存活的 codls-proxy

  • 高可用实现: Kafka,HBase,Hadoop 都依靠 Zookeeper 同步节点信息,实现高可用

基于 Docker 创建 Zookeeper

1.创建docker-compose.ymlzoo:  image: zookeeper  restart: always  hostname: zoo  ports:    - 2181:2181  environment:    - ZOO_MY_ID: 1    - ZOO_SERVER: server.1(id)=zoo(IP):2888:38882.执行docker-compose up -d
复制代码

Zookeeper 三种工作模式

  • 单机模式: 存在单点故障

  • 集群模式: 在多台服务器上部署 Zookeeper 集群

  • 伪集群模式: 在同一台服务器上运行多个 Zookeeper 实例,仍然有单点故障问题,其中配置的端口号要错开

Zookeeper 三种端口号

  • 2181: 客户端连接 Zookeeper 集群使用的监听端口号

  • 3888: 选举 Leader 使用

  • 2888: 集群内机器通讯使用(Leader 和 Follower 之间数据同步使用的端口号,Leader 监听此端口)

发布于: 2021 年 05 月 17 日阅读数: 23
用户头像

一位攻城狮的自我修养 2021.04.06 加入

分享技术干货,面试题和攻城狮故事。 你的关注支持是我持续进步的最大动力! https://github.com/ChovaVea

评论

发布
暂无评论
Zookeeper详细解析!分布式架构中的协调服务框架的最佳选型