分布式系统的一致性级别划分及Zookeeper一致性级别分析

最近在研究分布式系统的一些理论概念,例如关于分布式系统一致性的讨论,看了一些文章我有一些不解。大多数对分布式系统一致性的划分是将其分为三类:强一致性,顺序一致性以及弱一致性。强一致性(Strict Consistency)也称为:原子一致性(Atomic Consistency)、线性一致性(Linearizable Consistency)。

在谈到Zookeeper的一致性是哪种级别的一致性问题,以及CAP原则中的C是哪一种一致性级别时有些疑惑。

下面是大多数文章中提到的一致性级别

1. 一致性(Consistency)

一致性(Consistency)是指多副本(Replications)问题中的数据一致性。可以分为强一致性、顺序一致性与弱一致性。

1.1 强一致性(Strict Consistency)

也称为:原子一致性(Atomic Consistency)线性一致性(Linearizable Consistency)

强一致性有两个要求:

  • 任何一次读都能读到某个数据的最近一次写的数据。
  • 系统中的所有进程,看到的操作顺序,都和全局时钟下的顺序一致。

简言之,在任意时刻,所有节点中的数据都是一样的。

例如,对于关系型数据库,要求更新过的数据能被后续的访问都能看到,这是强一致性。

1.2 顺序一致性(Sequential Consistency)

the result of any execution is the same as if the operations of all the processors were executed in some sequential order, and the operations of each individual processor appear in this sequence in the order specified by its program. - - Lamport

两个要求:

  • 任何一次读都能读到某个数据的最近一次写的数据。
  • 系统的所有进程的顺序一致,而且是合理的。即不需要和全局时钟下的顺序一致,错的话一起错,对的话一起对。

举个例子:

Write(x, 4):写入x=4
Read(x, 0):读出x=0

1)图a是满足顺序一致性,但是不满足强一致性的。原因在于,从全局时钟的观点来看,P2进程对变量X的读操作在P1进程对变量X的写操作之后,然而读出来的却是旧的数据。但是这个图却是满足顺序一致性的,因为两个进程P1,P2的一致性并没有冲突。从这两个进程的角度来看,顺序应该是这样的:Write(y,2) , Read(x,0) , Write(x,4), Read(y,2),每个进程内部的读写顺序都是合理的,但是这个顺序与全局时钟下看到的顺序并不一样。

2)图b满足强一致性,因为每个读操作都读到了该变量的最新写的结果,同时两个进程看到的操作顺序与全局时钟的顺序一样,都是Write(y,2) ,Write(x,4), Read(x,4) ,  Read(y,2)。

3)图c不满足顺序一致性,当然也就不满足强一致性了。因为从进程P1的角度看,它对变量Y的读操作返回了结果0。那么就是说,P1进程的对变量Y的读操作在P2进程对变量Y的写操作之前,这意味着它认为的顺序是这样的:Write(x,4) , Read(y,0) , Write(y,2), Read(x,0),显然这个顺序又是不能被满足的,因为最后一个对变量x的读操作读出来也是旧的数据。因此这个顺序是有冲突的,不满足顺序一致性。

1.3 弱一致性

数据更新后,如果能容忍后续的访问只能访问到部分或者全部访问不到,则是弱一致性。

最终一致性就属于弱一致性。

最终一致性

不保证在任意时刻任意节点上的同一份数据都是相同的,但是随着时间的迁移,不同节点上的同一份数据总是在向趋同的方向变化。

简单说,就是在一段时间后,节点间的数据会最终达到一致状态。

最终一致性根据更新数据后各进程访问到数据的时间和方式的不同,又可以区分为:

因果一致性(Casual Consistency)。如果进程A通知进程B它已更新了一个数据项,那么进程B的后续访问将返回更新后的值,且一次写入将保证取代前一次写入。与进程A无因果关系的进程C的访问,遵守一般的最终一致性规则。

“读己之所写(read-your-writes)”一致性。当进程A自己更新一个数据项之后,它总是访问到更新过的值,绝不会看到旧值。这是因果一致性模型的一个特例。

会话(Session)一致性。这是上一个模型的实用版本,它把访问存储系统的进程放到会话的上下文中。只要会话还存在,系统就保证“读己之所写”一致性。如果由于某些失败情形令会话终止,就要建立新的会话,而且系统的保证不会延续到新的会话。

单调(Monotonic)读一致性。如果进程已经看到过数据对象的某个值,那么任何后续访问都不会返回在那个值之前的值。

单调写一致性。系统保证来自同一个进程的写操作顺序执行。要是系统不能保证这种程度的一致性,就非常难以编程了。



另外一种划分一致性级别的:

一致性是指从系统外部读取系统内部的数据时,在一定约束条件下相同,即数据变动在系统内部各节点应该是同步的。根据一致性的强弱程度不同,可以将一致性级别分为如下几种:

  ①强一致性(strong consistency)。任何时刻,任何用户都能读取到最近一次成功更新的数据。
  ②单调一致性(monotonic consistency)。任何时刻,任何用户一旦读到某个数据在某次更新后的值,那么就不会再读到比这个值更旧的值。也就是说,获取的数据顺序必是单调递增的。
  ③会话一致性(session consistency)。任何用户在某次会话中,一旦读到某个数据在某次更新后的值,那么在本次会话中就不会再读到比这值更旧的值。会话一致性是在单调一致性的基础上进一步放松约束,只保证单个用户单个会话内的单调性,在不同用户或同一用户不同会话间则没有保障。示例case:php的session概念。
  ④ 最终一致性(eventual consistency)。用户只能读到某次更新后的值,但系统保证数据将最终达到完全一致的状态,只是所需时间不能保障。
  ⑤弱一致性(weak consistency)。用户无法在确定时间内读到最新更新的值。

2. 共识(Consensus)

共识问题中所有的节点要最终达成共识,由于最终目标是所有节点都要达成一致,所以根本不存在一致性强弱之分。

例如,Paxos是共识(Consensus)算法而不是强一致性(Consistency)协议。共识算法没有一致性级别的区分。


疑惑

关于线性一致性的观点,《线性一致性(Linearizability)是并发控制的基础》中提到,Zookeeper是线性一致性的,再比如分布式领域著名的CAP定理中的C,也是指线性一致性。

《如何理解Zookeeper的顺序一致性》中阐述的观点是Zookeeper是顺序一致性的,不是最终一致性也不是强一致性。

又有人在某文章下评论说顺序一致性和最终一致性不是同一个维度的概念。

3.线性化和可串行化的区别

另外在一篇英文文章《Linearizability versus Serializability》讲述了线性化和可串行化的区别

Linearizability for read and write operations is synonymous with the term “atomic consistency” and is the “C,” or “consistency,” in Gilbert and Lynch’s proof of the CAP Theorem. We say linearizability is composable (or “local”) because, if operations on each object in a system are linearizable, then all operations in the system are linearizable.

翻译:读写操作的线性化与术语“原子一致性”同义,并且是Gilbert和Lynch 对CAP定理证明中的 “C”或“一致性” 。我们说线性化是可组合的 (或“本地”),因为如果系统中每个对象的操作是可线性化的,那么系统中的所有操作都是可线性化的。

Serializability is the traditional “I,” or isolation, in ACID. If users’ transactions each preserve application correctness (“C,” or consistency, in ACID), a serializable execution also preserves correctness. Therefore, serializability is a mechanism for guaranteeing database correctness.1

Unlike linearizability, serializability does not—by itself—impose any real-time constraints on the ordering of transactions. Serializability is also not composable. Serializability does not imply any kind of deterministic order—it simply requires that some equivalent serial execution exists.

翻译:可串行性是ACID中的传统“I”或隔离。如果用户的事务各自保持应用程序的正确性(ACID中的“C”或一致性),则可序列化执行也保持正确性。因此,可串行化是一种保证数据库正确性的机制。

与线性化不同,可串行化本身不会对事务的排序施加任何实时约束。可序列化也是不可组合的。可串行化并不意味着任何类型的确定性顺序 - 它只需要存在一些等效的串行执行。

One of the reasons these definitions are so confusing is that linearizability hails from the distributed systems and concurrent programming communities, and serializability comes from the database community. Today, almost everyone uses both distributed systems and databases, which often leads to overloaded terminology (e.g., “consistency,” “atomicity”).

翻译:这些定义如此混乱的原因之一是线性化来自分布式系统和并发编程社区,可串行化来自数据库社区。如今,几乎每个人都使用分布式系统和数据库,这往往会导致过载的术语(例如,“一致性”,“原子”)。

4、zookeeper的一致性分析-单调一致性

很多文章和博客里提到,zookeeper是一种提供强一致性的服务,在分区容错性和可用性上做了一定折中,这和CAP理论是吻合的。但实际上Zookeeper提供的只是单调一致性。
原因
  1. 假设有2n+1个server,在同步流程中,leader向follower同步数据,当同步完成的follower数量大于 n+1时同步流程结束,系统可接受client的连接请求。如果client连接的并非同步完成的follower,那么得到的并非最新数据,但可以保证单调性,也就是说,可获取的数据顺序是单调递增的。
  2. 假设是follower接收到的写请求,则会转发给leader处理;leader完成两阶段提交的机制。向所有server发起提案,当提案获得超过半数(n+1)的server的ACK后,将对整个集群进行同步,超过半数(n+1)的server同步完成后,该写请求完成。如果client连接的并非同步完成follower,那么得到的并非最新数据,但可以保证单调性,也就是说,可获取的数据顺序是单调递增的。

用分布式系统的CAP原则来分析Zookeeper
(1)C: Zookeeper保证了最终一致性,在十几秒可以Sync到各个节点
(2)A: Zookeeper保证了可用性,数据总是可用的,没有锁.并且有一大半的节点所拥有的数据是最新的,实时的. 如果想保证取得是数据一定是最新的,需要手工调用Sync()
(3)P: 有2点需要分析的

  • 节点多了会导致写数据延时非常大,因为需要多个节点同步.
  • 节点多了Leader选举非常耗时, 就会放大网络的问题. 可以通过引入 observer节点缓解这个问题.

5、 结论

可以的出的结论是Zookeeper的一致性保证的是单调一致性,CAP原则中的C是强一致性。

————————————————

参考:https://blog.csdn.net/chao2016/article/details/81149674

https://www.cnblogs.com/sunddenly/articles/4072987.html

http://www.bailis.org/blog/linearizability-versus-serializability/

原文地址:https://www.cnblogs.com/ibigboy/p/11379418.html

时间: 2024-08-02 02:16:40

分布式系统的一致性级别划分及Zookeeper一致性级别分析的相关文章

ZooKeeper学习第七期---ZooKeeper一致性原理

转:http://www.cnblogs.com/sunddenly/p/4138580.html 一.ZooKeeper 的实现 1.1 ZooKeeper处理单点故障 我们知道可以通过ZooKeeper对分布式系统进行Master选举,来解决分布式系统的单点故障,如图所示. 图 1.1 ZooKeeper解决单点故障 那么我们继续分析一下,ZooKeeper通过Master选举来帮助分布式系统解决单点故障,保证该系统中每时每刻只有一个Master为分布式系统提供服务.也就是说分布式的单点问题

微软内部员工级别划分

Topic 1: Regarding Level In general, a college grad dev or PM will start at 59. 59 and 60 are level 1 (ie, PM) 61 and 62 are level 2 (ie, PM II) 63 and 64 are Senior (ie, Senior PM) 65 through 67 are Principal 68+ are Partner, Director, GM, etc. Titl

基于K-means Clustering聚类算法对电商商户进行级别划分(含Octave仿真)

在从事电商做频道运营时,每到关键时间节点,大促前,季度末等等,我们要做的一件事情就是品牌池打分,更新所有店铺的等级.例如,所以的商户分入SKA,KA,普通店铺,新店铺这4个级别,对于不同级别的商户,会给予不同程度的流量扶持或广告策略.通常来讲,在一定时间段内,评估的维度可以有:UV,收订金额,好评率,销退金额,广告位点击率,转化率,pc端流量.手机端流量.客单价......等n多个维度,那么如何在这n多个维度中找到一种算法,来将我们的品牌划分到4个级别中呢?今天所讨论的K-means聚类算法是其

zookeeper源码分析之一客户端发送请求流程

znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个功能是zookeeper对于应用最重要的特性,通过这个特性可以实现的功能包括配置的集中管理,集群管理,分布式锁等等. 知识准备: zookeeper定义的状态有: Unknown (-1),Disconnected (0),NoSyncConnected (1),SyncConnected (3),AuthFailed (4),ConnectedReadOnly (5),Sasl

程序员级别鉴定书 ----会写代码级别

线程跟进程 一个程序至少有一个进程,一个进程至少有一个线程.线程的划分尺度小于进程,使得多线程程序的并发性高. 进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率. 线程在执行过程中跟进程有区别 线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制 进程具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位. 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.

Zookeeper 源码分析-启动

Zookeeper 源码分析-启动 博客分类: Zookeeper 本文主要介绍了zookeeper启动的过程 运行zkServer.sh start命令可以启动zookeeper.入口的main函数在类中QuorumPeerMain. main函数主要调用了runFromConfig函数,创建了QuorumPeer对象,并且调用了start函数,从而启动了zookeeper. Java代码   public class QuorumPeerMain { protected QuorumPeer

zookeeper源码分析之五服务端(集群leader)处理请求流程

leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcessor -> ProposalRequestProcessor ->CommitProcessor -> Leader.ToBeAppliedRequestProcessor ->FinalRequestProcessor 具体情况可以参看代码: @Override protected v

【PHP自定义显示系统级别的致命错误和用户级别的错误】

使用方法set_error_handler可以自定义用户级别的错误和系统级别的错误信息显示和处理 用户级别的错误使用trigger_error方法产生一个用户级别的错误信息 代码示例: 系统级别的错误: 1 <?php 2 //以下显示系统级别的错误,为语法错误等 3 function my_error($level,$info) 4 { 5 echo "出现了致命错误!<br/>错误级别:".$level."<br/>错误信息:".$

zookeeper源码分析之一服务端处理请求流程

上文: zookeeper源码分析之一服务端启动过程 中,我们介绍了zookeeper服务器的启动过程,其中单机是ZookeeperServer启动,集群使用QuorumPeer启动,那么这次我们分析各自一下消息处理过程: 前文可以看到在 1.在单机情况下NettyServerCnxnFactory中启动ZookeeperServer来处理消息: public synchronized void startup() { if (sessionTracker == null) { createSe