任意read(x)操作都要读到最新的write(x)的结果。
依赖于绝对的全局时钟,实际系统不可能做到。
1.2 顺序一致性(Sequetial
Consistency)
要求:
对于一些读写写操作的集合,所有进程看到的都是同样的顺序。也就是将并行的操作序列化,而且每个进程得到的序列都相同。
那么,很自然对于同一个进程执行的操作,必然要按照它们执行的顺序出现。
比严格一致性去掉了全局时钟。
1.2
可线性化(Linearizability)
要求:
在顺序一致性的基础上,加上序列化后的操作必须与它们的时间戳一致。也就是不单要变成一个序列,而且如果序列中op1->op2,那么要有ts(op1)<ts(op2)
做到可线性化需要与时间戳同步,所以开销大。因而只是用于程序的形式化验证。
1.3 因果一致性(Casual
Consitency)
要求:
有因果关系的写操作必须按照它们的因果关系的顺序被看到,没有因果关系的写操作可以以任意顺序被别的进程看到。
例如:
进程1 W(x)a 将x写成a
进程2
R(x)a W(x)b
进程3
R(x)a R(x)b
进程4
R(x)b R(x)a
进程3和1、2是满足因果一致性的,加上4就不满足了。因为进程2是由于读到x=a才把x写成b的,所以W(x)a和W(x)b之间有因果关系,必须按照因果的顺序出现。
相比顺序一致性,去掉了那些没有联系的操作达成一致顺序观点的要求,只是保留那些必要的顺序(有因果关系的)。
1.4 先进先出一致性(FIFO
Consistency)
要求:
同一个进程的写操作必须以同样的顺序被别的进程看到,不同进程的写操作可以以任意顺序被看到。
比起因果一致性,不同进程的操作顺序都不管了,只要同一个进程的操作顺序保证就行了。
使用同步变量的———————————————————————————————————————————
1.5 弱一致性(Weak
Consistency)
直观上就是定义一个同步变量以实现一致性。
要求:
1
同步变量的操作要满足顺序一致性。
2
对于同步变量,在别的所有地方的写操作完成之前不允许做任何操作。
3
同步变量的操作是阻塞的,所以在它完成之前同一过程对别的数据的读写都不能进行。
注:这里与其他进程进行协调的其实就在对同步变量的操作,在这个操作中,首先要把别人的更新(如果有的话)传播到自己的数据上,另外就是如果自己写了数
据,还要通知别人数据已经更新。这样,当前进程多于共享数据的操作可以看作是在执行同步操作(也就是书中的S)时一起进行的。原因是如果没有进行同步,前
面所有的操作对于其他的进程都是不可见的,别的进程执行同步的时候也不会得知这些更新。那么,所有进程各自的写操作都可以看作是在执行同步的时候进行的,
那么同步操作就可以看作一个互斥的临界区,修改都在这个地方产生作用。
总结:其实跟上锁的道理是一样的,只是这里用了个同步操作,看不到上锁和解锁,但是因为所有的操作到了同步操作的时候才产生作用,而同步变量又要互斥操作,那么这个只是一个变了样子的锁罢了。
1.6 释放一致性(Release
Consitency)
其实就是构造一个临界区,用类似上锁的机制对数据进行访问。如果不进行同步(不先获得这把锁),那么读到什么结果是不保证的。
要求:
在读写共享数据之前要先获得锁,而在别的已经获得的锁没有释放之前,这个请求不被满足。(锁互斥)
在释放锁之前,进程对于读写共享数据的操作必须已经完成。(同步)
对同步变量(也就是锁)的操作必须满足FIFO一致性。
1.7 入口一致性(Entry
Consistency)
其实也就是对每个共享数据定义一个同步变量(即:锁)。当然,没有进行同步就进行的读操作结果是不保证的。
2 客户为中心的一致性
也就是从用户视角来看数据是一致的。只是关心数据最终会一致(eventually
consitent)。
只要保证对于同一个用户,他访问到的数据是一致的就可以了。如果用户只是访问一个副本,这个就很好实现,否则就需要一定策略了。当没有更多的更新的时候,要保证当前的更新会最终传播到所有的副本上。
也有下面几种一致性条件。
2.1 单调读(Monotonic
Reads)
当进程从一个地方读出数据x,那么这个以后再读到的x应该是和当前x相同或比当前更新的版本。也就是如果进程迁移到了别的位置,那么对x的更新应该比进程先到达。这里的客户就是指这个进程。
2.2 单调写(Monotonic
Writes)
跟单调读相应,如果一个进程写一个数据x,那么它在本地或者迁移到别的地方再进行写操作的时候,原来的写操作必须要先传播到这个位置。也就是进程要在任何地方至少和上一次写一样新的数据。
2.3 Read your
writes
一个进程对于数据x的写操作,那么进程无论到任何副本上都应该看到这个写操作的影响,也就是看到和自己写操作的影响或者更新的值。
2.4 Writes follow
reads
顾名思义了,也就是在读操作后面的写操作要是基于至少跟上一次读出来一样新的值。也就是如果进程在地点1读了x,那么在地点2要写x的副本的话,至少写的时候应该是基于至少和地点1读出的一样新的值。
3 副本放置(Replica
Placement)
3.1
放置的三个方法
永久副本(Permanent replica)
也就是选几个固定位置放置副本,或者说做镜像
服务端发起(Server-initiated)
也就是服务端决定什么时候向什么地方分发副本,或者push cache
客户端发起(Client-initiated) 也就是客户端缓存(client
cache)
3.2 更新传播
a
传播什么?
可以是更新的通知(客户自己来取)
可以是更新后的数据
可以是更新的操作
b
谁来传播
服务器push或客户pull
c
传播协议?
保证最终会收敛到一致
3.3 复制协议(Replication
Protocols)
3.3.1
远程写(Remote-Write)协议
对于数据x有一个主副本,当没有x副本的服务器操作x的时候就会得到一个x的副本。而有x副本的服务器响应客户读请求的时候可以立刻返回。而当客户进行写操作的时候,写操作首先在主副本完成,然后再通知其他副本更新。
3.3.2
本地写(Local-Write)协议
和远程写比较类似,不同点是当一个服务器得到了副本以后就成了新的主副本,以后的写操作首先在本地完成,然后再通知其他的副本,本地写的名字由此而来。
3.3.3
主动复制(Active Replication)
对于副本的操作要设计到另外一个单一对象。比如,n个副本代理对象C的一个接口,如果向所有副本发出请求,每个副本都会发一个请求到C,那么同样的操作就
执行了n次。所以需要一个协调者。另外,多副本返回值的时候也会有同样的情况。所以这种只执行一次的动作需要副本种有一个协调者,保证操作只被执行一次或
者只返回一次。
3.3.4
基于候选团(Quorum-Based)协议
也就是读操作要得到Vr个服务器的同意,写操作要得到Vw个进程的同意。总共有V个进程。Vr和Vw要满足以下条件:
Vr+Vw >
V
这样就不可能同时发生读写,并且读到的server肯定有一个以上被更新过的
Vw >
V/2
这样就不可能同时发生两个写
也就是类似于投票获得读写的锁。另外就是雀巢原理保证总会看到最新的版本。
3.4
ROWA(Read-one-write-all)
顾名思义,也就是读的时候只要读任意一个副本,写的时候同时写所有的副本。
写也有两种情况:
1
客户只写一个(主)副本,这个副本通知所有的其他副本
2
客户同时写所有的副本
3.5 Orca
参考文献:
Andrew S.
Tanenbaum and Maarten van Steen, Distributed Systems: Principles
and Paradigms, Prentice Hall 2002
转自: http://blog.sina.com.cn/s/blog_4b99f86c0100074c.html
分布式复制和一致性(consistency and replication)
为什么复制? 可靠(防止单点失效)、性能
为什么不复制?
复制透明性不能保证、一致性问题(更新、availablity)
结构:
外部看起来是一个单一的逻辑对象,而操作会转化成对各个实际的物理对象的操作。
1
以数据为中心的一致性模型
Data-Centric Consistency Models
物理上看起来像是一个单一的数据对象,实际上每个进程都有一个自己的副本。
不使用同步变量的—————————————————————————————————————————
1.1 严格一致性(Strictly
Consistency)
2120

被折叠的 条评论
为什么被折叠?



