数据一致性: 时间戳策略

本片文章为Lamport关于时间戳文章的翻译,但是又加了一点自己的理解。因此没有将其归为“翻译”一类。并且这也不是问题的关键,重要的是希望能为大家学习提供方便。


        时间戳策略在关系数据库中有广泛的应用,该策略主要用于关系数据库日志系统中记录事务操作,以及数据恢复时的Undo/Redo等操作。在并行系统中,时间戳策略有更加广泛的应用。从较高的层次来说,时间戳策略可用于SNA架构或并行架构系统中的时间、数据的同步。


        在并行数据存储系统或并行数据库中,由于数据时分散存储在不同的节点上的,那么对于不同节点上的数据如何区分它们的版本信息将成为比较繁琐的事情,该问题将涉及到不同节点之间的同步问题。若使用时间戳策略将能够很好地缓解这一境况,例如,我们可以为每一份或一组数据附加一个时间戳标记。在进行数据版本比较或数据同步的时候只需要比较其时间戳就可以区分他们之间的版本。但是分布式系统中不同节点之间的物理时钟可能会有偏差,这样就可能导致交完更新的数据其时间戳却比较晚。因此我们设置一个全局时钟来进行时间同步。当一份数据更新之后,该数据所在节点向全局时钟请求一个时间戳。那么,此时新的问题将出现:1)该全局时钟同步开销过大,影响系统效率;2)该全局时钟出现宕机,整个系统将无法工作。因此,该系统时钟将成为系统效率和可用性的瓶颈。

        使用时间戳的策略将能够很好地解决这一问题。时间戳策略不依赖于任何单个的机器,也不依赖于物理是综合能够。该时间戳为逻辑上的时钟,并且通过时间戳版本的更新可以在系统中生成一个全局有序的逻辑关系。下面我们将简单介绍该策略的核心思想。

1  时间戳

        时间戳最早用于分布式系统中进程之间的控制,用于确定分布式系统中事件的先后关系,可用于协调分布式系统中的资源控制。

我们假设发送或接受消息是进程中的一个事件,下面我们来定义分布式系统事件集中的先后关系,用“→”符号来表示,例如:若事件a发生在事件b之间,那么有a→b。

该关系需要满足下列三个条件:

1) 如果事件a和事件b是同一个进程中的事件,并且a在b之前发生,那么有a→b;

2) 如果事件a是某消息发送方进程中的事件,事件b是该消息接收方进程中接收该消息的事件,那么有a→b;

3) 对于事件a、事件b和事件c,如果有a→b和b→c,那么a→c。

如果两个不同的事件a和事件b,既不能得出a→b也不能得出b→a,那么有事件a和事件b同时发生。

如图1所示,下面我们通过该图说明系统中可能存在的事件先后关系。

数据一致性: 时间戳策略_第1张图片

图1:分布式系统多进程通信

 

在图1中,纵向代表事件轴,虚线表示进程之间的消息通信。在该模型中,如果存在着一个从a到b的时间或消息的先后关系,那么有a→b。

例1:在同一进程P中,事件p2发生在事件p1之后,因此有p1→p2

例2:对于事件q1和时间p3,由于存在从q1到p2的消息传递,因此有q1→p2,同时在同一进程P中,我们知道p2→p3,因此根据该模型,有q1→p3

例3:对于事件p3和事件q3,在逻辑上,我们不能确定p3是否在q3之前发生(只能得出p3在q1之前发生),也不能确定q3是否在p3之前发生(只能得出)q3在p1之前发生。尽管在物理时间上,q3要先于p3发生,但是我们不能确定两事件在该模型下的逻辑关系,因此我们说p3和q3同时发生。

2 逻辑时钟

        现在我们将时钟引入到系统中。这里我们并不关心时钟值是如何产生的,他可以通过本地时钟产生,也可以为有序的数字。这里我们为每一个进程Pi定义一个时钟Ci,该时钟能够为任意一个事件a分配一个时钟值:Ci〈a〉。在全局上,同样存在一个时钟C,对于事件b,该时钟能够分配一个时钟值C〈b〉,并且如果事件b发生在进程i上,那么有 C〈b〉=Ci〈b〉。

我们的系统并不依赖于物理时钟,因为物理时钟可能会出现错误,因此我们要求

时钟条件:如果对于事件a和事件b,有a→b,那么C〈a〉<C〈b〉。

 

但是,事件a的逻辑时钟值小于事件b的逻辑时钟值并不意味着有a->b,因为可能有事件a与事件b同时发生(见例3)。

另外,在图2-X中我们可以得到p2与q3同时发生,p3与q3也同时发生,那么这意味着p2与p3同时发生。但是这与实际情况相违背,因为p2→p3。因此,我们给出下面两个限制条件:

C1:如果事件a和事件b是同一个进程Pi中的事件,并且a在b之前发生,那么有:

Ci〈a〉<Ci〈b〉

 

C2:如果a为进程Pi上某消息发送事件, b为进程Pj上该消息接收事件,那么有:

Ci〈a〉<Ci〈b〉

现在我们可以进一步考虑下“时钟走表”的概念,若事件a发生在事件b之前,有C〈a〉<C〈b〉,例如C〈a〉=4,C〈b〉=7,那么在事件a和事件b之间存在4到5,5到6和6到7三个时间间隔。也就是说存在先后顺序的事件之间一定至少存在至少一个时间间隔。那么C1意味着,同一个进程中的两个事件之间一定存在至少一个时间间隔;C2意味着,每一条消息一定跨越了至少一个时间间隔。

根据以上规则,我们为存在事件间隔的事件或消息之间添加一条灰色的事件线来表示时间间隔的存在,那么图2-X可以转换为图2,如下所示:

数据一致性: 时间戳策略_第2张图片

图2:时间线

3  应用

下面,我们可以假定进程为分布式存储系统或并行数据库系统中的不同节点。下面我们将时钟的概念引入到并行系统中。在系统中,每一个节点i均包含一个时钟Ci,系统中包含两类事件,一种为节点上的数据更新;另一类为节点之间的消息通信(或数据同步)。

下面我们来说明,该系统是如何满足C1和C2条件的。

对于C1条件来说,系统需要满足下面的实现规则:

IR1:对于同一节点上任意的连续事件来说,该节点上的时钟只需要保证较晚发生事件的时钟值要大于较早发生事件的时钟值即可。

对于C2条件来说,当节点发送消息m时,该消息需要同时携带发送时刻的在该节点产生的时间戳。在接收方收到该消息m之后,接收方节点所产生的时间戳要大于消息m所携带的时间戳。但是仅仅如此还是不够的,例如:

假设某节点A向节点B发送消息m,在发送消息时刻节点A的本地事件为:15:33:30,那么该m所携带的时间戳可能为Tm_a=153330。节点B在接收到m后,可能设置该事件的时间戳Tm_b为153400。但是由于机器之间的时间误差,本地时间可能为:15:50:05。并且,在该接收m事件事前15:45:15时刻,节点B上发生数据更新事件,该事件戳为Tm_b=154515。显然,将Tm_b设置为153400将会引起逻辑上的错误。

那么,为了满足C2约束,则需要满足下面的规则:

IR2:(a)如果事件a代表节点Ni发送消息m,那么消息m将携带时间戳Tm,且Tm=Ci〈a〉;(b)当节点Nj接收到消息m后,节点将设置该事件的时钟Cj大于等于该节点上一事件的时钟并且大于等于Tm。

 

该理论为时间戳策略的基本理论,具体的系统和实现要根据当前环境来决定。


参考文献:Leslie Lamport: Time, Clocks, and theOrdering of Events in a Distributed System. Commun. ACM (CACM) 21(7):558-565(1978)

你可能感兴趣的:(c,数据库,存储,分布式存储,存储系统,events)