ITPub博客

首页 > 数据库 > 数据库开发技术 > 分布式原理(6)--混合逻辑时钟

分布式原理(6)--混合逻辑时钟

原创 数据库开发技术 作者:那海蓝蓝 时间:2023-11-28 06:56:00 0 删除 编辑

逻辑时钟可能造成人类从物理视角(物理时间)理解事件/事务顺序的不一致性,而物理时钟虽然符合人的物理视角的一致性,但是不能保证整个分布式系统事件/事务的逻辑的一致性(分区、时延发生)。

混合逻辑时钟(Hybrid Logical Clock,简写为HLC)。混合逻辑时钟着力解决物理时钟和逻辑时钟存在的问题,把两种时钟的优点结合(文献《Logical Physical Clocks and Consistent Snapshots in Globally Distributed Databases》)。

混合逻辑时钟在系统事件时间戳上采用了因果序列和物理时钟的组合,提供了单向的因果序列检测和排序能力(逻辑时钟)。其算法如下:

说明:混合逻辑时钟的一个时间戳使用两个值来表示 l、c。l表示本节点知道的最大物理时钟值(注意不是Wall Clock的值,即不是节点上的实际的物理时间值),c表示l与本地物理时间戳相等的情况下各个节点间的偏序序关系。另外,如下使用pt表示本节点的物理时钟值。c.j的j是节点名,c.j表示j这个物理节点的与其他节点间的具有偏序的时钟值


Initially l.j :=0; c.j:0  //每个节点上的初始值都是零,逐步递增,注意如下类似“c.j+1”赋值Send or local event  //本地发生事件,或本地发送消息给其他节点,则有因偏序系发生,本地时钟递增   l’.j := l.j  //暂存本节点j的已知物理时间戳l的值(来自本地或其他节点,主要是来自远程相关节点,即与本节点发生过偏序关系的节点)   l.j = max(l’.j, pt.j) // pt为物理时钟,获取本地物理时间戳和远程相关节点的物理时钟最大者。本地事件发生,如数据库新开启一个事务,则j节点上的物理时钟值会增长(但注意不是按步长1增长,而是按pt的实际值增长)   if (l.j = l’.j) then c.j := c.j+1  //如果本地物理时间戳和混合时钟中的物理时间戳相等,则使得记载偏序关系的c递增,借以表示相关节点间的偏序关系发生   else c.j = 0 //本地事件发生,则表示某个时间段内节点间的偏序关系没有发生   Timestamp with l.j c.j  //混合时钟包括了l和c Receive event of message m //接收到m节点发来的消息,本地时钟根据情况递增  l’.j := l.j   //暂存本节点的已知物理时间戳  l.j := max(l’.j, l.m, pt.j) // 从本地和消息中选出最大的物理时钟戳  if (l.j = l’.j = l.m) then c.j := max(c.j,c.m)+1 //来自消息的物理时钟戳和本地混合逻辑时钟中的物理时间戳以及本地的物理时间戳相等,则本地逻辑时钟递增,这样就表达了与远程相关节点之间的偏序关系  else if (l.j = l’.j)  then c.j := c.j+1 //物理时钟戳来自本地(本地事件),本地的c递增  else if (l.j = l.m)   then c.j := c.m+1 //物理时钟戳来自消息,本地的逻辑递增,借以表达与远程相关节点之间的偏序关系  else c.j := 0  Timestamp with l.j c.j

如上算法,使得混合逻辑时钟表示物理时钟的值尽量与本地节点的物理时钟保持一致,但是不依赖本地的物理时钟,同时不用担心各个节点的物理时钟值不一致。

该算法如果和NTP结合使用时,不存在NTP 跳变[1]带来的问题。

混合逻辑时钟表示的逻辑时钟值是一个整形绝对递增值。与Spanner系统的TrueTime机制相比,不存在TrueTime的overlap问题,使得单位时间内可提供的时间戳值增多,这意味着逻辑上提高了事件间的并发度。

如图1,形象地表示了混合逻辑时钟的算法。四个节点分别用0、1、2、3表示,各个节点上,用三元组表示本地物理时钟(pt,第一个)和混合逻辑时钟(l和c,第二、三个),实线箭头表示两个节点间发生了Send和Receive事件,同一个节点上多个三元组相连表示本地事件发生。从节点0到节点1,传递的消息{l,c}的值是{10,0};节点1的pt时间值由0变更为1(节点1的物理时间不受节点0的物理时间影响,这点对于实现去中心化的分布式算法有帮助),节点1的物理时间1小于来自消息的物理时间10,则节点1的c值变为10,然后满足算法中Receive阶段的“else if (l.j = l.m) then c.j := c.m + 1”而使得c值为1所以三元组表示为了{1,10,1};之后本地事件发生,满足算法中的Send阶段的“if (l.j = l’.j) then c.j := c.j+1”,节点1的三元组变为{2,10,2};在节点3的箭头指向节点1之前,节点1本地事件发生,二元组{3,13}实则是三元组{3,13,2}的简写,节点1收到消息,依据算法中Receive阶段的“else if (l.j = l.m) then c.j := c.m + 1”而使得c值为1所以三元组表示为了{4,10,7}。所以,从逻辑关系看,发生在四个节点间的偏序关系,全部用c表达,其值从初始的0开始变为了1和2(节点1)、3和4(节点2)、5和6(节点3)、7(节点1)。

如图1,粗黑色的线沿着逻辑时钟c值为0从节点0到节点1,一直到节点3,三元组的变化分别为:节点0{10,10,0}、节点1{0,0,0}、节点2{1,1,0}、节点3{2,2,0},这表明在这样的一个状态下,四个节点处于一致的状态。即混合逻辑时钟可以获取一致性的一个点,这是本算法的主要用法(根据全局快照点,找出处于一致性状态的数据,但全局快照点的建立,需要一个全局的逻辑时钟保证全局一致性)。但是,对于节点3而言,节点0{10,10,0}、节点1{0,0,0}、节点2{1,1,0}、节点3{1,1,0}也是处于一个一致状态,所以处于一致的状态,可能存在多个。需要注意的是,混合逻辑时钟的本质还是逻辑时钟,是一个分布式的去中心化的逻辑时钟,其同3.2节的逻辑时钟在构建一致性快照方面的作用是相通的。

图1 混合逻辑时钟示意图


混合逻辑时钟,解决了分布式系统内部的事件之间偏序排序的问题,但是,从系统外部的角度看(应用层面),依然不能满足全局一致性,此点对于逻辑时钟、向量时钟、混合逻辑时钟等谈及的技术都不能避免。例如,同一个用户从2个不同的物理节点上执行了2个不同的事务,这2个事务因是同一个用户从同一个应用发出所以存在偏序顺序,但是第二个事务所在的节点的逻辑时间,有可能早于第一个事务所在的逻辑时间(2个节点之间没有Send和Receive事件发生没有建立偏序关系),从逻辑时间戳的角度看第二个事务先于第一个事务发生,这样就产生了不一致。

在分布式事务型数据库中,混合逻辑时钟通常和MVCC技术结合,用于建立全局快照,解决读操作的全局一致性问题。

[1] 跳变是指在client和server间时间差过大时(server是NTP服务器),瞬间调整client端的系统时间,这样可能导致被调整的client的时间值相比旧值变小产生“回退”现象。



扫码加关注,知数行云,专业有深度


声明:本文禁止用于开发“任何软件程序,包括但不限于训练机器学习或人工智能(AI)系统”。


原文作者:那海蓝蓝知数行云;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2023-09-02

  • 博文量
    52
  • 访问量
    31004