分布式系统概念--第一篇 一致性协议、一致性模型、拜占庭问题、租约、副本协议

简介:

1,一致性协议

两阶段提交协议与Raft协议、Paxos协议

①两阶段提交协议

在分布式系统中,每个节点虽然可以知晓自己的操作时成功或者失败,却无法知道其他节点的操作的成功或失败。当一个事务跨越多个节点时,为了保持事务的ACID特性,需要引入一个作为协调者的组件来统一掌控所有节点(称作参与者)的操作结果并最终指示这些节点是否要把操作结果进行真正的提交(比如将更新后的数据写入磁盘等等)。因此,二阶段提交的算法思路可以概括为: 参与者将操作成败通知协调者,再由协调者根据所有参与者的反馈情报决定各参与者是否要提交操作还是中止操作。

因此,系统包含两类节点,一类是协调者,一类是参与者,协议的执行由两个阶段组成:

具体参考:二阶段提交:维基百科

两阶段协议是阻塞的,节点在等待对方的应答消息时,它不能做其他事情且持有的资源也不释放。它主要是用来保证跨多个节点的操作的原子性--要么都操作,要么都不操作,而像Raft协议则诸如用来保证操作的一致性,即各个节点都执行相同的操作

两阶段协议的举例参考:两阶段提交协议

 

②Raft协议和Paxos协议

Raft与Paxos 在分布式应用中的基本功能相似,但是Paxos难于理解,相对而言Raft算法要简单一些。关于Raft协议有一篇经典的论文:

《In Search of an Understandable Consensus Algorithm (Extended Version)》

其中文翻译地址参考:寻找一种易于理解的一致性算法(扩展版)

还有一篇文章详细解释了Raft算法的相关实现:Raft论文的第 31 号参考文献。

下面仅记录一下看论文过程中出现的一个问题:

为什么 “大多数规则” 能够保证对于一个给定的任期,只会有一个候选人最终赢得选举成为Leader?
在Raft中,对于一个给定的任期号,每一台Server按照先来先服务原则对该任期号最多只投一张票,若某Candidate发送的请求投票RPC带有的任期号获得超过半数的Server的同意,则该Candidate成为Leader。
正是由于每个Server对某个任期只最多投一次票,且获得的投票要超过半数才能成为Leader,故在一个给定的任期投票中,最终只会有一个Candidate成为Leader。

关于Raft协议中的Leader选举步骤参考:Raft系列文章之二:Leader选举

 

2,分布式系统中常见的三种一致性模型

①强一致性:当更新操作在某个副本上执行成功后,之后所有的读操作都要能够获得最新的数据。对于单副本而言,读写操作都是在同一数据上执行,很容易保证一致性;而对于多副本数据,则需要使用分布式协议如2PC协议。

②弱一致性:当更新某数据时,用户读到最新的数据需要一段时间。

③最终一致性:它是一种特殊形式的弱一致性。它不能保证当某个数据X更新后,在所有后续对X的操作能够看到新数据,而是需要一个时间片段,在经过该时间片段之后,则能保证。在这个时间片段内,数据可能是不一致的,该片段称“不一致窗口“。

参考:数据一致性模型

 

3,拜占庭将军问题

在分布式理论中,经常看到”在非拜占庭错误情况下,算法是有效的……“ 或者说 ”...可以容忍非拜占庭失效“。那么什么是拜占庭将军问题呢?

分布式计算上,不同的计算机透过讯息交换,尝试达成共识;但有时候,系统上协调计算机(Coordinator / Commander)或成员计算机 (Member / Lieutanent)可能因系统错误并交换错的讯息,导致影响最终的系统一致性。参考:维基百科:拜占庭将军问题

也即,在系统不同的机器之间会传递错误的消息,这种情况即为拜占庭问题。这与”网络分割、机器崩溃...”是不同的。比如Raft协议不能容忍拜占庭问题,但是能够 在非拜占庭错误情况下,有网络延迟、分区、丢包、冗余和乱序等错误情况出现时,都可以保证其操作的正确性。

 

4,租约,心跳包(heartbeat)

①租约

这里主要列举租约可以用来干什么?

a,进行故障检测。这类似于ZooKeeper中master 与 slaver 之间发送的心跳包的作用。在ZK中, master 和 slaver 之间通过交换心跳包来检测它们是否还存活。一个具体的例子参考:故障检测

b,维护缓存一致性维护缓存的一致性,第一种办法是轮询:每次读取数据时都先询问服务器数据是不是最新的,若不是,则先让服务器传输新数据,然后再读取该新数据。第二种方法是回调:由服务器记录有哪些客户端读取了数据,当服务器对数据做修改时先通知记录下来的这些客户端,上次读取过的数据已经失效。这二种方法都有一定的缺陷,参考:租约机制简介

因此,可以引入租约机制。在租约期限内,可以保证客户端缓存的数据是最新的。当租约过期后,客户端需要重新向服务器询问数据,重新续约。

租约的定义:租约就是在一定期限内给予持有者特定权力的 协议。每个租约都有一个期限,正是这个期限可以保证租约机制容忍机器失效和网络分割。

租约机制优化后台数据库访问的一个例子:使用租约机制解决缓存数据更新的问题

 

5,副本协议

副本协议是控制副本读写行为的规则,使得副本满足可用性和一致性。

副本协议分为两类,①中心化的副本控制协议:由一个中心节点协调副本数据的更新,维护副本数据的一致性。这里重点介绍下常用的Primary-Secondary中心化副本控制协议:假设数据是以数据段(segment/partition)为单位分布在集群各台机器上的,每个数据段指定一个作为主副本,其余的数据段则为从副本,对该数据段的更新(读写)而言,由主副本来负责。比如,当多个Client同时需要更新某个数据段时,所有的更新操作都发送到该数据段所对应的主副本所在的机器上,由它来确定更新的顺序,负责协调一致性。

那么,Client如何找到主副本所在的机器呢???这需要一个元数据服务器,它专门用来记录主副本的位置及相关信息,记录集群个各个数据段的主副本的位置信息,副本分配情况……该元数据服务器应该相当于GFS中的Master。

注意:由于上面是假设数据不是以机器为单位分布在集群中,而是以数据段为单位分布在集群中,当某个数据段被指定为主副本时,该主副本也是按照以数据段为单位的数据分布方式分布到集群中的,即各个Primary副本的位置在集群中是随机分配的。

要将Primary副本所在的机器与Master机器区分开来:应该在GFS中,Primary副本所在的机器可能是某台Slaver机器,它用来存储各个数据块。而Master是用来存储元数据信息的。

②去中心化的副本控制协议:各个节点之间是平等的,通过协商方式来达成某些操作。

学习材料参考:《分布式系统原理介绍  刘杰》


本文转自hapjin博客园博客,原文链接:http://www.cnblogs.com/hapjin/,如需转载请自行联系原作者

相关文章
|
10天前
|
机器学习/深度学习 数据可视化 TensorFlow
使用Python实现深度学习模型的分布式训练
使用Python实现深度学习模型的分布式训练
127 73
|
6天前
|
存储 缓存 负载均衡
一致性哈希:解决分布式难题的神奇密钥
一致哈希是一种特殊的哈希算法,用于分布式系统中实现数据的高效、均衡分布。它通过将节点和数据映射到一个虚拟环上,确保在节点增减时只需重定位少量数据,从而提供良好的负载均衡、高扩展性和容错性。相比传统取模方法,一致性哈希能显著减少数据迁移成本,广泛应用于分布式缓存、存储、数据库及微服务架构中,有效提升系统的稳定性和性能。
34 1
|
1月前
|
分布式计算 Java 开发工具
阿里云MaxCompute-XGBoost on Spark 极限梯度提升算法的分布式训练与模型持久化oss的实现与代码浅析
本文介绍了XGBoost在MaxCompute+OSS架构下模型持久化遇到的问题及其解决方案。首先简要介绍了XGBoost的特点和应用场景,随后详细描述了客户在将XGBoost on Spark任务从HDFS迁移到OSS时遇到的异常情况。通过分析异常堆栈和源代码,发现使用的`nativeBooster.saveModel`方法不支持OSS路径,而使用`write.overwrite().save`方法则能成功保存模型。最后提供了完整的Scala代码示例、Maven配置和提交命令,帮助用户顺利迁移模型存储路径。
|
1月前
|
存储 分布式计算 负载均衡
分布式计算模型和集群计算模型的区别
【10月更文挑战第18天】分布式计算模型和集群计算模型各有特点和优势,在实际应用中需要根据具体的需求和条件选择合适的计算架构模式,以达到最佳的计算效果和性能。
70 2
|
2月前
|
JSON 分布式计算 前端开发
前端的全栈之路Meteor篇(七):轻量的NoSql分布式数据协议同步协议DDP深度剖析
本文深入探讨了DDP(Distributed Data Protocol)协议,这是一种在Meteor框架中广泛使用的发布/订阅协议,支持实时数据同步。文章详细介绍了DDP的主要特点、消息类型、协议流程及其在Meteor中的应用,包括实时数据同步、用户界面响应、分布式计算、多客户端协作和离线支持等。通过学习DDP,开发者可以构建响应迅速、适应性强的现代Web应用。
|
2月前
|
架构师 Java 数据中心
二阶段提交:确保分布式系统中数据一致性的关键协议
【10月更文挑战第16天】在分布式系统中,数据一致性的维护是一个至关重要的挑战。为了应对这一挑战,二阶段提交(Two-Phase Commit,简称2PC)协议应运而生。作为一种经典的分布式事务协议,2PC旨在确保在分布式系统中的所有节点在进行事务提交时保持一致性。
44 0
|
2月前
|
存储 分布式计算 负载均衡
|
2月前
|
消息中间件 缓存 算法
分布式系列第一弹:分布式一致性!
分布式系列第一弹:分布式一致性!
|
2月前
|
NoSQL Java Redis
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
Redis分布式锁在高并发场景下是重要的技术手段,但其实现过程中常遇到五大深坑:**原子性问题**、**连接耗尽问题**、**锁过期问题**、**锁失效问题**以及**锁分段问题**。这些问题不仅影响系统的稳定性和性能,还可能导致数据不一致。尼恩在实际项目中总结了这些坑,并提供了详细的解决方案,包括使用Lua脚本保证原子性、设置合理的锁过期时间和使用看门狗机制、以及通过锁分段提升性能。这些经验和技巧对面试和实际开发都有很大帮助,值得深入学习和实践。
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
|
22天前
|
存储 NoSQL Java
使用lock4j-redis-template-spring-boot-starter实现redis分布式锁
通过使用 `lock4j-redis-template-spring-boot-starter`,我们可以轻松实现 Redis 分布式锁,从而解决分布式系统中多个实例并发访问共享资源的问题。合理配置和使用分布式锁,可以有效提高系统的稳定性和数据的一致性。希望本文对你在实际项目中使用 Redis 分布式锁有所帮助。
65 5