分布式系统一致性概念及设计方法

CAP

分布式系统,尤其是分布式存储系统,在进行设计时有许多方面需要考虑,其中绕不开的一个问题就是CAP,CAP定理描述如下:

C(Consistency)一致性:也就是所有用户看到的数据是一样的。

A(Availability)可用性:总是能够在合理的时间内返回合理的响应。

P(Partition tolerance)分区容错性:当出现网络分区后,系统能够继续工作。

C、A、P三者之间不不可兼得,分布式系统的设计是就要思考对他们如果取舍。

在分布式系统中,网络无法100%可靠,网络分区其实是一个必然现象。如果我们选择了CA而放弃了P,那么当发生分区现象时,为了保证一致性,这个时候必须拒绝请求,但是A又不允许,所以分布式系统理论上不可能选择CA架构,只能选择CP或者AP架构。

对于CP来说,放弃可用性,追求一致性和分区容错性,ZooKeeper 其实就是追求的强一致。

对于AP来说,放弃一致性(这里说的一致性是强一致性),追求分区容错性和可用性,这是很多分布式系统设计时的选择,后面要说的BASE也是根据AP来扩展。

另外,如果CAP中选择两个,比如你选择了CP,并不是叫你放弃A。因为P出现的概率实在是太小了,大部分的时间你仍然需要保证CA。就算分区出现了你也要为后来的 A 做准备,比如通过一些日志的手段,是其他机器回复至可用。

 

对于Consistency有着诸多分类,常见如:

Eventual Consistency 最终一致

Linearizability Consistency线性一致

Causal Consistency因果一致

以上这些分类却没有明确相对应的Availability。这也是分布式系设计时需要思考的一个问题:我们降低了Consistency后,是否真的能够提高Availability?Paxos算法可以容忍系统中少数集合中的节点失效,根据描述我们认为Paxos算法在系统级别提供高可用服务,同时提供了Consistency服务。这似乎与CAP理论相违背。考虑CAP理论对于Availability的定义,要求对任意节点的请求都能立刻(read-time)得到回应。假设由于网络分区将系统分为了一个多数集和一个少数集,对于Paxos算法,尽管多数集中的节点仍然可以正确且立即回复请求,但是少数集中的节点不能。CAP理论这样定义有一定道理,因为在网络分区发生时,有可能客户端并不能访问多数集中的节点。

ACID

ACID性质指的是并行执行多个事务(Transaction)时需要保证的性质:

A(Transaction Atomicity)原子性:组成事务的多个事件要么都成功要么都失败(all-or-nothing)

C(Database Consistency)一致性:执行事务的前后,数据库的状态保持一致

I(Isolation)独立性:并发执行的事务之间不互相影响

D(Durability)持久性:已经提交的事务中的事件不会丢失

ACID中的Consistency和CAP定理中的Consistency意义完全不同,为了区分这一点我将ACID中的C称为Database Consistency。同样的,ACID中的Atomicity和CAP中的Availability也完全不同。

BASE

BASE 是 Basically Available(基本可用)、Soft state(软状态)和 Eventually consistent (最终一致性)三个短语的缩写,是对 CAP 中 AP 的一个扩展。

基本可用:分布式系统在出现故障时,允许损失部分可用功能,保证核心功能可用。

软状态:允许系统中存在中间状态,这个状态不影响系统可用性,这里指的是 CAP 中的不一致。

最终一致:最终一致是指经过一段时间后,所有节点数据都将会达到一致。

BASE 解决了 CAP 中理论没有网络延迟,在 BASE 中用软状态和最终一致,保证了延迟后的一致性。

BASE 不同于 ACID 的强一致性模型,而是通过牺牲强一致性来获得可用性,并允许数据在一段时间内是不一致的,但最终达到一致状态。

CAP和ACID的区别

CAP理论更多的关注于分布式共享模型下对象的一致性问题和可用性问题,可以称之为外部一致性。例如:在分布式系统中,写操作后再读,就必须返回写入的值。比如分布式数据库A、B、CA 中写入数据 hello,写完马上读 BC,就一定要读出 hello,读出来我们就称之为符合一致性。

ACID性质是数据库系统中并发执行多个事务时的问题,是数据库领域的传统问题,可以称之为内部一致性。例如:事务开始前和结束后,数据库的完整性约束没有被破坏 。比如 AB 转账,不可能 A 扣了钱,B 却没收到。

内部一致性注重于事务前后数据的完整性,而外部一致性则注重于读写数据的一致性。

强一致性约束下的分布式系统

线性一致性的实现方法

我们的目标是实现一个线性一致性的存储系统。由于线性具有本地属性,我们可以将问题进一步简化。

总的来说实现一个Linearizability有如下几种方法:

  • Single-leader replication (potentially linearizable)
  • Consensus algorithms (linearizable)
  • Multi-leader replication (not linearizable)
  • Leaderless replication (probably not linearizable)

分为这样几种思路:

  1. Total Order Broadcast
  2. Quorum read/write
  3. Write-invalidate & Read-through
  4. Write-through

Total Order Broadcast:让每个replication以相同的顺序接收到全序排列的消息,显然,这符合Linearizability Consistency的定义。使用Consensus算法,例如Raft、ZAB等,相当于先在Leader节点上定序,然后再将消息和这一顺序本身传播给所有的replication,实际上等同于Total Order Broadcast。

Quorum:实现Linearizability之前需要在每次Read/Write操作的之前都进行一次Repair,需要注意的是,只有Read/Write操作能够以这种方式实现,Compare-And-Set之类的操作不能以这种形式实现,而必须使用分布式共识(Consensus)算法。

Read-through/Write-through:主要适用于Cache场景,在分布式存储场景下使用这样的方法有较大的丢失数据的风险。

达成Linearizability的代价为Client到Leader的延迟加上Leader到多数集中最慢的节点的延迟。

串行隔离事务的实现方法

常见的串行隔离事务的方法主要有:

  1. 单线程Serialize执行
  2. Strict 2 Phase Locking
  3. Serializable Snapshot Isolation Algorithm

单并发Serialize和Strict 2PL(两阶段提交)属于悲观并发,SSI(Serializable Snapshot Isolation)属于乐观并发。SSI的原理大致是使用快照隔离每个人物都认为自己是唯一的,在处理过程中不检查是否冲突,但是在提交前检查是否与其他操作冲突,如果有的话就Abort,没有的话就可以提交。具体的乐观并发控制会出一篇详细介绍。

 

实现分布式事务所需要解决的主要问题是Atomic Commitment,即多个节点数据一致的问题。Atomic Commitment分为阻塞和非阻塞两种。阻塞的一个典型的实现方法是两阶段提交。非阻塞式提交一个典型的实现方法是3PC(3 阶段提交),但是由于3PC不能在节点失效时保证正确性,所以几乎没有人在实际环境中使用3PC。

 

对于一个Linearizability Consistency的系统,对于跨越多个机器的事务的实现方法,一个可行的方案是使用Paxos协调多个Replication,每个Replication使用Strict 2PL。这个方案基本上和传统数据库的事务处理一致。SSI的实现需要解决一个重要问题,即如何跨越多个Replication生成一致的快照。

强一致性系统的问题

强一致性虽然使得我们可以像是对待只有一份副本系统一样使用这一系统,但是代价不仅是增大了时延,还有扩展性的下降,因为我们不能够通过增加副本来提高系统的性能。因此,我们应该只在必要的时候提供强一致性服务,例如使用额外的系统(Zookeeper)。

Strict 2PL的并发度也比较低,带来的问题是事务处理的性能低。SSI的并发度尽管比Strict 2PL要高,但是在高并发场景下Abort的概率也比较高。

高可用性约束下的分布式系统

从前面的CAP定理的结论可知若想实现一个100% 高可用的系统,最高只能支持Causal Consistency。这里没说Eventual Consistency,是因为目前还没有统一的对于Eventual Consistency的形式化的定义,分歧主要集中在是什么程度才是最终和怎样才算一致两方面。

因果一致的实现方法

Single Object(或者说Per-Key)的因果一致性是容易实现的,使用MVCC等技术可以同时存储对象的多个版本,在写入时只需指定其依赖于哪一个版本,即可实现Single Object的因果一致性。需要注意的是,为了维持数据访问的一致性在会话期间只与同一个副本进行通信。一般情况下系统应该提供Single Object的因果一致性。

 

Serial number因果一致性是为每个操作分配一个表示顺序的序列号,以序列号来表明操作之间的因果关系。常见的大规模序列号生成手段有:

时间戳:使用高精度的时间戳作为序列号

提前规划:使用取模的方式,按照生成器个数来划分可用序列号,部署多个序列号生成服务(例如:两个节点可以分别使用奇偶序列号的生成器)

批量生成:生成器以批量分配的方式,每次向节点分配一个连续的区间。

以上这些生成序列号的方法问题在于,这些序列号不能保证全局有序:

系统时钟会有偏差,多个节点间时钟之间不一定同步,时间戳不一定能表示操作的先后顺序。

如果服务节点的负载不均,则旧的序列号可能会被应用到新的操作上面,先后顺序也无法保证。

为此,我们需要一个能够保证全局顺序的序列号生成机制。

最终一致的实现方法

在某个时间点左右数据库系统中的各个副本间的状态很可能是不一致的。但是经过一段任意长的时间后,数据库中的所有副本最终都能收敛convergence到相同的状态。

这种极弱的一致性保证,就是我们常说的 最终一致性Eventual Consistency。这种弱一致性保证使得系统设计较为灵活,从而能够达到较高的性能。但是这种最终一致性的系统设计要求比较高,当系统设计中涉及到最终一致性时,应用层需要十分关注复制滞后对系统的影响。并且需要根据业务所需的一致性保证来设计系统,变相增加了应用开发者的工作量。此外,某些问题在网络错误或者高并发等特定场景下时才会暴露出来。

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
《大规模分布式存储系统:原理解析与架构实战》是分布式系统领域的经典著作,由阿里巴巴高级技术专家“阿里日照”(OceanBase核心开发人员)撰写,阳振坤、章文嵩、杨卫华、汪源、余锋(褚霸)、赖春波等来自阿里、新浪、网易和百度的资深技术专家联袂推荐。理论方面,不仅讲解了大规模分布式存储系统的核心技术和基本原理,而且对谷歌、亚马逊、微软和阿里巴巴等国际型大互联网公司的大规模分布式存储系统进行了分析;实战方面,首先通过对阿里巴巴的分布式数据库OceanBase的实现细节的深入剖析完整地展示了大规模分布式存储系统的架构与设计过程,然后讲解了大规模分布式存储技术在云计算和大数据领域的实践与应用。, 《大规模分布式存储系统:原理解析与架构实战》内容分为四个部分:基础篇——分布式存储系统的基础知识,包含单机存储系统的知识,如数据模型、事务与并发控制、故障恢复、存储引擎、压缩/解压缩等;分布式系统的数据分布、复制、一致性、容错、可扩展性等。范型篇——介绍谷歌、亚马逊、微软、阿里巴巴等著名互联网公司的大规模分布式存储系统架构,涉及分布式文件系统、分布式键值系统、分布式表格系统以及分布式数据库技术等。实践篇——以阿里巴巴的分布式数据库OceanBase为例,详细介绍分布式数据库内部实现,以及实践过程中的经验。专题篇——介绍分布式系统的主要应用:云存储和大数据,这些是近年来的热门领域,本书介绍了云存储平台、技术与安全,以及大数据的概念、流式计算、实时分析等。
自己花钱买的电子书,高清完整版!很实用的教材,读起来一点也不晦涩。 目 录 译者序 前言 第1章 概论 1.1 推动因素 1.2 基本计算机组成 1.3 分布式系统的定义 1.4 我们的模型 1.5 互连网络 1.6 应用与标准 1.7 范围 1.8 参考资料来源 参考文献 习题 第2章 分布式程序设计语言 2.1 分布式程序设计支持的需求 2.2 并行/分布式程序设计语言概述 2.3 并行性的表示 2.4 进程通信与同步 2.5 远程过程调用 2.6 健壮性 第 3 章 分布式系统设计的形式方法 3.1 模型的介绍 3.1.1 状态机模型 3.1.2 佩特里网 3.2 因果相关事件 3.2.1 发生在先关系 3.2.2 时空视图 3.2.3 交叉视图 3.3 全局状态 3.3.1 时空视图中的全局状态 3.3.2 全局状态:一个形式定义 3.3.3 全局状态的“快照” 3.3.4 一致全局状态的充要条件 3.4 逻辑时钟 3.4.1 标量逻辑时钟 3.4.2 扩展 3.4.3 有效实现 3.4.4 物理时钟 3.5 应用 3.5.1 一个全序应用:分布式互斥 3.5.2 一个逻辑向量时钟应用:消息的 排序 3.6 分布式控制算法的分类 3.7 分布式算法的复杂性 第4章 互斥和选举算法 4.1 互斥 4.2 非基于令牌的解决方案 4.2.1 Lamport算法的简单扩展 4.2.2 Ricart和Agrawala的第一个算法 4.2.3 Maekawa的算法 4.3 基于令牌的解决方案 4.3.1 Ricart和Agrawala的第二个算法 4.3.2 一个简单的基于令牌环的算法 4.3.3 一个基于令牌环的容错算法 4.3.4 基于令牌的使用其他逻辑结构的 互斥 4.4 选举 4.4.1 Chang和Roberts的算法 4.4.2 非基于比较的算法 4.5 投标 4.6 自稳定 第5章 死锁的预防、避免和检测 5.1 死锁问题 5.1.1 死锁发生的条件 5.1.2 图论模型 5.1.3 处理死锁的策略 5.1.4 请求模型 5.1.5 资源和进程模型 5.1.6 死锁条件 5.2 死锁预防 5.3 一个死锁预防的例子:分布式数据库 系统 5.4 死锁避免 5.5 一个死锁避免的例子:多机器人的 灵活装配单元 5.6 死锁检测和恢复 5.6.1 集中式方法 5.6.2 分布式方法 5.6.3 等级式方法 5.7 死锁检测和恢复的例子 5.7.1 AND模型下的Chandy,Misra和Hass 算法 5.7.2 AND模型下的Mitchell和Merritt 算法 5.7.3 OR模型下的Chandy,Misra和Hass 算法 第6章 分布式路由算法 6.1 导论 6.1.1 拓扑 6.1.2 交换 6.1.3 通信类型 6.1.4 路由 6.1.5 路由函数 6.2 一般类型的最短路径路由 6.2.1 Dijkstra集中式算法 6.2.2 Ford的分布式算法 6.2.3 ARPAnet的路由策略 6.3 特殊类型网络中的单播 6.3.1 双向环 6.3.2 网格和圆环 6.3.3 超立方 6.4 特殊类型网络中的广播 6.4.1 环 6.4.2 2维网格和圆环 6.4.3 超立方 6.5 特殊类型网络中的组播 6.5.1 一般方法 6.5.2 基于路径的方法 6.5.3 基于树的方法 第7章 自适应、无死锁和容错路由 7.1 虚信道和虚网络 7.2 完全自适应和无死锁路由 7.2.1 虚信道类 7.2.2 逃逸信道 7.3 部分自适应和无死锁路由 7.4 容错单播:一般方法 7.5 2维网格和圆环中的容错单播 7.5.1 基于局部信息的路由 7.5.2 基于有限全局信息的路由 7.5.3 基于其他故障模型的路由 7.6 超立方中的容错单播 7.6.1 基于局部信息的模型 7.6.2 基于有限全局信息的模型:安全 等级 7.6.3 基

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值