ZooKeeper
2020-09-29 15:43:01 0 举报
AI智能生成
登录查看完整内容
分布式协调系统:ZooKeeper
作者其他创作
大纲/内容
应用场景
数据发布/订阅
发布/订阅系统一般有两种设计模式
推(Push)模式
服务端主动将数据更新发送给所有订阅的客户端
拉(Pull)模式
由客户端主动发起请求来获取最新数据,通常客户端都采用定时进行轮询拉取的方式
ZooKeeper采用推拉相结合的方式
客户端向服务端注册自己需要关注的节点,一旦该节点的数据发生变更,那么服务端就会向相应的客户端发送Watcher事件通知,客户端收到这个消息通知后,需要主动到服务端获取最新的数据。
负载均衡
命名服务
分布式协调/通知
集群管理
Master选举
Master节点宕机后,其他节点尝试在ZooKeeper中创建相同的临时节点,创建成功的作为Master节点,其他节点监听这个节点。
利用ZooKeeper的强一致性
分布式锁
获取锁
1、创建临时有序的节点,如:/lock/lock_000000001
2、获取/lock节点的子节点列表,并判断当前创建的子节点是否最小
1、最小,获取锁
2、否,监听前一个节点并阻塞等待通知唤醒
释放锁
1、删除对应的临时有序节点
2、节点删除并通知监听该节点的客户端停止阻塞,并判断当前节点是否是最小的临时有序节点并尝试获取锁
羊群效应
简单来说就是一拥而上
用另一种方式实现分布式锁,所有的客户端尝试在ZooKeeper中创建一个临时节点(假设:/lock),那个节点创建成功那个节点获取锁,其他节点监听这个节点,羊群效应来了,当获取锁的节点释放锁后,通知所有客户端(假设成千上万)尝试创建节点
分布式队列
一致性协议
二阶段提交协议
阶段一:提交事务请求
1、事务询问
2、执行事务
3、各参与者向协调者反馈事务询问的响应
阶段二:执行事务提交
执行事务提交
1、发送提交事务
2、事务提交
3、反馈事务提交结果
4、完成事务
中断事务
1、发送回滚请求
2、事务回滚
3、返回事务回滚结果
4、中断事务
三阶段提交协议
阶段一:CanCommit
2、各参与者向协调者反馈事务询问的响应
阶段二:PreCommit
执行事务预提交
1、发送预提交请求
2、事务预提交
3、各参与者向协调者反馈事务执行的响应
1、发送中断请求
2、中断事务
阶段三:doCommit
执行提交
1、发送提交请求
3、反馈事务回滚结果
4、事务中断
Paxos协议
ZooKeeper与Paxos
ZAB协议
ZooKeeper中的一致性协议,ZooKeeper并没有完全采用Paxos算法,而是使用了ZAB(原子消息广播协议)
基于该协议,ZooKeeper实现了一种主备模式的系统架构来保持集群中各个副本之间的数据一致性。具体的,ZooKeeper使用一个单一的主进程来接收并处理客户端的所有事物请求,并采用ZAB的原子广播协议,将服务器数据的状态变更以事务Proposal(提议)的形式广播到所有副本进程上去。
消息广播
ZAB协议的消息广播过程使用的是一个原子广播协议,类似于一个二阶段提交过程
针对客户端的事务请求,Leader服务器会为其生成对应的Proposal,并将其发送给集群中其余的所有机器,然后再分别收集各自的选票,最后进行事务提交。
与二阶段提交协议不同之处在于,在ZAB协议的二阶段提交过程中,移除了中断逻辑
崩溃恢复
ZAB协议的这个基于原子广播协议的消息广播过程,依赖于Leader服务器,所以一旦Leader服务器宕机,就需要迅速选举出Leader,这也是崩溃恢复的由来
Leader选举结束后进行数据同步,选举过程参考集群
ZooKeeper
介绍及核心概念
分布式系统面临的问题
ZooKeeper的主要使用场景,是作为分布式系统的分布式协同服务
通信问题
数据同步问题
故障转移问题
leader选举问题
分布式系统的协调工作方式
分布式系统的协调工作就是通过某种方式,让每个节点的信息能够同步和共享。这依赖于服务进程之间的通信。通信方式有两种:
通过网络进行信息共享
通过共享存储
ZooKeeper是通过共享存储实现协同服务的
介绍
ZooKeeper是什么?
ZooKeeper是一个开放源代码的分布式协调服务,ZooKeeper的设计目标是将那些复杂且容易出错的分布式一致性服务封装起来,构成一个高效可用的原语集。
典型的分布式数据一致性解决方案
它公开了一组简单的API,分布式应用程序可以基于这些简单的API实现诸如发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master选举、分布式锁和分布式队列等功能
其由Java语言编译,支持Java和C两种语言的客户端
核心概念
ZooKeeper的核心思想是,提供一个非锁机制的Wait Free的用于分布式系统同步的核心服务。提供简单的文件创建、读写操作接口,其系统核心本身对文件读写并不提供加锁互斥的服务,但是提供基于版本比对的更新操作,客户端可以基于此自己实现加锁逻辑。
集群角色
经典Master/Slave模式(主备模式)
redis集群
Leader、Follower、Observer(ZooKeeper)
ZooKeeper集群
节点ZNode
ZooKeeper数据模型中的数据单元
ZooKeeper的数据模型类似与文件系统,以树形结构存储
ZNode结构包含的信息
path唯一路径
childNode:子节点
stat:状态属性
type:节点类型
节点对应的数值
节点类型
PERSISTENT 持久节点
持久化保存的节点,也是默认创建的
PERSISTENT_SEQUENTIAL 持久有序节点
创建时ZooKeeper会在路径上加上序号作为后缀
创建序号节点:create -s /path
EPHEMERAL 临时节点(不能拥有子节点)
临时节点会在客户端会话结束后自动删除,适用于心跳、服务发现等场景,创建时添加参数-e即可
创建临时节点:create -e /path
EPHEMERAL_SEQUENTIAL 临时有序节点(不能拥有子节点)
临时且有序的节点,创建时加-e -s即可
创建临时有序节点:create -e -s /path
CONTAINER 容器节点
用于Leader、lock等特殊用途,当容器节点不存在任何子节点时,容器将成为服务器在将来某个时刻删除的候选节点
PERSISTENT_WITH_TTL 带TTL(time-to-live 存活时间)的永久节点
节点在TTL时间内没有得到更新并且没有子节点,就会自动删除
PERSISTENT_SEQUENTIAL_WITH_TTL 带TTL(time-to-live 存活时间)的有序的永久节点
节点属性
查看节点属性
stat /path
属性列表
ZXID:事务ID,用来唯一标识一次服务器状态变更(增删改)
节点的监听(watch)
客户端添加-w可实时监听节点或子节点的变化,并且实时收到节点的通知,非常适用于保证分布式系统数据一致的情况下
ls -w /path 监听子节点的变化(增、删)
get -w /path 监听节点的数据变化
stat -w /path 监听节点属性的变化
printwatches on|off 触发监听事件后,是否打印监听事件,默认on
权限设置(ACL)
保障数据安全的权限控制机制
数据指的是保存的一些节点信息,比如:实现分布式锁创建的节点等
包含最大1MB的数据信息
监听与通知(Watcher)
事件监听,基于通知机制
客户端通过向ZooKeeper注册需要接收通知的ZNode,通过对ZNode设置监视点(watch)来接收通知
观察点触发后立即失效。所以一旦观察点触发,需要再次设置新的观察点
我们使用Zookeeper不能期望能够监控到节点每次的变化。思考如下场景:1、客户端C1设置观察点在/tasks2、观察点触发,C1处理自己的逻辑3、C1设置新的观察点前,C2更新了/tasks4、C1处理完逻辑,再次设置了观察点。此时C1不会得到第三步的通知,因此错过了C2更新/tasks这次操作。要想不错过这次更新,C1需要在设置监视点前读取/tasks的数据,进行对比,发现更新。
zookeeper可以定义不同的观察类型。例如观察znode数据变化,观察znode子节点变化,观察znode创建或者删除
版本
每个znode都有版本号,随着每次数据变化自增。setData和delete,以版本号作为参数,当传入的版本号和服务器上不一致时,调用失败。当多个zookeeper客户端同时对一个znode操作时,版本将会起到作用,假设c1,c2同时往一个znode写数据,c1先写完后版本从1升为2,但是c2写的时候携带版本号1,c2会写入失败。
法定人数、半数规则(集群模式)
分支主题
会话(Session)
客户端对zookeeper集群发送任何请求前,需要和zookeeper集群建立会话。客户端提交给zookeeper的所有操作均关联在一个会话上。当一个会话因某种原因终止时,会话期间创建的临时节点将会消失。而当当前服务器的问题,无法继续通信时,会话将被透明的转移到另外一台zookeeper集群的服务器上。会话提供了顺序保障。同一个会话中的请求以FIFO顺序执行。并发会话的FIFO顺序无法保证。
Leader选举
数据同步
分布式一致性特性
顺序一致性
从同一个客户端发送的事务请求,最终将会严格的按照请求顺序执行到ZooKeeper上
原子性
所有的事务请求处理结果在整个集群的所有机器上的应用应该一致的,也就是说要么集群所有的机器都成功应用了某一事务,要么都没应用,一定不会出现部分应用事务的情况出现。
单一视图
无论客户端连接的那个集群节点服务器。其看到的服务端数据模型都是一致的
可靠性
事务一旦成功应用,那么其引起的服务器状态变更会被一直保留下来,除非另一个事务又对其变更。
实时性
只能保证在一定的时间内,客户端最终一定能从服务端读取最新的数据。
ZooKeeper将全量数据存储在内存中
使用ZooKeeper
安装(Windows)
1、下载
https://zookeeper.apache.org/releases.html#download
2、解压
普通解压即可
3、创建配置文件
解压后的路径下找到conf文件夹,进入conf文件夹复制zoo_sample.cfg,命名为zoo.cfg
参数说明
# 每个tick的毫秒数。后面的initLimit和syncLimit都以tick为单位tickTime=2000#初始化同步阶段时长initLimit=10# 同步确认时长syncLimit=5# 快照存储路径,不要使用/tmp。这里使用只是为了示例dataDir=/tmp/zookeeper# 客户端端口好clientPort=2181#可连接的client的最大数#如果需要处理更多的clinet,请增加此数量#maxClientCnxns=60...
4、单机启动ZooKeeper
在ZooKeeper根目录下执行 bin/zkServer.cmd
5、通过客户端连接ZooKeeper
在ZooKeeper根目录下执行 bin/zkCli.cmd
6、集群配置和启动
1、修改zoo.cfg文件
tickTime=2000dataDir=/var/lib/zookeeperclientPort=2181initLimit=5syncLimit=2server.1=ip1:2888:3888server.2=ip2:2888:3888server.3=ip3:2888:3888
2、复制n份zookeeper到另外两台server上
4、启动每个zookeeper
客户端命令
客户端命令可以通过:help命令查看
开源客户端
zkClient
Curator-运用最广泛
集群
集群架构说明
读写分离:提高承载,为更多的客户端提供连接,并保障性能
主从自动切换:提高服务容错性,部分节点故障不会影响整个服务集群
半数以上运行机制
集群节点数强烈建议使用奇数个服务器
ZooKeeper通过判断大多数节点的存活来判断整个服务是否可用
比如3个节点,挂掉2个表示整个集群挂掉,而用偶数4个,挂掉2个也表示其并不是大部分存活,因此也会挂掉
集群部署
集群角色说明
leader 主节点,又名领导者。用于写数据(事务)通过选举产生,如果宕机将会选举新的主节点。
follower 子节点,又名追随者。用于实现数据的读取。同时也是主节点的备选节点,并拥有投票权。
observer 次级子节点,又名观察者。用于读取数据,与follower区别在于没有投票权,不能选为主节点。并且在计算集群可用状态时不会讲observer节点计算在内。
配置方法:server.3=127.0.0.1:2889:3889:observer
过半机器数
指的是集群中所有机器总和的过半,即使某些服务器宕机也要计算到总和中。
选举投票机制
服务器启动时期的Leader选举
(2)接收来自各个服务器的投票。集群中的每个服务接收到投票后,首先判断该投票的有效性,如检查是否是本轮投票、是否来自LOOKING状态的服务器。
(3)处理投票。针对每个投票,服务器都需要将别的服务器投票和自己的投票进行PK,PK规则如下
(5)改变服务器状态。一旦确定Leader,每个服务器就会更新自己的状态,如果是Follower,那么就变更为FOLLOWING,如果是Leader,就变更为LEADING
服务器运行期间的Leader选举
前提:Leader服务器宕机,集群在选举出新的Leader之前无法提供服务,而是进入新一轮的Leader选举:
(1)变更状态 当Leader挂掉后,余下的非Observer服务器都会将自己的服务器状态变更为LOOKING,然后开始进入Leader选举流程。
(2)每个Server会发出一个投票 在这个过程中,需要生成投票信息(myid,ZXID)。因为是运行时期,因此每个服务器的ZXID可能不同,我们假设Server1的ZXID为123,而Server3(Server2挂掉了)的ZXID为122。在第一轮投票中,Server1和Server3都会投自己,即分别产生投票(1,123)和(3,122),然后各自将投票信息发给集群中的所有机器。
(3)接收来自各个服务器的投票。
(4)处理投票 对于投票的处理同启动时期一致。
(5)统计投票
(6)改变服务器状态
数据同步机制
正常客户端数据提交
(1)client向zk中的server发送写请求,如果该server不是leader,则会将该请求转发给leader server,leader将请求事务以proposal形式发给follower;
(2)当follower接收到leader的proposal时,根据接收的先后顺序处理proposal;
(3)当leader收到follower针对某个proposal过半的ack后,则发起事务提交,重新发起一个commit的proposal;
(4)follower收到commit的proposal后,记录事务提交,并把数据更新到磁盘中;
(5)当写成功后,反馈给client;
集群某个节点宕机后再恢复后的数据同步
在集群运行过程中如果有一个follower节点宕机,由于宕机节点没有过半,集群仍然能正常服务。当leader收到新的客户端请求,此时无法同步给宕机的节点。造成数据不一致。为了解决这个问题,当节点重新启动时,第一件事就是找当前集群的leader,对比数据是否一致。不一致则开始同步,同步完成以后再对外提供服务。如何对比leader的数据版本?这里通过ZXID事务ID来确认。比leader小就需要同步。
ZXID是一个长度64位的数字,其中底32位是按照数字递增,任何数据的变更都会导致底32位的数字简单加1。高32位是leader周期编码,每当选举出一个新的leader时,新的leader就从本地事务日志中取出ZXID,然后解析出高32位的周期编码,进行加1操作,再将底32位的全部设置为0,这样就保证了每次新选举的leader后,保证ZXID的唯一性而且是保证递增的。
0 条评论
回复 删除
下一页