Zookeeper基础知识原理篇

Zookeeper 的前世今生
Apache ZooKeeper 是一个高可靠的分布式协调中间件。它是 Google Chubby 的一个开源 实现,那么它主要是解决什么问题的呢?那就得先了解 Google Chubby Google Chubby 是谷歌的一个用来解决分布式一致性问题的组件,同时,也是粗粒度的分布
式锁服务。
 
分布式一致性问题
什么是分布式一致性问题呢?简单来说,就是在一个分布式系统中,有多个节点,每个节点 都会提出一个请求,但是在所有节点中只能确定一个请求被通过。而这个通过是需要所有节 点达成一致的结果,所以所谓的一致性就是在提出的所有请求中能够选出最终一个确定请求.并且这个请求选出来以后,所有的节点都要知道。
由于网络通信存在不可靠的问题,也就是可能存在消息丢失,或者网 络延迟。如何在这样的背景下对某一个请求达成一致。 为了解决这个问题,很多人提出了各种协议,比如大名鼎鼎的 Paxos; 也就是说在不可信的 网络环境中,按照 paxos 这个协议就能够针对某个提议达成一致。 所以:分布式一致性的本质,就是在分布式系统中,多个节点就某一个提议如何达成一致
 
这个和 Google Chubby 有什么关系呢
 
在 Google 有一个 GFS(google file system),他们有一个需求就是要从多个 gfs server 中选出 一个 master server。这个就是典型的一致性问题,5 个分布在不同节点的 server,需要确定 一个 master server,而他们要达成的一致性目标是:确定某一个节点为 master,并且所有节 点要同意。
而 GFS 就是使用 chubby 来解决这个问题的。 实现原理是:所有的 server 通过 Chubby 提供的通信协议到 Chubby server 上创建同一个文 件,当然,最终只有一个 server 能够获准创建这个文件,这个 server 就成为了 master,它 会在这个文件中写入自己 的地址,这样其它的 server 通过读取这个文件就能知道被选出的 master 的地址.
Zookeeper基础知识原理篇_第1张图片
分布式锁服务
从另外一个层面来看,Chubby 提供了一种粗粒度的分布式锁服务,chubby 是通过创建文件 的形式来提供锁的功能,server 向 chubby 中创建文件其实就表示加锁操作,创建文件成功 表示抢占到了锁。 由于 Chubby 没有开源,所以雅虎公司基于 chubby的思想,开发了一个类似的分布式协调 组件 Zookeeper,后来捐赠给了 Apache。 所以,大家一定要了解,zookeeper 并不是作为注册中心而设计,他是作为分布式锁的一种 设计。而注册中心只是他能够实现的一种功能而已。
 
 
zookeeper 的设计猜想
 
基于 Zookeeper 本身的一个设计目标,zookeeper 主要是解决分布式环境下的服务协调问题 而产生的,我们来猜想一下,如果我们要去设计一个 zookeeper,需要满足那些功能呢?
 
防止单点故障
首先,在分布式架构中,任何的节点都不能以单点的方式存在,因此我们需要解决单点的问 题。常见的解决单点问题的方式就是集群 大家来思考一下,这个集群需要满足那些功能?
1. 集群中要有主节点和从节点(也就是集群要有角色)
2. 集群要能做到数据同步,当主节点出现故障时,从节点能够顶替主节点继续工作,但是继
续工作的前提是数据必须要主节点保持一直
3. 主节点挂了以后,从节点如何接替成为主节点? 是人工干预?还是自动选举
所以基于这几个点,我们先来把 zookeeper 的集群节点画出来。
 
 
Leader 角色
Leader 服务器是整个 zookeeper 集群的核心,主要的工作任务有两项
1. 事物请求的唯一调度和处理者,保证集群事物处理的顺序性
2. 集群内部各服务器的调度者
 
Follower 角色
Follower 角色的主要职责是
1. 处理客户端非事物请求、转发事物请求给 leader 服务器 2. 参与事物请求 Proposal 的投票(需要半数以上服务器通过才能通知 leader commit 数据;
Leader 发起的提案,要求 Follower 投票)
3. 参与 Leader 选举的投票
 
数据同步
接着上面那个结论再来思考,如果要满足这样的一个高性能集群,我们最直观的想法应该是, 每个节点都能接收到请求,并且每个节点的数据都必须要保持一致。要实现各个节点的数据 一致性,就势必要一个 leader 节点负责协调和数据同步操作。这个我想大家都知道,如果在 这样一个集群中没有 leader 节点,每个节点都可以接收所有请求,那么这个集群的数据同步的复杂度是非常大
所以,当客户端请求过来时,需要满足,事务型数据和非事务型数据的分开处理方式,就是 leader 节点可以处理事务和非事务型数据。而 follower 节点只能处理非事务型数据。原因是, 对于数据变更的操作,应该由一个节点来维护,使得集群数据处理的简化。同时数据需要能 够通过 leader 进行分发使得数据在集群中各个节点的一致性

 

Zookeeper基础知识原理篇_第2张图片

 

leader 节点如何和其他节点保证数据一致性,并且要求是强一致的。在分布式系统中,每一 个机器节点虽然都能够明确知道自己进行的事务操作过程是成功和失败,但是却无法直接获 取其他分布式节点的操作结果。所以当一个事务操作涉及到跨节点的时候,就需要用到分布 式事务,分布式事务的数据一致性协议有 2PC 协议和 3PC 协议
 
关于 2PC 提交
 
当一个事务操作需要跨越多个分布式节点的时候,为 了保持事务处理的 ACID 特性,就需要引入一个“协调者”(TM)来统一调度所有分布式节点 的执行逻辑,这些被调度的分布式节点被称为 AP。TM 负责调度 AP 的行为,并最终决定这 些 AP 是否要把事务真正进行提交;因为整个事务是分为两个阶段提交,所以叫 2pc
Zookeeper基础知识原理篇_第3张图片
 
阶段一:提交事务请求(投票)
1. 事务询问
协调者向所有的参与者发送事务内容,询问是否可以执行事务提交操作,并开始等待各参与者的 响应
2. 执行事务
各个参与者节点执行事务操作,并将 Undo 和 Redo 信息记录到事务日志中,尽量把提交过程中 所有消耗时间的操作和准备都提前完成确保后面 100%成功提交事务
3. 各个参与者向协调者反馈事务询问的响应
如果各个参与者成功执行了事务操作,那么就反馈给参与者 yes 的响应,表示事务可以执行; 如果参与者没有成功执行事务,就反馈给协调者 no 的响应,表示事务不可以执行,上面这个阶 段有点类似协调者组织各个参与者对一次事务操作的投票表态过程,因此 2pc 协议的第一个阶 段称为“投票阶段”,即各参与者投票表名是否需要继续执行接下去的事务提交操作。
 
阶段二:执行事务提交
 
在这个阶段,协调者会根据各参与者的反馈情况来决定最终是否可以进行事务提交操作,正常情况 下包含两种可能:执行事务、中断事务
 
Observer 角色
Observer 是 zookeeper3.3 开始引入的一个全新的服务器角色,从字面来理解,该角色充当 了观察者的角色。
观察 zookeeper 集群中的最新状态变化并将这些状态变化同步到 observer 服务器上。 Observer 的工作原理与 follower 角色基本一致,而它和 follower 角色唯一的不同在于 observer 不参与任何形式的投票,包括事物请求 Proposal 的投票和 leader 选举的投票。简 单来说,observer 服务器只提供非事物请求服务,通常在于不影响集群事物处理能力的前提 下提升集群非事物处理的能力。
 
 
leader 选举
当 leader 挂了,需要从其他 follower 节点中选择一个新的节点进行处理,这个时候就需要涉 及到 leader 选举
从这个过程中,我们推导处了 zookeeper 的一些设计思想
 
数据模型
 
zookeeper 的视图结构和标准的文件系统非常类似,每一个 节点称之为 ZNode,是 zookeeper 的最小单元。每个 znode
上都可以保存数据以及挂载子节点。构成一个层次化的树形 结构 持久节点(PERSISTENT) 创建后会一直存在 zookeeper 服务器上,直到主动删除 持久有序节点(PERSISTENT_SEQUENTIAL) 每个节点都会为它的一级子节点维护一个顺序
临时节点(EPHEMERAL) 临时节点的生命周期和客户端的会话绑定在一起,当客户端会话 失效该节点自动清理
临时有序节点(EPHEMERAL) 在临时节点的基础上多了一个顺序性 CONTAINER 当子节点都被删除后,Container 也随即删除 PERSISTENT_WITH_TTL 超过 TTL 未被修改,且没有子节点 PERSISTENT_SEQUENTIAL_WITH_TTL 客户端断开连接后不会 自动删除 Znode,如果该 Znode 没有子 Znode 且在给定 TTL 时 间内无修改,该 Znode 将会被删除;TTL 单位是毫秒,必须大于 0 且小于或等于 EphemeralType.MAX_TTL
 
 
会话
Zookeeper基础知识原理篇_第4张图片
1. Client 初始化连接,状态转为 CONNECTING(①)
2. Client 与 Server 成功建立连接,状态转为 CONNECTED(②)
3. Client 丢失了与 Server 的连接或者没有接受到 Server 的响
应,状态转为 CONNECTING(③)
4. Client 连上另外的 Server 或连接上了之前的 Server,状态
转为 CONNECTED(②)
5. 若会话过期(是 Server 负责声明会话过期,而不是 Client ),
状态转为 CLOSED(⑤),状态转为 CLOSED
6. Client 也可以主动关闭会话(④),状态转为 CLOSED

 

Stat 状态信息
每个节点除了存储数据内容以外,还存储了数据节点本身的 一些状态信息,通过 get 命令可以获得状态信息的详细内容
 
Zookeeper基础知识原理篇_第5张图片
 
 
版本-保证分布式数据原子性
 
zookeeper 为数据节点引入了版本的概念,每个数据节点都有三 类版本信息,对数据节点任何更新操作都会引起版本号的变化

版本有点和我们经常使用的乐观锁类似。这里有两个概念说 一下,一个是乐观锁,一个是悲观锁 悲观锁:是数据库中一种非常典型且非常严格的并发控制策 略。假如一个事务 A 正在对数据进行处理,那么在整个处理 过程中,都会将数据处于锁定状态,在这期间其他事务无法 对数据进行更新操作。 乐观锁:乐观锁和悲观锁正好想法,它假定多个事务在处理
过程中不会彼此影响,因此在事务处理过程中不需要进行加 锁处理,如果多个事务对同一数据做更改,那么在更新请求
提交之前,每个事务都会首先检查当前事务读取数据后,是 否有其他事务对数据进行了修改。如果有修改,则回滚事务
再回到 zookeeper,version 属性就是用来实现乐观锁机制的 “写入校验”
 
Watcher
 
zookeeper 提供了分布式数据的发布/订阅功能,zookeeper 允许客户端向服务端注册一个 watcher 监听,当服务端的一
些指定事件触发了 watcher,那么服务端就会向客户端发送 一个事件通知。 值得注意的是,Watcher 通知是一次性的,即一旦触发一次 通知后,该 Watcher 就失效了,因此客户端需要反复注册 Watcher,即程序中在 process 里面又注册了 Watcher,否则,
将无法获取 c3 节点的创建而导致子节点变化的事件。
一些搭建的api可以看下我的另外一篇博客: zk的一些基础操作知识
 
 
 

你可能感兴趣的:(中间件)