现实生活中时间是很重要的概念,时间可以记录事情发生的时刻、比较事情发生的先后顺序。分布式系统的一些场景也需要记录和比较不同节点间事件发生的顺序,但不同于日常生活使用物理时钟记录时间,分布式系统使用逻辑时钟记录事件顺序关系,下面我们来看分布式系统中几种常见的逻辑时钟。

物理时钟 vs 逻辑时钟

可能有人会问,为什么分布式系统不使用物理时钟(physical clock)记录事件?每个事件对应打上一个时间戳,当需要比较顺序的时候比较相应时间戳就好了。

这是因为现实生活中物理时间有统一的标准,而分布式系统中每个节点记录的时间并不一样,即使设置了 NTP 时间同步节点间也存在毫秒级别的偏差。因而分布式系统需要有另外的方法记录事件顺序关系,这就是逻辑时钟(logical clock)。

Lamport timestamps

Leslie Lamport 在1978年提出逻辑时钟的概念,并描述了一种逻辑时钟的表示方法,这个方法被称为Lamport时间戳(Lamport timestamps)。

分布式系统中按是否存在节点交互可分为三类事件,一类发生于节点内部,二是发送事件,三是接收事件。Lamport时间戳原理如下:

图1: Lamport timestamps space time (图片来源: wikipedia)

每个事件对应一个Lamport时间戳,初始值为0 如果事件在节点内发生,时间戳加1 如果事件属于发送事件,时间戳加1并在消息中带上该时间戳 如果事件属于接收事件,时间戳 = Max(本地时间戳,消息中的时间戳) + 1

假设有事件a、b,C(a)、C(b)分别表示事件a、b对应的Lamport时间戳,如果C(a) < C(b),则有a发生在b之前(happened before),记作 a -> b,例如图1中有 C1 -> B1。通过该定义,事件集中Lamport时间戳不等的事件可进行比较,我们获得事件的偏序关系(partial order)。

如果C(a) = C(b),那a、b事件的顺序又是怎样的?假设a、b分别在节点P、Q上发生,Pi、Qj分别表示我们给P、Q的编号,如果 C(a) = C(b) 并且 Pi < Qj,同样定义为a发生在b之前,记作 a => b。假如我们对图1的A、B、C分别编号Ai = 1、Bj = 2、Ck = 3,因 C(B4) = C(C3) 并且 Bj < Ck,则 B4 => C3。

通过以上定义,我们可以对所有事件排序、获得事件的全序关系(total order)。上图例子,我们可以从C1到A4进行排序。

Vector clock

Lamport时间戳帮助我们得到事件顺序关系,但还有一种顺序关系不能用Lamport时间戳很好地表示出来,那就是同时发生关系(concurrent)。例如图1中事件B4和事件C3没有因果关系,属于同时发生事件,但Lamport时间戳定义两者有先后顺序。

Vector clock是在Lamport时间戳基础上演进的另一种逻辑时钟方法,它通过vector结构不但记录本节点的Lamport时间戳,同时也记录了其他节点的Lamport时间戳。Vector clock的原理与Lamport时间戳类似,使用图例如下:

图2: Vector clock space time (图片来源: wikipedia)

假设有事件a、b分别在节点P、Q上发生,Vector clock分别为Ta、Tb,如果 Tb[Q] > Ta[Q] 并且 Tb[P] >= Ta[P],则a发生于b之前,记作 a -> b。到目前为止还和Lamport时间戳差别不大,那Vector clock怎么判别同时发生关系呢?

如果 Tb[Q] > Ta[Q] 并且 Tb[P] < Ta[P],则认为a、b同时发生,记作 a <-> b。例如图2中节点B上的第4个事件 (A:2,B:4,C:1) 与节点C上的第2个事件 (B:3,C:2) 没有因果关系、属于同时发生事件。

Version vector

基于Vector clock我们可以获得任意两个事件的顺序关系,结果或为先后顺序或为同时发生,识别事件顺序在工程实践中有很重要的引申应用,最常见的应用是发现数据冲突(detect conflict)。

分布式系统中数据一般存在多个副本(replication),多个副本可能被同时更新,这会引起副本间数据不一致,Version vector的实现与Vector clock非常类似[8],目的用于发现数据冲突。下面通过一个例子说明Version vector的用法:

图3: Version vector

  • client端写入数据,该请求被Sx处理并创建相应的vector ([Sx, 1]),记为数据D1
  • 第2次请求也被Sx处理,数据修改为D2,vector修改为([Sx, 2])
  • 第3、第4次请求分别被Sy、Sz处理,client端先读取到D2,然后D3、D4被写入Sy、Sz
  • 第5次更新时client端读取到D2、D3和D4 3个数据版本,通过类似Vector clock判断同时发生关系的方法可判断D3、D4存在数据冲突,最终通过一定方法解决数据冲突并写入D5

Vector clock只用于发现数据冲突,不能解决数据冲突。如何解决数据冲突因场景而异,具体方法有以最后更新为准(last write win),或将冲突的数据交给client由client端决定如何处理,或通过quorum决议事先避免数据冲突的情况发生。

由于记录了所有数据在所有节点上的逻辑时钟信息,Vector clock和Version vector在实际应用中可能面临的一个问题是vector过大,用于数据管理的元数据(meta data)甚至大于数据本身。

解决该问题的方法是使用server id取代client id创建vector (因为server的数量相对client稳定),或设定最大的size、如果超过该size值则淘汰最旧的vector信息。

小结

以上介绍了分布式系统里逻辑时钟的表示方法,通过Lamport timestamps可以建立事件的全序关系,通过Vector clock可以比较任意两个事件的顺序关系并且能表示无因果关系的事件,将Vector clock的方法用于发现数据版本冲突,于是有了Version vector。

参考资料:

[1] Time is an illusion, George Neville-Neil, 2016

[2] There is No Now, Justin Sheehy, 2015

[3] Time, Clocks, and the Ordering of Events in a Distributed System, Leslie Lamport, 1978

[4] Timestamps in Message-Passing Systems That Preserve the Partial Ordering, Colin J. Fidge, 1988

[5] Virtual Time and Global States of Distributed Systems, Friedemann Mattern, 1988

[6] Why Vector Clocks are Easy, Bryan Fink, 2010

[7] Conflict Management, CouchDB

[8] Version Vectors are not Vector Clocks, Carlos Baquero, 2011

[9] Detection of Mutual Inconsistency in Distributed Systems, IEEE Transactions on Software Engineering , 1983

[10] Dynamo: Amazon’s Highly Available Key-value Store, Amazon, 2007

[11] Conflict Resolution, Jeff Darcy , 2010

[12] Why Vector Clocks Are Hard, Justin Sheehy, 2010

[13] Causality Is Expensive (and What To Do About It), Peter Bailis ,2014

c++ 获取时间戳_分布式系统理论基础三-时间、时钟和事件顺序相关推荐

  1. mysql获取时间戳_服了!阿里Mysql三位封神专家总结1200多页性能优化的千金良方...

    MYSQL(关系型数据库管理系统) MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品.MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应 ...

  2. c++获取时间戳_时间简史

    好吧,我承认这篇文章有点标题党,本文内容与霍金同学同名书无任何相关,而是一篇不折不扣的关于时间和计算机程序的"时间简史".时间是什么?数学家说时间是第四维度,不过显然计算机不这么看 ...

  3. java获取时间戳(计算两个时间相差几天几小时几秒,获取当前日期是周几。。。)

    java时间相关 博主所有博客都是验证过的 获取一个时间的时间戳 //获取当前时间戳Calendar cal1 = Calendar.getInstance();cal1.setTime(new Da ...

  4. c++获取时间戳_「崩坏3」众星陨落 | 限时补给开启,4星装备获取概率UP

    11月6日12:00,神之键限时补给通道--「众星陨落」特别补给即将开启! 在「众星陨落」特别补给中,获得★4装备的整体概率将会提升. 本期UP的武器为4★双枪武器「伊甸双星」和4★大剑武器「睡美人」 ...

  5. python 获取年份_如何从Pythondate时间对象中提取年份?

    这个问题的其他答案似乎打上了现场. 现在你怎样才能知道自己没有堆栈溢出? 查看IPython ,这是一个具有标签自动完成function的交互式Python shell. > ipython i ...

  6. 触发事件_黑暗的三天之触发事件

    作者:Elizabeth Marie 翻译:地狱天堂你决定 我非常犹豫来释放这些信息,因为现在,在网络上,有如此多关于黑暗的三天的信息.但是,我也一直在领受关于这个事件的信息,因此,我会忠实,并分享它 ...

  7. 分布式系统:时间、时钟和事件序列

    在程序中,我们经常需要知道事件序列,在单体应用中,事件序列是较为简单的,最简单的办法就是用时间戳,但在分布式系统中,事件序列是很困难的,Leslie Lamport大神在论文Time, Clocks, ...

  8. java unix 时间戳_「unix时间戳」Unix时间戳和Java中的时间戳的区别 - seo实验室

    unix时间戳 前言 最近在使用阿里的日志服务时,遇到了一些Timestamp的坑,所以特意做了了解并整理了一下.在这之前首先得介绍一下Unix时间戳:unix时间戳是从1970年1月1日(UTC/G ...

  9. java 当前时间戳_通过各种方法 获取当前系统时间、时间戳

    php中,如何通过各种方法 获取当前系统时间.时间戳,并备注各种格式的含义,可灵活变通. 1.获取当前时间方法date() 很简单,这就是获取时间的方法,格式为:date($format, $time ...

最新文章

  1. 阻止button刷新页面
  2. HTML5 Canvas 自定义笔刷
  3. java常用类总结_java——常用类的总结
  4. day05 数据类型
  5. 用梯度下降求解最小二乘线性回归python实现
  6. 安装rational rose软件教程
  7. 开源免费CRM云端的客户管理系统SuiteCRM简介(视频)
  8. 学c语言学生智商要搞么,作为一个学渣,哥来告诉你如果你智商不够该怎么办...
  9. Faulty Robot-(dfs或者dijkstra)
  10. 叶俊在深圳天长地久集团培训会上谈到“唤醒沟通力与工匠精神”
  11. html5自动淡入淡出图片,利用html5实现图片的淡入淡出效果
  12. 模电_数电_微机接口_微机应用实验装置,QY-MS535F
  13. python爬wos数据库,分布式爬虫困惑,如何合理安排抓取/解析/储存?
  14. Keras: 创建多个输入以及混合数据输入的神经网络模型
  15. nt6安装win7:发现系统安装文件,但该分区不支持本安装模式
  16. 60进制计数器的设计
  17. 设置pdf为护眼绿色
  18. 基于Metronic的Bootstrap开发框架经验总结(1)-框架总览及菜单模块的处理
  19. 在阿里云服务器上搭建 SVN 服务端
  20. 图像处理:像素间的一些基本关系(领域、领接性、通路、连通分量、距离)

热门文章

  1. restful api接口规范_如何理解RESTful API设计规范?
  2. linux启动过程及内核裁剪,裁剪测试Linux启动流程
  3. 富文本框让最大四百像素_Django2.0.4 结合 KindEditor 4.1.11 富文本编辑器
  4. java f反射_java反射机制
  5. web实现远程桌面:Apache Guacamole
  6. php linux下保存文件路径怎么写,linux下php导入带图片的word文档转为html,图片保存下来生成路径。...
  7. html美化计算机,职称计算机Dreamwaver教程:CSS样式表滤镜
  8. ?php query_posts(cat)?,query_posts()函数 (wordpress日志调用)
  9. bar图设置距离 python_python画图设置坐标轴的位置及角度及设置colorbar
  10. python ui自动化_pythonUI自动化整理