在之前的一些博文中,我们简要地描述了几个一致性模型,以及它们在数据库事务方面的意义。通过下面的写作,我想进一步消除白色知识差距,并解释一些其他众所周知的一致性模型,如最终和因果。与传统数据库相比,这些在分布式系统中更为常见,不过,目前这两者之间几乎没有什么区别。
顺序一致性
让我们回想一下上次我们创建的遵循正确路径的一致性模型:
因此,我们将假定可序列化模型的后代并不像第一次那样可怕。今天,顺序一致性模型(图像的左路径)世系将被揭开面纱。
但首先,让我们熟悉并熟悉顺序模型本身。它被Lamport定义为一个属性:
任何执行的结果都是相同的,就像读写操作以某种顺序发生,每个处理器的操作以其程序指定的顺序出现在这个序列中。
我想要一个更直观的解释。当然,如果一个人投入了足够的精力,这种说法是很容易理解的,但人类天生就是懒惰的(至少我是),所以让我们试着重写它的定义(或者更好的,重新绘制!)以便更容易理解。
web上不同的资源使用不同的例子来解释顺序一致的系统。在这里,我想强调的是,想象一些抽象客户机(独立的)和一些它们都可以访问的共享资源就足够了。例如,cpu(或线程)可以是我们的客户端,RAM(或寄存器)可以是共享资源。同样,一些分布式系统(比如HDFS)可以是共享资源,而Alice和Bob应用程序可以是我们的客户端。但它基本上只是一些独立的工人和共享的资源。
而且,所有的一致性模型只是描述系统和用户之间契约的一种花哨的方式:在交互过程中,用户可以从系统期待什么,系统必须处于什么状态。
好吧,让我们想象有一些进程(P1和P2)与系统通信。第一个进程红色读取R(x),然后蓝色写入W(x),绿色写入W(y)。第二个进程执行红色读R(y),然后蓝色读R(x),绿色写W(y)。
如果我们的系统声称是严格可序列化的,那么它必须显示为一个全局位置,所有操作对所有进程来说都完全按照它们的全局顺序显示。这样的系统可能需要全球挂钟时间(这是很难获得的)。
系统保证了什么?它说进程的红色读在蓝色写之前发生,蓝色写在绿色写之前发生。它还说进程P2的red read发生在进程P1的red read之前,也就是说所有事件都是有序的。强有力的保证。
现在我们假设系统说它只是顺序一致的。改变什么?它仍然保证P1进程的读操作在写操作之前发生,而蓝色进程的写操作在绿色进程之前发生。过程P2也是如此。所以,每个进程的操作顺序都保持不变。但细微的区别是,总顺序是不能保证的:系统可以按照自己喜欢的方式交错操作:
每个流程操作顺序被保留(根据定义),但实际顺序不被保证。有些操作甚至看起来像发生在过去!因此,顺序一致性告诉每个进程,它的操作将按照发出的顺序出现。当然,一旦操作完成,它对所有客户机都是可见的。顺序一致允许系统在交错不同进程的操作时具有一定的灵活性。它更容易实现,并且不需要全局时钟。
因果一致性
希望你们现在对顺序一致性有了更清楚的认识。在移动。如果我们放宽我们的要求呢?然后我们就有了最终的一致性模型。它可以保证更少的性能,但可以实现更简单。
在这种情况下,我们有一个相当简单的保证:只有因果操作按顺序出现。它们按客户的顺序出现。然而,其他操作可以被不同的客户机以任意顺序看到。相比之下,顺序(和严格)一致性要求所有提交的操作都应该以相同的顺序出现。我们把这个限制放宽到只适用于因果相关的运算。
以下是这个概念的说明:
第一个进程向x写入值1,然后第二个进程从x读取(我们假设它读取值1),可能执行一些计算,然后再次向x写入值3。这些操作(写/写)是因果相关的,因此它们的顺序对于所有进程应该是相同的。现在,我们有其他进程试图读取x。第三个进程首先读取1,然后读取3。由于保留了正确的顺序,所以一切都没问题。第四个进程先读3,然后读1。这违反了因果一致性。在一个具有因果一致性保证的系统中,P4历史是不可能的。
然而,如果操作没有因果关系,用户可以看到它们的不同顺序。在下面的图像中,两个进程向x写入不同的值,由于它们是独立的,因此不存在顺序保证。
一个更人性化的例子是评论和回复。考虑这些发表:
- 噢,不!我的猫刚刚从窗户跳出去了。
- [几分钟后]呼,猫薄荷植物阻止了她的坠落。
- (朋友的回复)我喜欢这种情况发生在猫身上!
因果关系违反可能导致其他人的屏幕会有:
- 噢,不!我的猫刚刚从窗户跳出去了。
- (朋友的回复)我喜欢这种情况发生在猫身上!
- 天哪,猫薄荷草挡住了她。
第三条信息与第二条有因果关系。在因果一致的系统顺序(原来的2 -> 3)必须被保留。
已经证明,没有更强的一致性形式能够保证低延迟(参见Prince Mahajan, Lorenzo Alvisi, and Mike Dahlin, “Consistency, Availability, and Convergence,””)。
最终一致性
简单地说,最终的一致性保证是“在没有更新(写)的情况下,所有的客户端将在一段时间内看到完全相同的系统状态”。所以,如果我们停止新的写操作,系统最终会收敛到一致的状态。这是一个非常弱的约束,它(可能)实现起来更简单,而且性能也非常好。
好的,我们已经涵盖了上面图片中几乎所有的缩写,只剩下几个:PRAM, WFR, MR, RYW和MW。让我们解释这些。
这就是所谓的以客户端为中心的会话保证(相比之下,严格的顺序保证是以数据为中心的)。因此,在“会话”(一些客户端操作集-上下文)之外没有任何保证。
单调读取(MR) Monotonic reads 表示,一旦读取了某个值,所有后续读取都将返回这个值或一个更新的值。一个值得注意的例子是从系统中读取一些值,然后可能由于网络问题和分区的原因,读取的值可能是陈旧的。单调读取系统避免了这种情况。
单调写(MW) Monotonic writes (MW) 要求所有写的内容按照提交的顺序显示出来。可以肯定,系统不会改变顺序。假设你写了+ 50美元,然后+10%。对于单调的写操作,你可以预期将这些操作应用到一个有100美元的账户会得到165美元(100 + 50美元->美元150 + 10% ->美元165),而不是160美元(100 + 10% ->美元110 + 50美元->美元160)。
读你的写(RYW) Read your writes (RYW)要求每当客户端在更新后读取给定数据项时,Read返回更新后的值。简单。
流水线随机存取存储器(PRAM) Pipelined Random Access Memory 确保单个进程的所有操作都能被其他进程按照它们执行的顺序看到,就像它们在管道中一样。它是前三种型号的组合。
写跟随读(WFR) Writes follow reads 表示在读之后的一些写操作对该值或更近的值进行操作。用事务术语来说,如果一个客户端看到了事务T1的效果,并提交了事务T2,那么其他客户端只有在它看到了事务T1的效果时才会看到事务T2的效果。
这些保证实现最终的一致性。
结论
最后一个可以回答的问题是“在我们的指导图中的那些彩色区域是什么?”简而言之,红色区域系统不可能“完全可用”(因为网络分区和其他原因),而绿色区域系统可以。它们被称为“高可用性”,因为它们的担保很弱。蓝色区域是“粘性可用”系统(当客户端事务针对反映客户端之前所有操作的数据库状态副本执行时,它最终会收到响应)。更多细节可以在Peter Bailis的论文中找到。
参考文献
- All from the previous post
- http://www.news.cs.nyu.edu/~jinyang/fa09/notes/ds-consistency.pdf
- http://www-bcf.usc.edu/~wyattllo/papers/causal-login13.pdf
- http://www.cs.colostate.edu/~cs551/CourseNotes/Consistency/TypesConsistency.html
原文:https://sergeiturukin.com/2017/06/29/eventual-consistency.html
本文:http://jiagoushi.pro/node/1400
讨论:请加入知识星球【首席架构师圈】或者小号【jiagoushi_pro】或者QQ群【11107777】
- 登录 发表评论
- 210 次浏览
最新内容
- 4 days 11 hours ago
- 4 days 13 hours ago
- 4 days 13 hours ago
- 1 week ago
- 1 week ago
- 1 week ago
- 1 week ago
- 1 week ago
- 1 week 5 days ago
- 1 week 5 days ago