《zookeeper原理与实践》笔记

第1章 分布式架构
1.1 分布式
分布式特点:分布性、对等性、并发性、缺乏全局时钟、故障总是会发生。
分布式问题:通讯异常、网络分区(脑裂)、三态、节点故障。
 
1.2 ACID到CAP/BASE
事务:由一系列对系统中数据进行访问与更新的操作所组成的一个程序执行逻辑单元。
ACID:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。
隔离级别:读未提交、读已提交(解决脏读)、可重复读(解决脏读和不可重复读)、串行化(解决脏读,不可重复读和幻读)。
 
分布式事务:是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于分布式系统的不同节点之上。
CAP定理:一个分布式系统不能同时满足一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance),最多满足两个。
BASE理论:是对CAP中一致性和可用性权衡的结果,来源于大型互联网系统分布式实践的总结。核心思想是可以放弃强一致性,采用适当的方式使系统达到最终一致性。是基本可用(Basically Available)、软状态(Soft state)、最终一致性(Eventually consistent)的缩写。
 
 
第2章 一致性协议
2.1 2PC 二阶段提交协议
二阶段提交将一个事务处理分为投票和执行两个阶段,核心是对事务采用先尝试后提交的处理方式。目前绝大多数关系型数据库采用二阶段提交完成事务处理。
优点:原理简单,实现方便。
缺点:同步阻塞、单点问题、数据不一致(脑裂)、太过保守。
同步阻塞:是两阶段最大最严重的问题,极大影响性能,因为所有参与者都必须等待其他参与者完成,才能进行下一阶段操作。
单点问题:协调者一旦挂了,整个事务处理无法运转,另外收不到请求的参与者会一直处于锁定事务资源的状态中。
数据不一致:一部分收到Commit请求的参与者完成事务提交,而没收到的参与者无法提交,整个分布式系统出现数据不一致。
太过保守:比较脆弱,任何一个节点超时失败都会导致整个事务失败。
 
阶段一:提交事务请求
①协调者发起事务询问:协调者向所有参与者发送事务内容,询问是否可以执行事务提交操作,并等待响应。
②参与者执行事务操作:参与者执行事务操作,并将redo和undo写到事务日志。
③参与者将询问结果响应给协调者:返回Yes或No。
 
阶段二:执行事务提交
A、当全部Yes,则提交事务
①协调者发送提交请求:协调者向所有参与者发出Commit请求。
②参与者执行事务提交:参与者收到Commit请求后,正式执行事务提交操作,完成提交后释放整个事务执行期间占用的系统资源。
③参与者将事务提交结果响应给协调者:返回Ack消息。
④协调者完成事务:协调者接受到所有参与者响应的Ack消息后,完成事务。
 
B、当某一个存在No或超时,则中断事务
①协调者发送回滚请求:协调者向所有参与者发出Rollback请求。
②参与者执行事务回滚:参与者收到Rollback请求后,执行事务回滚操作,完成回滚后释放整个事务执行期间占用的系统资源。
③参与者将事务回滚结果响应给协调者:返回Ack消息。
④协调者中断事务:协调者接受到所有参与者响应的Ack消息后,完成事务中断。
 
2.2 3PC 三阶段提交协议
将二阶段提交协议的第一个阶段一分为二,增加询问阶段,形成了由CanCommit、PreCommit和DoCommit三个阶段组成的事务提交协议。
优点:当可能失败时,因为快速发现失败,降低了参与者的同步阻塞范围,是最大优点。
缺点:多出的询问阶段会增加整体阻塞耗时。
 
2.3 Paxos算法
Paxos算法引入“过半”理念,也就是少数服从多数的原则来避免同步阻塞问题;同时支持分布式节点角色之间的轮换,来避免单点问题和一致性(脑裂)问题。
拜占庭将军问题:从理论上来说,在分布式计算领域,试图在异步系统和不可靠的通道上来达到一致性状态是不可能的。因此,在一致性研究过程中,都假设信道是可靠的。
Paxos问题描述:假设有一组可以提出提案的进程集合,那么对于一个一致性算法来说需要保证以下几点:
①在这些被提出的提案中,只有一个会被选定。
②如果没有提案被提出,就不会有被选定的提案。
③当一个提案被选定后,进程可以获取被选定的提案。
 
Paxos问题难点:有三种参与角色,分别位Proposer、Acceptor、Learner。不同参与者可以消息通信,但存在以下问题:
①任何一个参与者都不稳定,随时可能失败或重启。
②消息传输过程中可能延迟、重复和丢失,但不会被篡改。
 
Chubby:Google开发的粗粒度的分布式锁服务,Paxos算法的工程实现者。其开源参考实现版本为Zookeeper。
 
 
第3章 Zookeeper与Paxos
3.1 初识Zookeeper
ZK是一个开源的分布式协调服务,也是一个分布式数据一致性的解决方案。
ZK设计目标:致力于提供一个高性能、高可用,具有严格的顺序一致性(主要是写操作的严格顺序性)的分布式协调服务。
ZK保证的分布式一致性特性:顺序一致性、原子性、单一视图、可靠性、实时性。
顺序一致性:同一个客户端发起的事务请求,最终将会严格的按照其发起顺序被应用到ZK中。
 
集群角色:Leader(读写,事务请求协调者)、Follower(读、参与Leader选举、参与写操作的“过半写成功”策略)、Observer(读)。
会话:基于客户端与服务端的TCP长连接和会话超时时间实现。
ZNode:简单数据模型是内存中的一颗目录树,树节点叫Znode。分为持久节点和临时节点两大类,节点的顺序属性是由父节点维护的一个自增数字后缀。
 
3.2 ZAB协议
ZAB是ZK实现分布式数据一致性的核心算法。ZAB两种基本模式:崩溃恢复和消息广播。
ZAB协议与Paxos算法的区别:Paxos是一种通用的分布式一致性算法,而ZAB是专门为ZK设计的支持崩溃可恢复的原子消息广播算法。
ZXID:64位全局唯一递增的事务ID,低32位保存单调递增计数器,高32位保存Leader周期epoch的编号。
进程状态:LOOKING(Leader选举阶段)、FOLLOWING(Follower角色)、LEADING(Leader角色)、OBSERVING。
 
3.3 消息广播
ZAB消息广播方式是一个简化的2PC,但去除了中断逻辑(采用过半写成功策略),并且用崩溃恢复来解决协调者(Leader)单点问题。
ZAB事务请求处理流程(类似2PC):所有事务请求必须由一个全局唯一的Leader服务器来协调处理,Leader负责将一个客户端事务请求转换成一个事务Proposal(提议),并将该Proposal分发给集群中所有的Follower服务器并等待其反馈,一旦超过半数的Follower服务器进行正确ACK反馈(投票)后,那么Leader就会再次向所有的Follower服务器分发Commit消息。要求其将前一个的Proposal进行提交。
 
3.4 崩溃恢复
启动条件:Leader崩溃、重启、与过半Follower网络中断时。
退出条件:完成Leader选举,并且新Leader上的所有Proposal已与过半机器完成数据同步,这时新Leader才能接受客户端事务请求。
Leader选举算法:拥有最高编号(ZXID最大)事务Proposal的机器会成为Leader。此算法优点是为了省去新Leader检查Proposal的提交和丢弃工作的这两步操作。
Proposal提交检查:是指ZAB协议需要确保那些已经在Leader服务器上提交的事务最终被所有服务器都提交。
Proposal丢弃检查:是指ZAB协议需要确保丢弃那些只在Leader服务器上被提出的事务。
 
3.5 ZAB与Paxos联系和区别
相同点:都是一个Leader多个Follower,提案提交都采用过半原则,并且都有Leader周期epoch。
区别:Leader选举算法不一样,Paxos的新Leader会向所有机器收集老Leader提出的提案,并将他们提交。而ZAB增加发现和同步阶段,拥有最高编号的事务提案会成为Leader。
本质区别:设计目标不一样,Paxos用于构建一个分布式的一致性状态机系统,ZAB则用于构建一个例如Zookeeper这样的高可用的分布式数据主备系统。
 
 
第4章 使用Zookeeper
4.1 部署与运行
部署模式:单机、伪集群、集群。
zkCli.sh客户端命令:create、ls、get、set、delete。
zkServer.sh服务器命令:status、start、stop、restart、help。
 
开源客户端:zkClient、Curator。
 
 
第5章 Zookeeper典型应用场景
5.1 数据发布/订阅
即配置中心,ZK采用推拉结合方式:客户端向服务器注册自己要关注的节点,一旦节点数据发生变更,服务器向客户端发送watcher事件通知(push),客户端接收到通知后,需要主动到服务器获取最新的数据(pull)。
 
5.2 命名服务
与JNDI类似,帮助应用系统通过一个资源引用的方式来实现对资源的定位和使用。可以利用目录树结构和ZNode的顺序属性来生成分布式全局唯一ID。
 
5.3 分布式协调/处理
基于ZK的watcher注册与异步通知机制,通常做法是:不同客户端都对ZK同一个数据节点进行watcher注册,监听数据节点变化。可以实现心跳检测、工作进度汇报、系统调度等。
 
5.4 集群管理
包括集群监控和集群控制两大块。可以实现机器注册、任务分发、状态汇报、动态分配、机器上下线、机器监控等。
 
5.5 Master选举
利用ZK特性实现,即ZK保证客户端无法重复创建一个已经存在的数据节点。做法是:同时多个客户端请求创建同一个节点,那么最终一定只有一个客户端能够创建成功。
 
5.6 分布式锁
排他锁
A、获取锁
①多个客户端同时在/el节点下创建同名临时子节点/el/lock,最终只有一个能创建成功,那么就获取到锁。
②获取锁失败的客户端在该/el节点注册一个子节点变更的watcher监听。
B、释放锁
拥有锁的客户端宕机、用完主动删除。
 
共享锁
A、获取锁
①多个客户端在/sl节点下创建顺序临时子节点/sl/host-读写类型[RW]-序号。
②当写操作时,对比自己序号小的节点注册节点变更watcher监听。
③当读操作时,对比自己序号小的写操作节点注册节点变更watcher监听,当比自己小的都是读操作节点时,则直接获取锁。
B、释放锁
拥有锁的客户端宕机、用完主动删除。
 
5.7 分布式队列FIFO
类似全部为写操作的共享锁模型。
A、获取锁
①多个客户端在/queue节点下创建顺序临时子节点/queue/host-序号。
②对比自己序号小的节点注册节点变更watcher监听。
 
5.8 分布式屏障
①多个客户端在/barrier节点(内容为数字N)下创建临时子节点/barrier/host。
②检查子节点数量是否小于N,满足则对/barrier节点注册一个子节点变更的watcher监听。
 
5.9 ZK在大型分布式系统的应用
Hadoop:ZK主要实现高可用HA功能。如:HDFS的namenode、YARN的resourcemanager。
HBase:HRegionServer的高可用,RootRegion自身的位置管理,Region状态管理等,Replication管理。
Kafka:Broker的注册管理、Topic节点(Topic分区信息与Broker的映射关系)的管理、生产者动态负载均衡(生产者通过对“broker的增减”,“topic的增减”,“topic与broker映射关系变化”等注册watcher监听)、消费者动态负载均衡(同上)。
Dubbo:服务注册中心。
 
 
第6章 Zookeeper技术内幕
6.1 系统模型
ZNode:命名空间树的节点,根节点为“/”,类似Unix文件系统风格。
ZK事务:能够改变ZK服务器状态的操作。包括ZNode创建删除、数据节点内容更新、客户端会话创建与失效等。
ZXID:事务ID,全局自增有序。节点stat中有czxid(创建)、mzxid(最后一次修改)、pzxid(子节点列表最后一次修改,不含子节点内容变更)三种类型。
节点类型:持久、临时、顺序。
临时节点:临时节点生命周期和客户端会话绑定,而不是TCP连接。
节点版本:表示修改次数,刚创建为0次。通过乐观锁和CAS校验机制来保证原子性操作。分为version(节点数据内容)、cversion(子节点列表)、aversion(节点ACL变更)三种类型。
 
watcher机制:包括客户端线程、客户端WatchManager和ZK服务器三部分。实现过程分为三个阶段:客户端注册watcher、服务端处理watcher和客户端回调watcher。
watcher事件:由keeperState和EventType组合实现。keeperState分为4种:SyncConnected、Disconnected、Expired、AuthFailed。而eventType分为5种:None、NodeCreated、NodeDeleted、NodeDataChanged、NodeChildrenChanged。
watcher特性:一次性、客户端串行执行、轻量级。
 
ACL:一条ACL信息的格式为scheme(权限模式):id(授权对象):permission(权限)。
scheme权限模式:分为4种,即IP、Digest(用户名:密码)、world、super。
permissionL权限:分为5种,即CREATE、READ、WRITE、DELETE、ADMIN。
 
Jute:zk的序列化组件。
 
6.2 客户端
zk客户端主要有四个核心组件:ZK实例、ClientWatcherManager、HostProvider、ClientCnxn。
zk服务端组件:NIOServerCnxn负责维护每一个客户端连接,采用TCP长连接。
 
6.3 会话
session会话的5个状态:connecting、connected、reconnecting、reconnected、close。
会话四个基本属性:sessionID、timeout、ticktime(下次会话超时时间点)、isClosing。
会话采用“分桶策略”管理,为了高效低耗的实现会话的超时检查和清理。
分桶策略:是指将类似的会话放在同一区块中管理,以便ZK对会话进行不同区块的隔离以及同一区块的统一处理。
 
会话重连:当客户端与服务器网络连接断开后,ZK客户端会自动进行反复的重连,直到最终成功连接上ZK集群中的一台机器。此时若还在会话超时时间内,则重连成功;否则会话失效过期。
会话转移:当网络连接断开后,重连到另外一台服务器,则客户端会话将从旧服务器转移到新服务器。
 
6.4 服务器启动
leader选举是单机和集群模式启动最大的不同点。默认的leader选举算法为FastLeaderElection。根据服务器SID、最新的zxid、当前的服务器epoch来生成一个投票。简单而言,哪个服务器处理过的数据越新,就越有可能成为leader。zxid相同时,sid最大的成为leader。
 
6.5 Leader选举
ZK服务器的三种角色:Leader、Follower、Observer。
Quorum:过半机器数。计算公式Quorum=(n/2+1)。
Vote:投票的基本元素包含:所推举的服务器sid,所推举服务器的zxid,如(SID,ZXID)。
 
Leader选举概述:
A、服务器启动期间的Leader选举(当首台机器启动时不会选举,此时无leader,只有当第2台启动时才会触发)
①每个服务器会发出一个投票,初始都投给自己,如(1,0)、(2,0)。
②接收来自各个服务器的投票,并校验投票有效性,如是否为本轮投票,是否来自LOOKING状态的服务器。
③将接收到的别人的N-1个投票和自己的投票PK,选出N个投票中的最大者,若最大者不是自己,则变更投票,通过将收到的最大者投票再次发出,来发起第二轮投票;若最大者是自己则没有第二轮投票。PK规则:先比较ZXID,相同则比较SID。
④统计所有投票,判断是否已经有过半的机器接收到相同的投票信息。
⑤改变服务器状态为Leading或Following。
 
B、服务器运行期间的Leader选举(非Leader机器增减不会选举,仅leader挂了才会)
①每个Follower服务器变更状态为LOOKING。
②每个服务器会发出一个投票(SID,ZXID),第一轮投票都投给自己。
③④⑤与上述相同。
 
zk服务器状态:分别为LOOKING、FOLLOWING、LEADING和OBSERVING。
 
FastLeaderElection选举算法核心概念:
外部投票:特指其他服务器发来的投票。
内部投票:服务器自身当前的投票。
选举轮次:ZK服务器Leader选举的轮次,即logicalClock。
PK:将内部投票和外部投票进行一个对比来确定是否需要变更内部投票。
sendQueue:选票发送队列。
recvQueue:选票接收队列。
recvSet:选票归档集合。无论是否发生了选票变更,都会将刚刚收到的那份外部选票放入选票集合recvSet中进行归档。完成归档后,开始统计选票。
 
6.6 请求处理
ZK中每一个事务请求都需要集群中过半机器投票认可后,才能被真正应用到ZK内存数据库中去。
事务处理相关概念:生成并广播提议Proposal、收集ACK消息反馈、广播Commit。
 
6.7 数据与存储
ZK数据存储分为内存和硬盘两部分。内存数据模型是一棵树DataTree。
ZKDatabase:ZK内存数据库,负责管理ZK所有会话,DataTree存储和事务日志。会定时向磁盘dump快照数据,同时在zk启动时,会通过磁盘上的事务日志和快照数据文件恢复成一个完整的内存数据库。
dataDir:快照数据目录。名为“snapshot.ZXID”二进制文件。
dataLogDir:事务日志目录。名为“log.ZXID”的二进制文件。
 
 
第7章 Zookeeper运维
7.1 配置详解
tickTime:配置zk中最小时间单元的长度,其他时间都是以其倍数来表示,单位毫秒。
initTime:配置Leader服务器等待Follower启动,并完成数据同步的时间。集群庞大时需要加大。
syncTime:配置Leader与Follower之间进行心跳检测的最大延时时间。
snapCount:配置两次数据快照之间事务操作次数。
 
7.2 四字命令
通过telnet客户端登录zk对外服务的2181端口,然后输入四字命令。
 
7.3 集群组成
zk集群只能部署为奇数个是错误的认识。任意台机器都能部署且能够正常运行。若要进一步满足集群可用,则需满足“过半存活即可用”的特性。
过半存活即可用:一个zk集群要对外提供一个“可用”的服务,那么集群中必须要有过半的机器正常工作并且彼此之间能够正常通信。
基于该特性,若想搭建允许F台down掉的集群,则服务器数量应该为2*F+1台。例如:6台和5台相比,都是只允许2台down掉,在容灾能力上没有任何优势,只会浪费资源,因此官方建议部署奇数个。
原文地址:https://www.cnblogs.com/fhwup/p/8587562.html