数据一致性设计理念

在分布式存储领域,为了增加系统的高可用性,经常将同一份数据存储多个副本,常见的做法的三备份。但是此做法也引来了数据一致性的问题。为了解决数据一致性的问题,业界常用的有CAP、ACID、BASE等理论模型。

CAP原则

CAP是对强一致性(Consistency)、可用性(Availability)、分区容忍性(Partition Tolerance) 的一种简称。
强一致性:即在分布式系统中同一数据多副本的情况下,对数据的更新操作体现出的效果与只有单份数据是一样的。
可用性:客户端在任何时刻对分布式系统的读写操作都应保证在限定延时内完成。
分区容忍性:即使分区机器间无法进行网络通信仍能继续工作。

CAP原则最初由Eric Brewer于1999年提出,他同时证明:对于一个大型分布式系统,CAP三者不可兼得。即要么AP,要么CP,要么AC,不存在CAP。

这里写图片描述

ACID原则

在关系型数据库领域经常采纳ACID原则,即原子性(Atomicity)、一致性(Consistency)、事务独立性(Isolation)、持久性(Durability)
原子性:指一个事务要么全部执行,要么完全不执行,不允许一个事务执行一半就停止。
一致性:事务的开始和结束时,硬始终满足一致性约束条件。
事务独立性:如果有多个事务同时执行,彼此之间不需要知晓对方的存在。不允许出现两个事务交错、间隔执行部分任务的情形,即要求事务之间需要序列化执行。
持久性:事务的持久性是指事务运行成功后,对系统状态的更新是永久,不会无缘由的回滚撤销。

BASE原则

传统关系型数据库靠ACID获得高可靠和强一致性。而绝大多数NoSQL则采用BASE原则,即基本可用(Basically Available)、软状态(Soft State)、最终一致性(Eventually Consistency)
基本可用:绝大多数时间内系统处于可用状态,运行偶尔的失败。
软状态:又称之为柔性状态。指数据状态不要求在任意时刻都保证完全同步。即处于有状态和无状态之间的中间状态。
最终一致性:最终一致性要求在给定时间窗口内数据会达到一致状态,属于一致弱一致性。

可以看出BASE原则通过牺牲强一致性来获取高可用性。
根据目前的NoSQL发展来看,尽管绝大多数NoSQL系统采用了BASE原则,但是正在逐步提供局部的ACID的特性,即全局保证BASE原则,局部支持ACID,吸收二者好处,在两者之间建立平衡。

一致性模型分类

一致性模型包括:强一致性、弱一致性、最终一致性、因果一致性、“读你所写”一致性、会话一致性、单调读一致性、单调写一致性。
其关系图如下:
这里写图片描述
可以看出最终一致性是弱一致性的一种特殊情况,除强一致性外,其他类型都属于最终一致性的特性或者其变体。其中会话一致性是“读你所写”一致性的变体,而“读你所写”一致性又是因果一致性的一个特例。

强一致性

对于连接系统的所有进程,看到的关于某数据的数值是一致的,如果某进程对数据进行了更新,所有数据的后序读操作都会以这个更新后的值为准,直到数据被其他进程改变为止。
如图,进程Awrite(x,v2)将x数值由v1变为v2,多有进程在这个操作后都会看到x的最新值v2。
这里写图片描述

弱一致性

不能满足强一致性的情形皆可统称为弱一致性。

最终一致性

最终一致性是一种弱一致性。他无法保证某个数值x做出更新后,所有后续针对x的操作能够立即看到新数值,而是需要一个时间片段,在这个时间片段之后可以保证这一点,而在这个时间片段内数据可能是不一致的。这个时间片段称之为“不一致窗口”。
如图,即使是对x做出改变的进程A,也可能在不一致窗口看到旧值。
这里写图片描述

因果一致性

因果一致性发送在进程之间有因果依赖的关系的情况下。
如图:进程A和B之间存在依赖关系,当进程A将x的值更新为v2后,会通过Notify(A,B,x,v2)来通知进程B,进程B在接到通知后,后续的操作会对新值进行操作,从而进程A和B保证了数据的因果一致性,而对进程C来说,在不一致窗口内可能看到的依旧是旧值v1
这里写图片描述

“读你所写”一致性

“读你所写”一致性是因果一致性的特例。如图:进程A把数据x更新为v2后,理解给自己发出一条通知Notify(A,A,x,v2),所以进程A之后的操作都是以新数值v2作为基础。其他进程未受影响。
这里写图片描述

会话一致性

“读你所写”一致性的一种现实版本变体即会话一致性。
当进程A通过会话与系统连接,在同一个会话内,可以保证“读你所写”一致性,而在不一致窗口内,如果因系统故障等原因导致会话终止,进程A仍旧可能读出x的旧值v1。
这里写图片描述

单调读一致性

单调读一致性是最终一致性的另外一种变体。它保证如果某个进程读取到数据x的某个版本v2,那么系统后序的读取操作都不能看到比v2更老的数值,比如v1。
这里写图片描述

单调写一致性

另外一种最终一致性的变体是单调写一致性,对于某进程来说,单调写一致性可以保证其多次写操作的序列化。

猜你喜欢

转载自blog.csdn.net/jsong1025/article/details/81079504