前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >了解一致性模型

了解一致性模型

作者头像
林一
发布2018-12-11 09:27:01
9980
发布2018-12-11 09:27:01
举报
文章被收录于专栏:MessageQueue

What is Consistency

一致性(Consistency)一直是分布式系统里一个很重要的话题。

在存储系统中,为了避免数据丢失,我们都会对数据进行持久化。

对数据进行持久化可以避免宕机带来的数据丢失问题,但是不能解决单机永久性故障的问题。存储系统作为基础设施,在单机上持久化是远远不够的,我们需要将数据复制到多台机器上以提升系统的可用性和可靠性。

一旦数据被复制到多个节点,那么就产生了一致性的问题。

系统需要定义一组协议来规定用户读写多副本的行为,这组协议称之为一致性模型(Consistency Model)。在分布式系统领域,谈论一致性时通常谈论的都是一致性模型。

Consistency Model

不同的一致性模型对系统的行为和表现有不同的约束。

Strict Consistency

Strict Consistency是最强的一致性模型,要求任何读取操作都能读取到最新的值,换句话说,要求任何写入操作立即同步给所有进程。在分布式系统中,数据的同步是需要时间的,因此在分布式系统下无法严格实现Strict Consistency。除非让所有的读写操作都只在一个进程的一个线程中执行或者,读写操作被锁保护起来。(根据CAP的原理,这个一致性模型在没有牺牲可用性的前提下是不能得到满足的。 性能也是不可接受的:所有的写操作需要同步到所有节点之后再返回给客户端。)

Strict Consistency如上图所示,在时间轴上,一旦有进行写入了x=1,其他进程立即能读到x=1的值。

  • 在W(x)1之后,W(x)2之前,所有进程读取到的x的值一定是1
  • 在W(x)2之后,W(x)3之前,所有进程读取到的x的值一定是2
  • 在W(x)3之后,所有进程读取到的x的值一定是3

Sequential Consistency

Sequential Consistency是比Strict Consistency弱一些的一致性模型,要求:

  1. 进程内,对同一个变量的读写保持顺序
  2. 进程间,“看到”的变量的变更顺序是一致的(不要求和“物理时间”下的顺序保持一致)

以Consistency Model中的例子举例,“看到”以下几种数据的变更顺序都是满足Sequential Consistency的:

  • x=1, x=2, x=3:满足Strict Consistency,自然满足Sequential Consistency
  • x=2, x=1, x=3:满足了P1中同一个变量的变更顺序,不同进程“看到”的顺序一致
  • x=1, x=3, x=2:同上

(进程间的事件的顺序可以参看《Time, Clocks, and the Ordering of Events in a Distributed System》)

Linearizable Consistency

Linearizable Consistency比Sequential Consistency更严格一些:

  1. 进程内,对同一个变量的读写操作保持顺序
  2. 进程间,“看到”的变量的变更顺序和全局“物理时钟”下的顺序是一致的

即Linearizable Consistency是Sequential Consistency的特例,除了满足所有进程读到的变更顺序是相同,还要求这个顺序和全局时钟下的顺序是一致的。

和全局时钟下的顺序保持一致容易理解,即事件的顺序和它们在客观的物理时间下发生的时间顺序是一致的。但是如果事件是并发发生的,如何满足这个顺序要求:

如上图,P0的write x=1操作和P1的read x=0/1有重叠的部分,那么之间的先后关系是怎样的?

对于并发的情况Linearizable Consistency并不要求他们之间有确定的顺序,即认为P0的write x=1先于P1的read x=0/1或者P1的read x=0/1先于P0的write x=1都是合理的,但是P0~P3进程看到的这两个操作的顺序必须是确定的、一致的。

上图的例子中,满足以下情况的序列都是满足Linearizable Consistency的:

  • w1 r1 r1 r1(P0->P1->P2->P3或P0->P1->P3->P2)
  • r0 w1 r1 r1(P1->P0->P2->P3或P1->P0->P3->P2)
  • r0 r0 w1 r1(P1->P2->P0->P3)

以上三种一致性模型:Strict Consistency、Linearizable Consistency、Sequential Consistency都是强一致模型

Causal Consistency

Causal Consistency是一种弱一致性模型,仅要求有因果关系的操作顺序性得到保证,非因果关系的操作顺序性没有要求。

具体如下:

  1. 本地顺序:统一进程中,事件的执行顺序即为本地的因果顺序
  2. 异地顺序:如果读操作返回的是写操作的值,那么该写操作一定在读操作之前
  3. 闭包传递:如果a->b,b->c,那么a->c

(Lamport在《Time, Clocks, and the Ordering of Events in a Distributed System》中描述的happen-before关系及其传递闭包)

腾讯朋友圈的例子

在infoq分享的腾讯朋友圈的设计中,他们在设计数据一致性的时候,使用了因果一致性这个模型。用于保证对同一条朋友圈的回复的一致性,比如这样的情况:

  • A发了朋友圈内容为梅里雪山的图片。
  • B针对内容a回复了评论:“这里是哪里?”
  • C针对B的评论进行了回复:“这里是梅里雪山”

那么,这条朋友圈的显示中,显然C针对B的评论,应该在B的评论之后,这是一个因果关系,而其他没有因果关系的数据,可以允许不一致。

微信的做法是:

  • 每个数据中心,都自己生成唯一的、递增的数据ID,确保能排重。在下图的示例中,有三个数据中心,数据中心1生成的数据ID模1为0,数据中心1生成的数据ID模2为0,数据中心1生成的数据ID模3为0,这样保证了三个数据中心的数据ID不会重复全局唯一。
  • 每条评论都比本地看到所有全局ID大,这样来确保因果关系。

上图是Causal Consistency在微信朋友圈中的应用。

比Causal Consistency更弱的一致性模型还有Eventual Consistency(最终一致),比如MySQL的异步复制。

Eventual Consistency:存储系统保证如果没有新的写操作,那么最终,所有的读操作都能读到一致的数据,这里强调对一个数据项的修改最终会收敛。

总结

本文简单的描述了分布式系统中一致性问题的由来,并介绍了几种一致性模型。其中,Strict Consistency要求最为严格,是现实环境中难以满足的一种一致性模型,除非牺牲可用性。Linearizable Consistency略弱于Strict Consistency,不要求写入操作立即可见,但是要求写入操作保持和全局时钟下的顺序一致。Sequential Consistency则更弱一些,不要求写入操作保持和全局时钟下的顺序一致,但是要求所有进程看到的写入操作的顺序是一致的。Strict Consistency、Linearizable Consistency、Sequential Consistency都被认为是强一致的模型。

Causal Consistency被认为是一种若一致模型,它只要求有因果关系的事件之间保持顺序,详细可以参看Lamport在《Time, Clocks, and the Ordering of Events in a Distributed System》中描述的happen-before关系及其传递闭包。

Eventual Consistency是最终一致,只要求在没有新写入的情况下,最终所有数据达成一致,常见于一些异步复制的系统。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-11-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 MessageQueue 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • What is Consistency
  • Consistency Model
  • 总结
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档