Zookeeper学习脑图
2022-07-09 16:41:33 0 举报
AI智能生成
该脑图参考“《从Paxos到Zookeeper 分布式一致性原理与实践》【倪超著】”编辑完成。
作者其他创作
大纲/内容
分布式架构
从集中式到分布式
集中式特点
由一台或多台计算机组成中心节点,这个中心节点承担数据集中存储、所有业务单元的集中部署、系统所有功能的处理。部署结构简单,无需考虑多节点部署和多节点之间的分布式协调问题。
分布式特点
分布式概念
分布式系统是一个硬件和软件组件分布在不同的网络计算机上,彼此之间仅仅通过消息传递进行通信和协调的系统。——《分布式系统概念与设计》
特点
分布性
分布式系统中的多台计算机都会在空间上随意分布,同时,机器的分布情况也会随时变动。
对等性
分布式系统中的计算机没有主从之分,既没有控制整个系统的主机,也没有被控制的从机。所有的计算机节点是对等的。
在此特点上延申的副本概念
数据副本:数据恢复
服务副本:服务容灾
并发性
分布式系统中的多个节点,可能会并发的操作一些共享的资源。
缺乏全局时钟
由于分布式系统缺乏一个全局的始终序列控制,因此,很难定义两个时间究竟谁先谁后。
故障总是会发生
任何在设计阶段考虑到的异常情况,一定会在系统实际运行中发生,并且在系统实际运行过程中还会遇到很多在设计时未能考虑到的异常故障。因此,除非需求指标允许,在系统设计时不能放过任何异常情况。
分布式环境的各种问题
通信异常
由于网络本身存在不可靠性,分布式系统中的节点在网络通信过程时刻会伴随着网络不可用的问题。从而导致最终分布式系统无法顺利完成一次网络通信。并且由于网络间通信有更高的延时,系统消息的收发过程也会受到影响,因此消息丢失和消息延迟会变得非常普遍。
网络分区
俗称“脑裂”。即在网络异常的情况下,分布式系统中部分节点的网络延迟不断增大,导致只有另外部分节点能够进行正常通信。这些正常节点形成的局部小集群,承担起了原本需要整个分布式系统才能完成的功能。
三态
成功、失败、超时。
节点故障
从ACID到CAP/BASE
事务
定义
事务是一系列对系统中数据进行访问与更新的操作所组成的一个程序执行逻辑单元,狭义的事务特指数据库事务。
思想
当多个应用程序并发访问数据库时,事务可以在这些应用程序之间提供一个隔离方法,以防止彼此的操作互相干扰。
事务为数据库操作序列提供了一个从失败中恢复正常状态的方法。
事务为数据库提供了在异常状态下仍能保持数据一致性的方法。
特征
原子性(Atomicity)
事务必须是一个原子的操作序列单元,其中包含的各项操作在一次执行过程中,要么全部执行,要么全部不执行。并且任何一项操作失败都将导致整个事务的失败,同时其他已经被执行的操作都将被撤销并回滚。
一致性(Consistency)
事务的执行不能破坏数据库数据的完整性和一致性,即:一个事务在执行前后,数据库都必须处于一致性状态。
隔离性(Isolation)
概念
在并发环境中,并发的事务是互相隔离的,一个事务的执行不能被其他事务干扰。即:不同的事务并发操纵相同的数据时,每个事务都有各自完整的数据空间,一个事务内部的操作及使用的数据对其他并发事务是隔离的,并发执行的事务之间不能相互干扰。
隔离级别
读未提交(Read Uncommitted)
脏读、幻读
读已提交(Read Committed)
幻读
可重复读(Repeatable Read)
幻读
串行化(Serializable)
持久性(Durability)
ACID
分布式事务
概念
事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于分布式系统的不同节点上。通常一个分布式事务中会涉及对多个数据源或业务系统的操作。
CAP和BASE理论
CAP
一致性(Consistency)
数据在多个副本之间是否能够保持一致的特性。当一个系统在数据一致的状态下执行更新操作后,应该保证系统的数据仍然处于一致的状态。
可用性(Availability)
系统提供的服务必须一直处于可用的状态,对于用户的每一个操作请求总是能够在有限的时间内返回结果。
分区容错性(Partition tolerance)
分布式系统在遇到任何网络分区故障的时候,仍然需要能够保证对外提供满足一致性和可用性的服务,除非是整个网络环境都发生了故障。
定理应用
放弃P
将所有数据都放在一个分布式节点上,同时也就意味着放弃了系统的可扩展性。
放弃A
一旦系统遇到网络分区或其他故障时,那么收到影响的服务需要等待一定的时间,因此在等待期间系统无法对外提供正常的服务,即不可用。
放弃C
并非完全不需要数据一致性。即放弃数据的强一致性,保留数据的最终一致性。
BASE
基本可用(Basically Available)
分布式系统在出现不可预知故障的时候,允许损失部分可用性。
响应时间上的损失
功能上的损失
软状态(Soft State)
也称为“弱状态”。允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性。即允许系统在不同节点的数据副本之间进行数据同步的过程存在延时。
最终一致性(Eventually Consistent)
概念
系统中所有的数据副本,在经过一段时间的同步之后,最终能够达到一个一致的状态。
实践中的变种
因果一致性(Causal Consistency)
读己之所写(Read Your Writes)
会话一致性(Session Consistency)
单调读一致性(Monotonic Read Consistency)
一个进程从系统中读取一个数据项的某个值后,那么系统对于该进程后续的任何数据访问都不应该返回更旧的值。
单调写一致性(Monotonic Write Consistency)
一个系统需要更够保证来自同一个进程的写操作被顺序的执行。
一致性协议
基础思想
当一个事务操作需要跨越多个分布式节点的时候,为了保持事务处理的ACID特性,需要引入“协调者”和“参与者”两个角色。协调者负责调度参与者的行为,并最终决定这些参与者是否要把事务真正进行提交。
协调者
用来统一调度所有分布式节点的执行逻辑。
参与者
被“协调者”调度的分布式节点称为“参与者”。
2PC与3PC
二阶段提交(2PC)
概念
是计算机网络尤其是在数据库内,为了使基于分布式系统架构下的所有节点在进行事务梳理过程中能够保持原子性的一致性而涉及的一种算法。也被认为是一种一致性协议,用来保证分布式系统数据的一致性。
特点
能够非常方便的完成所有分布式事务参与者的协调,统一决定事务的提交或回滚。被广泛应用。
说明
阶段一:提交事务请求
事务询问
协调者向所有参与者发送事务内容,询问是否可以执行事务操作,并开始等待各参与者的响应。
执行事务
各参与者节点执行事务操作,并将Undo和Redo信息记入事务日志中。
各参与者向协调者返回事务询问的响应
Yes响应
参与者成功执行了事务操作,反馈给协调者Yes响应,表示事务可以执行。
No响应
参与者没有成功执行事务,反馈给协调者No响应,表示事务不可以执行。
阶段二:执行事务提交
Yes响应:执行事务提交
发送提交请求
协调者向所有参与者节点发送Commit请求。
事务提交
参与者接收到Commit请求之后,会正式执行事务提交工作,并在完成提交之后释放整个事务执行期间占用的事务资源。
反馈事务提交结果
参与者在完成事务提交之后,向协调者发送Ack消息。
完成事务
协调者接收到所有参与者反馈的Ack消息后,完成事务。
No响应:中断事务
发送回滚请求
协调者向所有参与者节点发送Rollback请求。
事务回滚
参与者接收到Rollback请求之后,会利用其在阶段一中记录的Undo信息来执行事务回滚操作,并在完成回滚之后释放整个事务执行期间占用的事务资源。
反馈事务回滚结果
参与者在完成事务回滚之后,向协调者发送Ack消息。
中断事务
协调者接收到所有参与者反馈的Ack消息后,完成事务中断。
优缺点
优点
原理简单,易于实现。
缺点
同步阻塞
在提交执行的过程中,所有参与该事务的逻辑都处于阻塞状态,即各个参与者在等待其他参与者响应的过程中,将无法进行其他任何操作。这会极大地限制分布式系统的性能。
单点问题
一旦协调者出现问题,那么整个二阶段提交流程将无法运转。并且,如果协调者是在阶段二中出现问题,那么其他参与者将会一直处于锁定事务资源的状态中,而无法继续完成事务操作。
脑裂
在阶段二中,如果部分协调者或参与者由于网络或自身问题,导致事务服务最终提交,那么整个分布式系统便会出现数据不一致的情况。
保守
二阶段提交没有设计较为完善的容错机制,任意一个节点的失败都会导致整个事务的失败。
总结
二阶段提交将一个事务的处理过程分为了投票和执行两个阶段,其核心是对每个事务都采用先尝试后提交的处理方式,因此也可以将二阶段提交看作一个强一致性的算法。
三阶段提交(3PC)
概念
即三阶段提交,是二阶段提交的进阶版,将二阶段提交的“提交事务请求”过程一分为二,形成了由Can Commit, Pre Commit, Do Commit三个阶段组成的事务处理协议。
说明
阶段一:Can Commit
事务询问
各参与者向协调者反馈事务询问的响应
阶段二:Pre Commit
阶段一中各参与者全部反馈Yes响应
执行事务预提交
发送预提交请求
协调者向所有参与者节点发送preCommit请求。并进入Prepared阶段。
事务预提交
各参与者节点在接收到preCommit请求后,执行事务操作,并将Undo和Redo信息记入事务日志中。
各参与者向协调者反馈事务执行的响应
如果参与者成功完成了事务操作,就向协调者发送Ack消息。同时等待最终的命令:提交(commit)或终止(abort)。
阶段一中任何一个参与者反馈No响应
中断事务
发送中断请求
协调者向所有参与者节点发送abort请求。
中断事务
无论是收到来自协调者的abort请求,或者是在等待协调者请求过程中出现了超时,参与者都会终端事务。
阶段三:Do Commit
执行提交
发送提交请求
进入这一阶段,假设协调者处于正常工作状态,并且它及收到了来自所有参与者的Ack响应,那么它将从“预提交”状态转换到“提交”状态,并向所有参与者发送doCommit请求。
事务提交
参与者接收到doCommit请求之后,会正式执行事务提交工作,并在完成提交之后释放整个事务执行期间占用的事务资源。
反馈事务提交结果
参与者在完成事务提交之后,向协调者发送Ack消息。
完成事务
协调者接收到所有参与者反馈的Ack消息后,完成事务。
中断事务
发送回滚请求
协调者向所有参与者节点发送abort请求。
事务回滚
参与者接收到abort请求之后,会利用其在阶段二中记录的Undo信息来执行事务回滚操作,并在完成回滚之后释放整个事务执行期间占用的事务资源。
反馈事务回滚结果
参与者在完成事务回滚之后,向协调者发送Ack消息。
中断事务
协调者接收到所有参与者反馈的Ack消息后,中断事务。
优缺点
优点
相较于二阶段提交协议,三阶段提交协议降低了参与者的阻塞范围,并且能够在出现单点故障后继续达成一致。
缺点
参与者在接收到preCommit消息后,如果出现网络分区,该参与者依然会进行事务的提交,这必然会出现数据的不一致性。
Paxos算法
追本溯源
概念
是一种基于消息传递且具有高度容错性的一致性算法。
解决的问题
在一个可能出现网络分区的分布式系统中,快速且正确地在集群内部对某个数据的值达成一致,并且保证不论发生任何异常,都不会破坏整个系统的一致性。
Paxos理论的诞生
“拜占庭问题”,“Paxos小岛议会问题”,Leslie Lamport,Butler Lampson
Paxos算法详解(详见书籍)
目标
要保证最终有一个提按会被选定,当提案被选定后,进程最终也能获取到被选定的提案。
相关角色
Proposer\Acceptor\Leaner
推导过程
P1:一个Acceptor必须批准它收到的第一个提案
P2:如果编号为M0、Value值为V0的提案,即[M0,V0]被选定了,那么所有比编号M0更高的,且被选定的提案,其Value必须也是V0。
保证了只有一个value被选定
P2a:如果编号为M0、Value值为V0的提案,即[M0,V0]被选定了,那么所有比编号M0更高的,且被Acceptor批准的提案,其Value必须也是V0。
P2b:如果一个提案[M0,V0]被选定后,那么之后任何Proposer产生的编号更高的提案,其Value值都是V0.
数学归纳法证明
特点
引入了“过半”理念,同时支持分布式节点角色之间的转换,极大的避免了分布式单点的出现,因此Paxos既解决了无限期等待问题,也解决了“脑裂”问题。
Paxos的工程实践
Chubby
概述
是一个面向松耦合分布式系统的锁服务,通常用于为一个由大量小型计算机构成的松耦合分布式系统提供高可用的分布式锁服务。
实现
提供了粗粒度的分布式锁服务,开发人员不需要使用复杂的同步协议,而是直接调用Chubby的所服务接口即可实现分布式系统中多个进程之间粗粒度的同步控制,从而保证分布式数据的一致性。
应用场景
集群中服务器的Master选举
设计目标
锁服务优点
对上层应用程序的入侵性更小
便于提供数据的发布与订阅
开发人员基于锁的接口更为熟悉
更便捷地构建更可靠的服务
引入Quorum机制,即“过半机制”
设计目标
提供一个完整的、独立的分布式服务、而非仅仅是一个一致性协议的客户端库
提供粗粒度的锁服务
应用场景是客户端获得锁之后会进行长时间持有(数小时或数天),而非用于短暂获取所得场景。所以当锁服务暂时失效时,Chubby需要保持所有锁的持有状态,以避免持有锁的客户端出现问题。
在提供所服务的同时提供对小文件的读写功能
提供对小文件的读写服务,以使得被选举出来的Master可以在不依赖额外服务的情况下,非常方便的向所有客户端发布自己的状态信息。
高可用、高可靠
提供事件通知机制
Chubby技术架构
系统结构
客户端
服务端
目录与文件
结构上类似Unix系统
节点(命名空间,包括文件和目录)
节点类型
临时节点
会在其对那个的客户端会话失效后被自动删除,生命周期与客户端会话绑定。
持久节点
显式调用API接口删除
节点结构
实例编号
用于标识Chubby创建该数据节点的顺序
文件内容编号(只针对文件)
用于标识文件内容的变化情况
锁编号
用于标识节点锁状态变更情况,该编号会在节点锁从free状态转换到被持有状态时增加。
ACL编号
标识节点的ACL信息变更情况
锁与锁序列器
锁延迟
锁序列器
事件通知机制
文件内容变更
节点删除
子节点新增、删除
Master服务器转移
缓存
在客户端对文件内容和元数据信息进行缓存,并通过租期机制来保证缓存一致性(强一致性)。
会话与会话激活
在正常运行过程中,每一个Chubby客户端总是会有一个KeepAlive请求阻塞在Matser服务器上。
会话超时
客户端“危险状态”、“宽限期”、jeopardy/safe/expired事件通知机制
Paxos协议实现
Chubby基本架构分层
最底层:容错日志系统(Fault-Tolerant Log)
中间层:Key-Value类型的容错数据库(Fault-Tolerant DB)
最上层:Chubby对外提供的分布式锁服务和小文件存储服务
Hypertable
概述
使用C++实现的开源、高性能、可伸缩的数据库。Hypertable只支持最基本的增、删、改、查功能,对于事务处理和关联查询等关系型数据库的高级特性尚未支持。并且在数据量少的情境下,性能还不如传统的关系型数据库。
优点
支持对大量并发请求的处理。
支持对海量数据的管理。
扩展性好,在保证可用性的前提下,能够通过随意添加集群中的机器来实现水平扩容。
可用性极高,具有非常好的容错性,任何节点的失效,既不会造成系统的瘫痪,也不会影响数据的完整性。
核心组件
Hyperspace
提供了对分布式锁服务的支持以及对元数据的管理,是保证Hypertable数据一致性的核心。
RangerServer
对外提供服务的组件单元,负责数据的读取和写入。
Master
元数据管理中心,管理包括创建表、删除表或是其他表空间变更在内的所有元数据操作,同时负责检测RangServer的工作状态。一旦某一个RangeServer宕机或是重启,能够自动进行Range的重新分配,从未实现对RangeServer集群的管理和负载均衡。
DFS Broker
是底层分布式文件系统的抽象层,用于衔接上层Hypertable和底层文件存储。
文件系统包括HDFS\MapR\Ceph\KFS,针对任何其他的文件系统,只需要实现一个对应的DFS Broker,就可以将其快速接入到整个Hypertable系统中。
算法实现
Active Server
Active Server\Standby Server\Master选举,任意时刻只有Active Server能够对外提供服务。
事务请求处理
BDB、Master选举
Active HyperSpace 选举
所有服务器上事务日志的更新时间越新,被选举为Active Hyperspace的可能性就越大。
Zookeeper与Paxos
初识Zookeeper
Zookeeper介绍
概念
为分布式应用提供了高效且可靠的分布式协调服务,提供了诸如统一命名服务、配置管理、分布式锁等基础服务。在解决分布式数据一致性方面,Zookeeper并没有直接采用Paxos算法,而是采用了ZAB(Zookeeper Atomic Broadcast)一致性协议。
分布式系统可以基于它实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知,集群管理、Master选举、分布式锁和分布式队列等功能。
将复杂且容易出错的分布式一致性服务封装起来,构成一个高效可靠的原语集,并以一系列简单易用的接口提供给用户使用。
一致性特性
顺序一致性
同一个客户端发起的事务请求,会被严格的按照其发起顺序被应用到Zookeeper中去。
原子性
所有事务请求的处理结果在整个集群中所有机器的应用情况都是一致的。
单一视图
客户端连接的任意Zookeeper服务器,其看到的服务端数据模型都是一致的。
可靠性
一旦服务端成功的应用了一个事务,并完成对客户端的响应,那么该事务所引起的服务端状态便泵将会被一直保存下来,除非有另一个事务又对其进行了变更。
实时性
Zookeeper仅仅保证在一定的时间段内,客户端最终一定能够从服务端上读取到最新的数据状态。
设计目的:高性能、高可用、严格的顺序访问控制能力
简单的数据模型
数据模型有一系列的Znode数据节点组成,类似于文件系统。并且将全量数据存储在内存中,以此来实现提高服务器吞吐,减少延迟的目的。
可以构建集群
顺序访问
对于来自客户端的更新请求,Zookeeper都会分配一个全局唯一的递增编号,这个编号反应了所有事务操作的先后顺序,应用程序可以使用Zookeeper的这个特性来实现更高层次的同步原语。
高性能
100%读请求场景下压测结果是12~13W的QPS
Zookeeper从何而来
yahoo
Zookeeper基本概念
集群角色
Leader
Zookeeper集群中的所有机器可以通过一个Leader选举过程来选定一台被称为”Leader“的机器,Leader服务器为客户端提供读和写服务。
Follower
提供读服务,参与Leader选举。
Observer
提供读服务,不参与Leader选举。可以在不影响写性能的情况下提升集群的读性能。
会话
数据节点(Znode)
版本
对于每一个ZNode,Zookeeper都会为其维护一个叫做Stat的数据结构,Stat中记录了这个ZNode的三个数据版本
version(当前ZNode的版本)
cversion(当前ZNode子节点的版本)
aversion(当前ZNode的ACL版本)
Watcher(事件监听器)
Zookeeper允许用户在指定节点上注册一些Watcher,并且在一些特定事件触发的时候,Zookeeper服务端会将事件通知到感兴趣的客户端上去,该机制是Zookeeper实现分布式协调服务的重要特性。
ACL
Zookeeper采用ACL(Access Control Lists)策略来进行权限控制。
CREATE
创建子节点的权限
READ
获取节点数据和子节点列表的权限
WRITE
更新节点数据的权限
DELETE
删除子节点的权限
ADMIN
设置节点ACL的权限
Zookeeper的ZAB协议
ZAB协议(概念)
Zookeeper专门设计的一种支持崩溃恢复的原子广播协议。基于该协议,Zookeeper实现了一种主备模式的系统架构来保持集群中各副本之间数据的一致性。
核心是定义了那些会改变Zookeeper服务器数据状态的事务请求的处理方式
所有事务请求必须由一个全局唯一的服务器来协调处理,这样的服务器被称为Leader服务器,而余下的其他服务器则成为Follower服务器。Leader服务器负责将一个客户端事务请求转换成一个事务Proposal(提议),并将该Proposal分发给集群中所有的Follower服务器。之后Leader服务器需要等待所有Follower服务器的反馈,一旦超过半数的Follower服务器进行了正确的反馈后,那么Leader就会再次向所有的Follower服务器分发commit消息,要求其将前一个Proposal进行提交。
协议介绍
两种基本模式
崩溃恢复模式
当整个服务框架在启动过程中,或是当Leader服务器出现网络中断、崩溃推出与重启异常情况时,ZAB协议就会进入恢复模式并选举产生新的Leader服务器。当选举产生了新的Leader服务器,同时集群中已经有过半的机器与改Leader服务器完成了状态同步之后,ZAB协议就会退出恢复模式。
消息广播模式
当集群中已经有过半的Follower服务器完成了和Leader服务器的状态同步,那么整个服务框架就进入消息广播模式。
消息广播
消息广播过程使用的是一个原子广播协议,类似于一个二阶段提交过程。此时的二阶段提交协议移除了中断逻辑,所有的Follower服务器要么正常反馈Leader提出的事务Proposal,要么就抛弃Leader服务器。
崩溃恢复
ZAB协议需要一个高效且可靠的Leader选举算法,从而确保能够快速的选举出新的Leader。同时,Leader选举算法不仅仅需要让Leader自己知道其自身已经被选举为Leader,同时还需要让集权中的所有其他机器也能够快速的感知的选举产生的新的Leader服务器。
数据一致性隐患
Leader服务器崩溃
网络原因导致Leader服务器失去了过半Follower的联系
ZAB协议在崩溃恢复过程中需要保证的基本特性
ZAB协议需要确保那些已经在Leader服务器上提交的事务最终被所有服务器都提交。
ZAB协议需要确保丢弃那些只在Leader服务器上被提出的事务。
崩溃恢复后的数据同步
Leader服务器为每一个Follower服务器准备一个队列,并将那些没有被各Follower服务器同步的事务以Proposal消息的形式逐个发送给Follower服务器。
在每一个Proposal消息后面紧接着再发送一个Commit消息,以表示该事务已经被提交。
等到Follower服务器将所有其尚未同步的事务Proposal都从Leader服务器上同步过来并成功应用到本地数据库中后。
Leader服务器将该Follower服务器加入到真正的可用Follower列表中,并开始之后的其他流程。
ZAB对需要被丢弃的Proposal的处理方式
ZXID结构
低32位
一个简单的单调递增计数器,针对客户端的每一个事务请求,Leader服务器会在产生一个新的事务Proposal时,对该计数器进行加1操作。
高32位
代表Leader周期epoch编号,每当选举出一个新的Leader服务器,就会从这个Leader服务器上取出其本地日志中最大事务Proposal的ZXID,并从该ZXID中解析出对应的epoch值,然后再对其进行加1操作,之后会以此编号作为新的epoch,并将低32位置0来开始成成新的ZXID。
原理
当另外一台服务器被选举为新的Leader之后,当前集群中一定包含一个Quorum集合,该集合中的机器一定包含了更高epoch的事务Proposal,因此这台机器的事务Proposal肯定不是最高,也就无法称为Leader了。当这台机器以Follower加入到集群并连接上Leader之后,Leader会根据自己服务器上最后被提交的Proposal来和Follower服务器的Proposal进行对比,对比的结果时Leader会要求Follower进行一个回退操作——回退到一个确实已经被集群中过半机器提交的最新的事务Proposal。
深入ZAB协议
系统模型
数学模型
Π={p1,p2,...,p3};Π:进程组,P:进程。Q:进程子集。
存在这样的一个进程自己Q,其必定是进程组Π的子集;同时存在任意两个进程子集Q1和Q2,其交集必定非空。
网络通信信道
Pi、Pj表示进程组Π的两个不同进程,Cij表示Pi和Pj之间的网络通信信道
基本特性
完整性(Integrity)
进程Pj如果收到了来自Pi的消息m,那么Pi一定确实发送了消息m。
前置性(Prefix)
如果进程Pj收到了消息m,那么存在这样的消息m':如果消息m'是消息m的前置消息,那么Pj务必先接收到消息m',然后再接收到消息m。
问题描述
高吞吐低延迟
能够很好的在高并发情况下完成分布式数据的一致性处理
能够优雅的处理运行时故障
具备快速的从故障中恢复过来的能力
主进程周期
事务
算法描述
可以将消息广播和崩溃恢复两个过程细分为三个阶段
发现(Discovery)
同步(Synchronization)
广播(Broadcast)
运行分析
ZAB协议的设计中,每一个进程都有三种状态
LOOKING:Leader选举阶段
FOLLOWING:Follower服务器和Leader保持同步状态
LEADING:Leader服务器作为主进程领导状态
ZAB和Paxos算法的联系与区别
联系
两者都存在一个类似于Leader进程的角色,由其负责协调多个Follower进程的运行
Leader进程都会等待超过半数的Follower做出正确的反馈后,才会将一个提案进行提交
在ZAB协议中,每个Proposal中都包含了一个epoch值,用来代表当前的Leader周期,在Paxos算法中,同样存在这样的一个标识,只是名字变成了Ballot
区别
Paxos Leader
读阶段、写阶段、广播
ZAB Leader
发现、同步、广播
同步阶段的引入,能有效的保证Leader在新的周期中提出事务Proposal之前,所有的进程都已经完成了对之前所有事务Proposal的提交。
使用Zookeeper(详见书本)
部署与运行
系统环境
集群与单机
集群模式
伪集群模式
单机模式
运行服务
客户端脚本
创建
读取
更新
删除
Java客户端API使用
创建会话
创建节点
删除节点
读取数据
更新数据
监测节点是否存在
权限控制
客户端开源
ZkClient
Curator
小结
Zookeeper的典型应用场景
典型应用场景及实现
数据发布/订阅
概念
即配置中心,发布者降数据发布到Zookeeper的一个或一系列节点上,供订阅者进行数据订阅,进而打到动态获取数据的目的,实现配置信息的集中式管理和数据的动态更新。
设计模式
推(Push)
服务端主动将数据更新发送给所有订阅的客户端
拉(Pull)
客户端主动发起请求来获取最新数据,定时轮询拉取。
全局配置信息具备的特性
数据量比较小
数据内容在运行时会发生动态变化
集群中各机器共享,配置一致
全局配置信息的存储
小集群
存储在本地配置文件或是内存变量中
大集群
分布式化存储
配置存储
在Zookeeper上选取一个数据节点用于配置的存储
配置获取
集群中每台机器在启动初始化阶段,首先会从Zookeeper配置节点上读取数据库信息,同时,客户端还需要在该配置节点上注册一个数据变更的Watcher监听,一旦发生数据节点变更,所有订阅的客户端都能够获取到数据变更通知。
配置变更
当Zookeeper配置节点上的数据发生变更时,Zookeeper就能够将数据变更的通知发送到各个客户端,每个客户端在接收到这个变更通知后,就可以重新进行最新数据的获取。
负载均衡
硬件负载
软件负载
一种动态的DNS服务
域名配置
与配置管理相同,在Zookeeper上创建一个节点来进行域名配置。
域名解析
在DDNS中,域名的解析过程是由每一个应用自己负责。
应用会首先从域名节点中获取一份IP地址和端口的配置,进行自行解析。同时还会再域名节点上注册一个数据变更Watcher监听,以便及时收到域名变更的通知。
域名变更
同配置变更
DDNS系统架构体系主要角色
Register集群
负责集群域名的动态注册
Dispatcher集群
负责域名解析
Sacnner集群
负责监测以及维护服务状态(探测服务的可用性、屏蔽异常服务节点等)
SDK
提供各种语言的系统接入协议,提供服务注册以及查询接口
Monitor
负责收集服务信息以及对DDNS自身状态的监控
Controller
是一个后台管理的Console,负责授权管理、流量控制、静态配置服务和手动屏蔽服务等功能,另外,系统的运维人员也可以在上面管理Register、Dispatcher和Sacnner等集群。
自动化的DNS服务-运行方式
域名注册
每个服务提供者在启动的过程中,会把自己的域名信息注册到Register集群中去。
服务提供者通过SDK提供的API接口,将域名、IP地址和端口发送给Register集群。
Register获取到域名、IP地址和端口配置后,根据域名将信息写入相对应的Zookeeper域名节点中。
域名解析
服务消费者在使用域名的时候,会向Dispatcher发出域名解析请求。
Dispatcher收到请求后,会从Zookeeper上指定的域名节点读取响应的IP:PROT列表,通过一定的策略选取其中一个返回给前端应用。
域名探测
检测方式
服务端主动发起健康度心跳检测
需要在服务端和客户端之间建立起一个TCP长链接
客户端主动向服务端发起健康度心跳检测
DDNS架构使用的域名探测方式。
服务者主动向Scanner进行状态汇报,即每个服务提供者都会定时向Scanner汇报自己的状态。心跳间隔为5秒。
命名服务
概念
命名服务是分布式系统最基本的公共服务之一。在分布式系统中,被命名的实体通常可以是集群中的机器、提供的服务地址或远程对象等——都可以通称为他们的”名字“。其中较为常见的就是一些分布式服务框架中的服务地址列表,通过使用命名服务,客户端应用能够根据指定名字来获取资源的实体、服务地址和提供者的信息。
实践
JNDI命名服务
开发人员在使用JNDI时,可以完全不需要关心与数据库相关的任何信息,包括数据库类型、JDBC驱动类型、数据库账户
Zookeeper命名服务,与JNDI类似
分布式全局ID的生成
所有客户端都会根据自己的任务类型,在指定类型的任务下面通过create()接口来创建一个顺序节点。
节点创建完毕后,create()接口会返回一个完整的节点名。
客户端拿到这个返回值后,拼接上type类型。
分布式协调/通知
实现
不同的客户端都对Zookeeper上同一个数据节点进行Watcher注册,监听数据节点的变化,如果数据节点发生变化,那么所有订阅的客户端都能够接收到响应的Watcher通知,并做出相应的处理。
实践
MySQL数据复制总线:Mysql_Replicator
概念
是一个数据实时复制框架,用于在不同的MySQL数据库实例之间进行异步数据复制和数据变化通知
整体组成结构
MySQL数据库集群
消息队列系统
任务管理监控平台
Zookeeper集群
Core
Server
Monitor
具体实现
任务注册
Core进程在启动时,首先会向/mysql_replicator/tasks节点注册任务,如果在注册过程中发现该子节点已经存在,说明已经有其他Task机器注册了该任务,因此自己不需要再创建该节点了。
任务热备份
为了应对复制任务故障或者复制任务所在主机故障,复制组件采用”热备份“的容灾方式,即将同一个复制任务部署在不同的主机上,我们称这样的机器为”任务机器“,主、备任务机器通过Zookeeper互相检测运行健康状况。
热备切换
记录执行状态
控制台协调
冷备切换
冷热备份对比
一种通用的分布式系统机器间通信方式
心跳检测
基于Zookeeper临时节点特性,可以让不同的机器都在Zookeeper的一个指定节点下创建临时子节点,不同的机器之间可以根据这个临时节点来判断对应的客户端机器是否存活。
特点
检测系统和被检测系统之间不需要直接相关联,而是通过Zookeeper上的某个节点进行关联,从而降低系统耦合性,
工作进度汇报
场景
在常见的任务分发系统中,通常任务被分发到不同的机器上执行后,需要实时的将自己的任务执行进度汇报给分发系统。
Zookeeper实现
在Zookeeper上选择一个节点,每个任务客户端都在这个节点下面创建临时子节点
通过判断临时节点是否存在来确定任务机器是否存活。
各个任务机器会实时的将自己的任务执行进度写到这个临时节点上,以便中心系统能够哦实时的获取到任务的执行进度。
系统调度
控制台与客户端
控制台负责将一些指令信息发送给所有的客户端,以控制他们进行相应的业务逻辑。
集群管理
核心
集群监控
侧重对集群运行时状态的收集
集群控制
侧重对集群进行操作与控制
常见场景
希望知道当前集群中究竟有多少机器在工作
对集群中每台机器的运行时状态进行数据收集
对集群中机器进行上下线操作
实现方式
传统的Agent
具体实现
在集群中每台客户端机器上部署一个Agent,由这个Agent负责主动向指定的监控中心系统汇报自己所在机器的状态。
大规模集群应用中的弊端
大规模升级困难
统一的Agent无法满足多样的需求
编程语言多样性
Zookeeper
特性
客户端如果对Zookeeper的一个数据节点注册Watcher监听,那么该数据节点的内容或是其子节点列表发生变更时,Zookeeper服务器就会向订阅的客户端发送变更通知。
对在Zookeeper上创建的临时节点,一旦客户端与服务器之间的会话失效,那么该临时节点也就被自动清除。
实践
分布式日志收集系统
核心工作
收集分布在不同机器上的系统日志
架构设计
整个日志系统会把所有需要收集的日志机器(日志源机器)分为多个组别,每个组别对应一个收集器,其实就是一个后台机器(收集器机器),用于收集日志
解决的问题
变化中的日志源机器
变化中的收集器机器
应用的实现
注册收集器机器
在Zookeeper上创建一个节点作为收集器的根节点,每个收集器机器在启动的时候,都会在收集器节点下创建自己的节点。
任务分发
待所有收集器机器都创建好自己对应的节点后,系统根据收集器节点下子节点的个数,将所有日志源机器分成对应的若干组,然后将分组后的机器列表分别写到这些收集器机器创建的子节点上去。
状态汇报
每个收集器机器在创建完自己的专属节点后,还需要在对应的子节点上创建一个状态子节点,每个收集器都需要定期向该节点写入自己的状态信息。日志系统根据该状态子节点的最后更新时间来判断对应的收集器机器是否存活。
动态分配
全局动态分配
局部动态分配
注意事项
节点类型
使用持久节点来标识每一个收集器机器,同时在这个持久节点下面分别创建状态节点来表征每一个收集器机器的状态。
日志系统节点监听
应考虑放弃监听设置,而是采用日志系统主动轮询收集器节点的策略。以节省网卡流量,缺点是有一定的延时。
在线云主机管理
应用场景
虚拟主机提供商对集群机器的监控。
解决的问题
如何快速的统计出当前生产环境一共有多少台机器
如何快速的获取到机器上/下线的情况
如何实时监控集群中每台主机的运行时状态
应用的实现
机器上/下线
机器监控
Master选举
分布式锁
排他锁(写锁、独占锁)
定义锁
通过Zookeeper上的数据节点来表示一个锁,例如/exclusive_lock/lock节点就可以被定义为一个锁
获取锁
所有客户端会试图通过调用create()接口创建临时节点,创建成功代表成功获取锁。创建失败的客户端则会在节点上注册一个子节点变更的Watcher监听,以便实时监听到lock节点的变更情况。
释放锁
当前获取锁的客户端机器发生宕机,那么Zookeeper上的这个临时节点就会被移除
正常执行完业务逻辑后,客户端就会主动将自己创建的临时节点删除
共享做(读锁)
与排他锁的区别
加上排他锁后,数据对象只对一个事务可见,而加上共享锁后,数据对所有事务可见。
定义锁
通过Zookeeper上的数据节点来表示一个锁,是一个类似于”/shared_lock/[Hostname]-请求类型-序号“的临时顺序节点,例如/shared_lock/192.168.0.1-R-000000000001
获取锁
所有客户端都会到/shared_lock这个节点下面创建一个临时顺序节点,如果当前是读请求,那么就创建例如/shared_lock/192.168.0.1-R-000000000001的节点;如果是写请求,那么就创建例如/shared_lock/192.168.0.1-W-000000000001的节点。
判断读写顺序
创建完节点后,获取/shared_lock节点下的所有子节点,并对该节点注册子节点变更的Watcher监听。
确定自己的节点序号在所有子节点中的顺序
读请求
如果没有比自己序号小的子节点,或者是所有比自己序号小的子节点都是读请求,那么表明自己已经成功获取到了共享做,同时开始执行读取逻辑。
如果比自己序号小的子节点中有写请求,那么就需要进入等待。
写请求
如果自己不是序号最小的子节点,那么就需要进入等待
接收到Watcher通知后,重复步骤
释放锁
同排他锁的释放。
羊群效应
概念
如果同一时间有多个和节点对应的客户端完成事务或是事务中断引起节点消失,Zookeeper服务器就会在短时间内向其余客户端发送大量的事件通知。
改进
客户端调用create()方法创建一个类似于”/shared_lock/[Hostname]-请求类型-序号“的临时顺序节点
客户端调用gerChildren()接口来获取所有已经创建的子节点列表,注意,这里不注册任何watcher。
如果无法获取共享锁,那么就调用exist()来对比自己小的哪个节点注册Watcher。
读请求
向比自己序号小的最后一个写请求节点注册Watcher监听。
写请求
相比自己序号小的最后一个节点注册Watcher监听。
等待Watcher通知,继续进入步骤
分布式队列
FIFO:先进先出
设计思路
所有客户端都会到”/queue_fifo“这个节点下面创建一个临时顺序节点。
执行顺序
调用getChildren()接口来获取/queue_fifo节点下的所有子节点,即获取队列中所有的元素
确定自己的节点序号在所有子节点中的顺序
如果自己不是序号最小的子节点,那么就需要进去等待,同时向比自己序号小的最后一个节点注册Watcher监听。
接收到Watcher通知后,重复步骤
Barrier:分布式屏障
概念
在分布式系统中,”屏障“特指系统之间的一个协调条件,规定了一个队列的元素必须都聚集后才能统一进行安排,否则一直等待。
应用场景
最终的合并运算需要基于很多并行极端的子结果来进行。
设计思路
开始时,/queue_barrier节点是一个已经存在的默认节点,并且将其节点的数据内容赋值为一个数字n来代表Barrier值,表示只有当/queue_barrier节点下的子节点数量达到10后,才会打开Barrier。
之后,所有的客户端都会到/queue_barrier节点下创建一个临时节点。
执行顺序
通过调用getData()接口获取/queue_barrier节点的数据内容:n
通过调用getChildren()接口获取/queue_barrier节点下的所有子节点,即获取队列中德所有元素,同时注册对子节点列表变更的Watcher监听。
统计子节点个数
如果子节点个数还不足n个,那么就需要进入等待
接收到Watcher通知后,重复步骤
Zookeeper在大型分布式系统中的应用
Hadoop
具体参考书本
HBase
具体参考书本
Kafka
概念
Kafka是一个吞吐量极高的分布式消息系统,其整体设计是典型的分布式与订阅模式系统。在Kafka集群中,没有”中心主节点“的概念,集群中所有的服务器都是对等的。
应用
主要用于实现低延迟的发送和收集大量的事件和日志数据——这些数据通常都是活跃的数据。
术语介绍
消息生产者
即Producer,是消息产生的源头,负责生成消息并发送到Kafka服务器上。
消息消费者
即Consumer,是消息的使用方,负责消费Kafka服务器上的消息。
主题
即Topic,由用户定义并配置在Kafka服务端,用于建立生产者和消费者之间的订阅关系
生产者发送消息到指定Topic下
消费者从这个Topic下消费消息
消息分区
即Partition,一个Topic下会分为多个分区。
Broker
即Kafka的服务器,用于存储消息,在消息中间件中通常被称为Broker。
消费者分组
即Group,用于归组同类消费者。在Kafka中,多个消费者可以共同消费一个Topic下的消息,每个消费者消费其中的部分消息,这些消费者就组成了一个分组,拥有同一个分组名称,通常也被称为消费者集群。
Offset
消息存储在Kafka的Broker上,消费者拉去消息数据的过程中需要知道消息在文件中的偏移量,这个偏移量就是所谓的Offset。
Broker注册
每个Broker服务器在启动时,都会到Zookeeper上进行注册,即到Broker节点下创建属于自己的节点,其节点路径为/broker/ids/[0...N]。
Broker创建的节点是一个临时节点。
Topic注册
生产者负载均衡
四层负载均衡
使用Zookeeper进行负载均衡
消费者负载均衡
Zookeeper在阿里巴巴的实践与应用
案例一 消息中间件:Metamorphosis
案例二 RPC服务框架:Dubbo
案例三 基于MySQL Binlog的增量订阅与消费
案例四 分布式数据库同步系统:Otter
案例五 轻量级分布式通用搜索平台: 终搜
案例六 实时计算引擎: JStorm
Zookeeper技术内幕
系统模型
数据模型
节点特性
版本——保证分布式数据原子性操作
Watcher——数据变更的通知
ACL——保障数据的安全
序列化与协议
Jute介绍
使用Jute进行序列化
深入Jute
通信协议
客户端
一次会话的创建过程
服务器地址列表
ClientCnxn:网络I/O
会话
会话状态
会话创建
会话管理
会话清理
重连
服务器启动
单机版服务器启动
集群版服务器启动
Leader选举
Leader选举概述
Leader选举的算法分析
Leader选举的实现细节
服务器个角色介绍
Leader
Follower
Observer
集群间消息通信
请求处理
会话创建请求
SetData请求
事务请求转发
GetData请求
数据与存储
内存数据
事务日志
snapshot——数据快照
初始化
数据同步
小结
Zookeeper运维
配置详解
基本配置
高级配置
四字命令
JMX
开启远程JMX
通过JConsole链接Zookeeper
监控
实时监控
数据统计
创建一个高可用的集群
集群组成
容灾
扩容与缩容
日常运维
数据与日志管理
Too many connections
磁盘管理
小结
分布式锁的目的是允许它的客户端进程同步彼此的操作,并对当前所处环境的基本状态信息达成一致
0 条评论
下一页