《从Paxos到Zookeeper》读书笔记,Watcher 监听机制是 Zookeeper 中非常重要的特性,许多 Zookeeper 的使用场景其实都建立在 Watcher 机制之上,例如:分布式锁、配置管理、发布/订阅、命名服务
Watcher 介绍基于 Zookeeper上创建的节点,可以对这些节点绑定监听事件,比如可以监听节点数据变更、节点删除、子节点状态变更等事件。它类似于订阅的方式,即客户端向服务端注册指定的 watcher ,当服务端符合了 watcher 的某些事件或要求则会向客户端发送事件通知,客户端收到通知后找到自己定义的 Watcher 然后 执行相应的回调方法。
ZooKeeper 的 Watcher 机制,总的来说可以分为三个过程:
客户端注册 Watcher
服务器处理 Watcher
客户端回调 Watcher
Watcher 事件同一个事件类型在不同的通知状态中代表的含义有所不同,下表列举了常见的通知状态和事件类型。
核心流程客户端注册 Watcher由两种方式注册 Watcher
创建 ZooKeeper 客户端实例时,传递 ...
Raft 是一种为了管理复制日志的一致性算法,它提供了与 Paxos 算法相同的功能与性能,而 Paxos 算法是为了最终唯一选定一个提案,有关 Paxos 的介绍,可以参考Paxos Made Simple 一文,为了提升可理解性,Raft 将一致性算法分解为几个关键模块,例如:领导者选举、日志复制和安全性,通过通过 Leader 来提供一个更强的一致性来减少需要考虑的状态数量。
介绍Raft 算法在许多方面与现有的一致性算法都很相似,但是它也有一些独特的特性:
强领导者:Raft 使用一种更强的领导能力形式。比如,日志条目只从领导人发送给其他的服务器。这种方式简化了对复制日志的管理并且使得 Raft 算法更加易于理解。
领导选举:Raft 通过随机超时时间来选举领导者,在解决冲突的时候会更加简单快捷。
成员关系调整:Raft 通过联合共识来处理集群成员变更的问题。
复制状态机一致性算法是从复制状态机的背景下提出的,其正确性主要来源于复制状态机的性质:
123任何初始状态一样的状态机,如果执行的命令序列一样,则最终达到的状态也一样。如果将此特性应用在多参与者进行协商共识上,可 ...
《Paxos Made Simple》是 Lamport 另一篇关于 Paxos 的论文,从一个一致性算法所需要满足的条件展开,向读者讲解 paxos 算法的合理性。
从整体上来说, Paxos 算法的目标就是要确保最终会有一个提案被选定,当提案被选定后,其他节点也会获取到被选定的提案。
在 Paxos 算法中存在三个角色:
Proposer (发送提案)
Acceptor (选定提案)
Learner (获取最终选定的提案)
在具体的实现中,一个节点可能充当不同的角色,这里不关心角色与节点之间的转换,不同参与者之间可以通过首发消息来进行通信,当然通信时可能会遇到各种状况:
消息在传递时的延迟、丢失,但是假设并不会被篡改(非拜占庭式容错)
节点可能会宕机,长时间任务导致的对外不可用
网络分区
提案的选定首先从一个最简单的方式出发,如果只有一个 Acceptor 负责选定提案,多个 Proposer 来提交提案,那么只需要约定 Acceptor 选定接受到的第一个提案就行,这种方式非常的简单且易于理解,但是问题也很明显,存在单点问题,当Acceptor 宕机时,整个系统就无法 ...
背景论文从事件开始讲起,进程的执行被看作为一连串事件的持续发生,随后事件的排序问题很自然的被提出来,正如一致性模型与共识一文中,对一致性的探讨。其目的是对事件的发生确定一个合理的顺序,这种顺序的确立,对于一个进程内部发生的事件通常是比较容易的,但是当涉及到不同进程上的事件,通常便没有那么直观。
「Happened Before」现实生活当中,事件的先后顺序往往依赖物理时钟,而物理时钟不可能百分百精确,因此,Lamport 在定义事件之间的关系的时候特意避开了物理时间。这就是著名的「Happened Before」关系(用符号“→”来表示)
在上图中,我们尝试对消息发送事件和消息接收事件进行排序。
在进程Q内部,q2表示一个消息接收事件,q4表示另一个消息发送事件,q2排在q4前面执行,所以q2→q4。
p1和q2分别表示同一个消息的发送事件和接收事件,所以p1→q2;同理,q4→r3。
“happened before”满足传递关系。由p1→q2,q2→q4和q4→r3,可以推出p1→r3。
但是这里的 “happened before” 关系,是一种偏序关系。比如p1和q1两个 ...
《从Paxos到Zookeeper》读书笔记
从集中式到分布式集中式系统指的是由一台或多台主计算机组成的系统,所有数据集中存储,系统功能由中心节点处理。其主要特点是:
部署结构简单:无需多个节点协作,依赖主机的卓越性能。
分布式系统是指硬件或软件组件分布在不同的网络计算机上,通过消息传递进行通信和协调。分布式系统的特点包括:
分布性:计算机可以随意分布在不同空间。
对等性:没有主从之分,所有节点平等。
并发性:多个节点可能并发操作共享资源,挑战较大。
缺乏全局时钟:没有全局时序,事件顺序难以定义。
故障不可避免:节点可能发生各种故障。
同时分布式系统面临许多挑战:
通信异常:网络不可靠,延时远高于单机操作。
网络分区:部分节点无法通信,导致“脑裂”现象,挑战一致性。
三态问题:分布式请求可能会有成功、失败或超时的结果,增加了不确定性。
节点故障:服务器节点宕机或“僵死”是常见问题
从ACID到CAP/BASE事务 指的是对系统中数据的一系列操作集合,详见 事务 这一文所述。
事务具有四个特征,俗称为 ACID :
原子性(Atomicity)
一致性(Con ...
从《从Paxos到Zookeeper》读书笔记 一文中,探讨了从集中式到分布式的发展,而在分布式中涉及到两个核心的概念 CAP 与 BASE,而后者则是对前者在实践中权衡的结果。其核心思想是即使无法做到强一致性,但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性。
那么究竟什么是一致性?各种一致性的含义到底有什么不同?与共识又有什么区别?本文将进行逐一探讨。
什么是一致性一致性这个词其实非常具有迷惑性,因为它在不同的场景中都涉及到,但是含义却又不同
ACID 中的一致性事务中的一致性指的是让数据库处于一致的状态,那什么是一致的状态?比如一次事务涉及金钱的转入与转出,那么这个事务就必须保证转入转出的金额保持一致,从而保证总金额不变,抽象来看,对数据库每进行一次事务操作,其状态就发生一种变化,那么只要数据库的起始状态是一致的,每一次操作保证一致,那么数据库的状态就能保持一致。
所以 ACID 中的一致性,是一个很偏应用层的概念,这与原子性、隔离性和持久性不同,因为这些都是数据库本身提供的,而一致性,则是由特定的业务场景决定的,要做到一致性,是需要依赖数据库的原子性 ...
在一个苛刻的数据存储环境中,可能会出现很多情况:
数据库软件硬件随时失效
应用程序崩溃
节点之间相互失联
由于边界条件竞争引入各种奇怪的问题
事务将应用程序的多个读、写操作捆绑在一起成为一个逻辑操作单元,整个事务要么全部成功、要么失败,从而简化错误处理。
传统关系型数据库(如MySQL、PostgreSQL、Oracle、SQL Server)的事务处理机制是成熟且稳定的。几乎所有的关系数据库和一些非关系数据库都支持事务处理,且大多数的设计理念来源于1975年IBM推出第一个SQL数据库System R。
21世纪末随着非关系(NoSQL)数据库的兴起,这类数据库通过提供新的 数据模型、复制 和 分区 等功能来改进传统关系模型。但在这一变革中,很多新一代的数据库完全放弃事务,或重新定义为比以前弱得多的保证。
为了更深入的理解事务,让我们考虑在正常运行和各种极端情况下,事务所能提供的保证
ACID的含义事务所提供的安全保证即大家所熟知的ACID,分别代表 原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)
...
当面对一些海量数据集或非常高的查询压力时,我们可以通过 数据复制复制,即在不同节点上保存相同数据的多个副本,然而有时还是不够,我们还需要将数据拆分为分区,也成为分片。
采用数据分区的主要目的是提高可扩展性。不同的分区可以放在一个无共享集群的不同节点上。这样一个大数据集可以分散在更多的磁盘上,查询负载也随之分布到更多的处理器上。
对单个分区进行查询时,每个节点对自己所在分区可以独立执行查询操作,因此添加更多的节点可以提高查询吞吐量。超大而复杂的查询尽管比较困难,但也可能做到跨节点的并行处理。
数据分区与数据复制分区通常与复制结合使用,即每个分区在多个节点都存有副本。这意味着某条记录属于特定的分区,而同样的内容会保存在不同的节点上以提高系统的容错性。
既然是切分,那么首要的目的是如何切分数据,即如何决定那些记录应该放在哪些节点上?
分区的首要目标是将数据和查询负载均匀的分布在所有节点上,因为如果分区不均匀,出现某些分区节点比其他分区承担更多的数据量与负载。这意味着10个节点9个空闲,那么最繁忙的那个将会成为系统的瓶颈。
如果随机平均分配在所有节点上,那么当读取特定数据时,便没法知道数 ...
就DDIA-分布式数据系统一文所提到的,出于高可用的目的,我们往往需要将数据复制到其他副本节点来提高容错。这里的复制主要指的是通过互联网在多台机器上保存相同的副本,并且可以带来如下好处:
使数据在地理位置上更接近用户,从而降低访问延迟。
当部分组件出现故障,系统依然可以继续工作,从而提高可用性。
扩展至多台机器以同时提供数据访问服务,从而提高读吞吐量。
在分布式系统中,复制并不像单机系统中几字节的移动那么简单,由于网络的不稳定,单机节点的故障,很有可能带来整个分布式系统的不一致或者不可用。
接下来我们将探讨三种流行的复制数据方式:主从复制、多主复制和无主复制,对于每一种复制方式,可能也需要考虑是同步复制还是异步复制,如何处理失败副本等。
主从复制每个保存数据库完整数据集的节点称之为副本。那么在分布式系统中如何保证数据的一致性呢?
对于每一笔数据写入,所有副本都需要随之更新;否则,某些副本将出现不一致。最常见的解决方案是基于主节点的复制(也称为主动/被动,或主从复制),主从复制的工作原理如下:
指定某一个副本为主副本 (或称为主节点) 。当客户写数据库时,必须将写请 ...
前面几篇文章主要讨论了单台机器存储系统设计的主要技术。后面我们将继续向前迈进,当需要多台机器提供数据存储和检索服务时,又会有哪些挑战和方案呢?
主要出于以下目的,我们需要在多台机器上分布数据:
扩展性当数据量或者读写负载巨大,严重超出了单台机器的处理上限,需要将负载分散到多台机器上。
容错与高可用性 当单台机器 (或者多台,以及网络甚至整个数据中心) 出现故障,还希望应用系统可以继续工作,这时需要采用多台机器提供冗余。这样某些组件失效之后,其他组件可以迅速接管。
延迟考虑如果客户遍布世界各地,通常需要考虑在全球范围内部署服务,以方便用户就近访问最近数据中心所提供的服务,从而避免数据请求跨越了半个地球才能到达目标。
系统扩展能力当负载增加需要更强的处理能力时,最简单的办法就是购买更强大的机器 (有时称为垂直扩展) 。由一个操作系统管理更多的CPU,内存和磁盘,通过高速内部总线使每个CPU都可以访问所有的存储器或磁盘。
这种共享内存架构的问题在于,成本增长过快甚至超过了线性: 即如果把一台机器内的CPU数量增加一倍,内存扩容一倍,磁盘容量加大一倍,则最终总成本增加不止一倍。并 ...