Time,Clocks,and the Ordering of Events in a Distributed System 读书笔记及个人见解

本贴最后更新于 3093 天前,其中的信息可能已经物是人非
论文在此: "Time, Clocks and the Ordering of Events in a Distributed System" 
 
1、分布式环境中 事件的 偏序关系 happens before 的介绍
 
实际上 时间 是一件难以把握的事情,不知道 你们有没有感觉,在引入业务时间约束的分布式系统里,处理时间是一件特别头疼的事情,因为不同机器的时间是不一定一致的。
而且,我们根本无法精确衡量时间,我们制作出来的钟表,必然在行进过程中存在误差,因此我们定义 happens before 关系的时候,应该要排除掉物理的时钟。
 
happens before 关系本质上是 因果关系,在lamport的设定里,happens before关系具现化如下:
 
happens before 用符号 → 表示,其代表 
1、如果事件a,b都在同一个进程内,如果 代码执行顺序中 a 在 b 之前,那么 a →b
2、进程间可以通过收发信息进行通讯,进程x发信息事件为a,进程y收信息事件为b,那么a->b
3、如果a→b,b→c那么a→c
 
如果 a,b是两个不同的事件,且 a !→ b,b !→ a,那么我们就称a,b是并发的。(超级赞的定义!!!)
 
 
2、一个逻辑时钟算法
时钟可以抽象成 为发生的事件 进行编码的工具,编码 代表 该时间发生的时间。
我们定义C为全局逻辑时钟,一个合理的逻辑时钟产生的 编码 符合以下条件即可:
if a->b then  C(a)<C(b)
 
约束条件很简单,那么对于两个并发的事件a,b,可以设定成 C(a)>C(b),也可以设定成C(b)<C(a),并没有关系,开心就好
 
既然约束条件简单,那么看一下lamport设定的 happens before 关系,可以推出一个逻辑时钟算法如下:
 
我们定义 Ci 为 进程Pi 的时钟,Ci(a)表示 Ci 为事件 a 进行的编码
1.每个进程Pi在任意连续的两个事件之间会增加Ci的值
2.(a)如果事件a代表了进程Pi发送消息m的事件,那么消息m包含的时间戳Tm=Ci(a).
  (b)在收到消息m后,进程Pj会设置Cj的值使得它大于等于它的当前值并大于Tm.
 
 
3、事件严格全序排列算法
有了上述的逻辑时钟算法,我们就可以为所有的事件进行编码,从而得到关于逻辑时间的全序关系
但是上述的算法有可能为不同的进程的并发事件分配同一个时间编码,为了去除这种情况,得到一个关于逻辑事件 的严格的全序关系,lamport给出了以下的算法设定
 
define a relation => as follows: 
if a is an event in process Pi and b is an event in process Pj, then a => b if and only if either (1) Ci(a) < Cj(b) or (2) Ci(a) = Cj(b) and Pi 《 Pj.      (“《”指代啊 进程间任意定义的一个全序关系,例如 进程的编号 )
 
这样 =>就是一个 进程的事件间 严格全序关系。因为逻辑时钟的实现不唯一,因此 这种全序关系 也可以有很多个,只有偏序关系是唯一的。(PAXOS算法也用了这中全序编码算法)
 
那得到这么一个全序关系有什么用?Lamport给我们举了个栗子
 
假设需要一个分布式锁的服务,满足以下需求,
(I) A process which has been granted the resource must release it before it can be granted to another process.拿到锁的进程,在释放锁之前,其他进程都不能获得锁
(II) Different requests for the resource must be granted in the order in which they are made. 获得锁的顺序必须跟锁请求发起的顺序一致。(*而不是接收到请求的顺序)
(III) If every process which is granted the resource eventually releases it, then every request is eventually granted. 如果获得锁的进程最终都都会释放锁的话,那么每一个 锁请求 最终都会请求成功
 
lamport给出了这么一个依赖于 事件全序关系 的算法(这个算法中默认 发送的消息是 按发送的顺序接收到的,且最终一定会接收到的,但这个实现并没在算法中体现,要实现的话,发送序号+ACK就能实现),满足上述需求:
1. To request the resource, process Pi sends the message Tm:Pi requests resource to every other process, and puts that message on its request queue, where Tm is the timestamp of the message. 
2. When process Pj receives the message Tm:Pi requests resource, it places it on its request queue and sends a (timestamped) acknowledgment message to Pi. 
3. To release the resource, process Pi removes any Tm:Pi requests resource message from its request queue and sends a (timestamped) Pi releases resource message to every other process. 
4. When process Pj receives a Pi releases resource message, it removes any Tm:Pi requests resource message from its request queue. . Process Pi is granted the resource when the following two conditions are satisfied: 
   (i) There is a Tm:Pi requests resource message in its request queue which is ordered before any other request in its queue by the relation =>. (To define the relation "=>" for messages, we identify a message with the event of sending it.)
   (ii) Pi has received a message from every other process timestamped later than Tm. 
 Note that conditions (i) and (ii) of rule 5 are tested locally by Pi. 
 
一大串鸡肠,表达的意思实际上是,
1、每个 进程都会保存一个队列,这个队列用于存储自己或者其他进程的锁获取请求,这些请求是按照 全序关系=>排列的。
2、一个进程 Pi 如果他自己的 获取锁请求,Tm:Pi排在最前面,且接收到了其他所有进程的大于 Tm的消息后,那么 进程自身就能认为 自己获得了锁。因为 收到消息的顺序跟发送消息的顺序是一致的,因此收到了其他所有进程大于Tm的消息后,Pi已经收集齐了所有时间小于 Tm的 事件,发现自己的请求Tm:Pi资源请求依然是最小的话,那么,自己必然是 锁 的拥有者。显然,这就满足了 需求(II)
3、释放锁的请求由 资源获得者 Pi发起,发起之后,其余进程才能将各自队列中Pi对应的锁请求消除,因此必然能保证需求(I)
4、因为锁释放的消息最终都传到各个进程中,因此(III)也能满足
 
因此本算法是可以达到指定目标的,但本算法在某个进程宕机时,就无法跑下去了╭(╯^╰)╮
 
 
4、关于逻辑时钟算法的一些异常
 
假设存在一个用上述逻辑时钟保证报名顺序的报名系统中,张三 在系统中报名了后,打电话给 李四,让李四也去系统中报名 这样的话,李四的报名是有可能早于张三的。
因为 打电话这个行为 是在逻辑时钟的系统之外,系统没办法获得   张三报名->打电话,打电话->李四报名 这个信息,因此张三报名和李四报名 在报名系统中,是并发的。
 
要怎么解决这个问题?有两种方法:
1、将打电话这个操作的信息保存到系统中,就是说建立 上面提到的->关系
2、实现一个 强逻辑时钟算法,满足以下条件:在软件系统中的两个事件 a,b,如果 a,b在真实时钟里存在 happens before关系(用-->表示),那么C(a)<C(b)
 
然后Lamport说:
One of the mysteries of the universe is that it is possible to construct a system of physical clocks which, running quite independently of one another, will satisfy the Strong Clock Condition. 
(我们可以构造 多个相互独立运行的物理时钟系统,并让他们协调合作构成一个整体的 符合 强逻辑时钟 的 分布式时钟算法系统)
 
 
5、物理时钟(以下为直接摘抄译文,自己看文章理解的不太好)
 
有效的物理时钟应该有以下特性:
PC1、对于所有的t,dCi(t)/dt≈1,也就是说 存在一个常数k,对于所有的i:| dCi(t)/dt -1|<k
PC2、对于所有的i,j:| Ci(t)-Cj(t)|<e.   e为一个足够小的常数。
 
两个不同的时钟永远都不会以相同的速率走动,这意味着它们之间的偏差会越来越大。因此我们必须要设计一种算法来保证PC2总是成立。但是,首先我们来看一下k和e要多小才能避免异常行为。
 
令u表示满足如下条件的值:如果事件a发生在物理时间t,同时b是发生在另一个进程中的满足a->b事件,那么b肯定发生在物理时间t+u之后。
换句话说,u需要小于进程间消息传输的最短时间。我们可以用进程间的距离除以光速的值作为u的值。(信息传播最快的速度为光速,视乎信息传播形式,传播速度可能远慢于光速)
 
为避免异常行为,我们必须保证对于任意i,j,t:Ci(t+u)-Cj(t)>0
 
现在由上述三条公式推导出 e,k,u的关系:
由 Ci(t+u)-Cj(t)>0 得  Ci(t+u) -Ci(t) + Ci(t)  - Cj(t) > 0 ,  Ci(t+u) -Ci(t)  > -Ci(t)  + Cj(t) .
由 | Ci(t)-Cj(t)|<e 得,-Ci(t)  + Cj(t) 的最大值为 e,因此  Ci(t+u) -Ci(t)  >= e
由| dCi(t)/dt -1|<k, 因此 1+k > dCi(t)/dt > 1-k,--》 Ci(t+u) -Ci(t) > (1-k)(t+u-t)   -->  Ci(t+u) -Ci(t) > (1-k)u 
由 Ci(t+u) -Ci(t) > (1-k)u,说明Ci(t+u) -Ci(t)的最小值可能为(1-k)u, 为了保证Ci(t+u) -Ci(t)  >= e成立, (1-k)u >=e 即可
 
推导的这个公式(1-k)u >=e 可以理解为,最小的信息传达的时间,要大于误差时间。
 
PC1这个条件由我们物理时钟的实现技术保证,典型的由晶体控制的时钟来说,k<=10^-6
 
我们来看看保证PC2实现的算法,即一个物理时钟同步算法
 
证明实在看不下去了,以后有空再回顾一下,说一下结论:
THEOREM.假设一个半径为d的由多个进程组成的强连通图始终满足规则IR1’和IR2’。同时对于任意消息 m,Um<=某常数U,以及任意时刻t>=t0来说:(a)PC1成立.(b)存在常数τ和ε,每τ秒都会有一个消息在不可预测的延迟部分小 于ε的情况下在每条边上传送。那么PC2就能被满足,同时对于所有的t>t0+τd,e≈d(2kτ+ε),这里我们假设 U+ε<<τ。
 
IR1’.对于每个i,如果Pi在物理时间t未收到消息,那么Ci是在时间t就是可微分的并且dCi(t)/dt>0.

IR2’. (a)如果Pi在物理时间t发送了一个消息m,那么m将包含一个时间戳Tm=Ci(t).(b)当在时间t’接收到消息m时,进程Pj将设置Cj(t’) 等于max(Cj(t’-0),Tm+Um).(注:Cj(t’-0)=[limCj(t’-|&|),&->0])

 
m表示一个在物理时间t发送和时间t’被接收的消息。我们定义Vm=t’-t来表示消息m的总延迟。当然,接收消息m 的进程并不知道该延迟。但是我们假设接收进程知道某个最小延迟取值Um>=0,并且Um<=Vm。我们称Em=Vm-Um为消息的不可预测的 延迟部分。
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • Vim

    Vim 是类 UNIX 系统文本编辑器 Vi 的加强版本,加入了更多特性来帮助编辑源代码。Vim 的部分增强功能包括文件比较(vimdiff)、语法高亮、全面的帮助系统、本地脚本(Vimscript)和便于选择的可视化模式。

    29 引用 • 66 回帖
  • BND

    BND(Baidu Netdisk Downloader)是一款图形界面的百度网盘不限速下载器,支持 Windows、Linux 和 Mac,详细介绍请看这里

    107 引用 • 1281 回帖 • 35 关注
  • 服务

    提供一个服务绝不仅仅是简单的把硬件和软件累加在一起,它包括了服务的可靠性、服务的标准化、以及对服务的监控、维护、技术支持等。

    41 引用 • 24 回帖 • 3 关注
  • 工具

    子曰:“工欲善其事,必先利其器。”

    298 引用 • 763 回帖 • 1 关注
  • Facebook

    Facebook 是一个联系朋友的社交工具。大家可以通过它和朋友、同事、同学以及周围的人保持互动交流,分享无限上传的图片,发布链接和视频,更可以增进对朋友的了解。

    4 引用 • 15 回帖 • 441 关注
  • 微服务

    微服务架构是一种架构模式,它提倡将单一应用划分成一组小的服务。服务之间互相协调,互相配合,为用户提供最终价值。每个服务运行在独立的进程中。服务于服务之间才用轻量级的通信机制互相沟通。每个服务都围绕着具体业务构建,能够被独立的部署。

    96 引用 • 155 回帖 • 1 关注
  • 锤子科技

    锤子科技(Smartisan)成立于 2012 年 5 月,是一家制造移动互联网终端设备的公司,公司的使命是用完美主义的工匠精神,打造用户体验一流的数码消费类产品(智能手机为主),改善人们的生活质量。

    4 引用 • 31 回帖 • 9 关注
  • OpenStack

    OpenStack 是一个云操作系统,通过数据中心可控制大型的计算、存储、网络等资源池。所有的管理通过前端界面管理员就可以完成,同样也可以通过 Web 接口让最终用户部署资源。

    10 引用 • 5 关注
  • MySQL

    MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 是最流行的关系型数据库管理系统之一。

    693 引用 • 537 回帖
  • 运维

    互联网运维工作,以服务为中心,以稳定、安全、高效为三个基本点,确保公司的互联网业务能够 7×24 小时为用户提供高质量的服务。

    151 引用 • 257 回帖
  • Tomcat

    Tomcat 最早是由 Sun Microsystems 开发的一个 Servlet 容器,在 1999 年被捐献给 ASF(Apache Software Foundation),隶属于 Jakarta 项目,现在已经独立为一个顶级项目。Tomcat 主要实现了 JavaEE 中的 Servlet、JSP 规范,同时也提供 HTTP 服务,是市场上非常流行的 Java Web 容器。

    162 引用 • 529 回帖 • 6 关注
  • Firefox

    Mozilla Firefox 中文俗称“火狐”(正式缩写为 Fx 或 fx,非正式缩写为 FF),是一个开源的网页浏览器,使用 Gecko 排版引擎,支持多种操作系统,如 Windows、OSX 及 Linux 等。

    7 引用 • 30 回帖 • 391 关注
  • 机器学习

    机器学习(Machine Learning)是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。

    83 引用 • 37 回帖 • 1 关注
  • WebSocket

    WebSocket 是 HTML5 中定义的一种新协议,它实现了浏览器与服务器之间的全双工通信(full-duplex)。

    48 引用 • 206 回帖 • 296 关注
  • C

    C 语言是一门通用计算机编程语言,应用广泛。C 语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。

    85 引用 • 165 回帖 • 1 关注
  • jsDelivr

    jsDelivr 是一个开源的 CDN 服务,可为 npm 包、GitHub 仓库提供免费、快速并且可靠的全球 CDN 加速服务。

    5 引用 • 31 回帖 • 110 关注
  • SOHO

    为成为自由职业者在家办公而努力吧!

    7 引用 • 55 回帖
  • SVN

    SVN 是 Subversion 的简称,是一个开放源代码的版本控制系统,相较于 RCS、CVS,它采用了分支管理系统,它的设计目标就是取代 CVS。

    29 引用 • 98 回帖 • 693 关注
  • Scala

    Scala 是一门多范式的编程语言,集成面向对象编程和函数式编程的各种特性。

    13 引用 • 11 回帖 • 160 关注
  • Gitea

    Gitea 是一个开源社区驱动的轻量级代码托管解决方案,后端采用 Go 编写,采用 MIT 许可证。

    5 引用 • 16 回帖 • 4 关注
  • SendCloud

    SendCloud 由搜狐武汉研发中心孵化的项目,是致力于为开发者提供高质量的触发邮件服务的云端邮件发送平台,为开发者提供便利的 API 接口来调用服务,让邮件准确迅速到达用户收件箱并获得强大的追踪数据。

    2 引用 • 8 回帖 • 492 关注
  • OpenResty

    OpenResty 是一个基于 NGINX 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

    17 引用 • 57 关注
  • Ubuntu

    Ubuntu(友帮拓、优般图、乌班图)是一个以桌面应用为主的 Linux 操作系统,其名称来自非洲南部祖鲁语或豪萨语的“ubuntu”一词,意思是“人性”、“我的存在是因为大家的存在”,是非洲传统的一种价值观,类似华人社会的“仁爱”思想。Ubuntu 的目标在于为一般用户提供一个最新的、同时又相当稳定的主要由自由软件构建而成的操作系统。

    127 引用 • 169 回帖
  • ZeroNet

    ZeroNet 是一个基于比特币加密技术和 BT 网络技术的去中心化的、开放开源的网络和交流系统。

    1 引用 • 21 回帖 • 648 关注
  • PHP

    PHP(Hypertext Preprocessor)是一种开源脚本语言。语法吸收了 C 语言、 Java 和 Perl 的特点,主要适用于 Web 开发领域,据说是世界上最好的编程语言。

    180 引用 • 408 回帖 • 490 关注
  • 倾城之链
    23 引用 • 66 回帖 • 166 关注
  • TensorFlow

    TensorFlow 是一个采用数据流图(data flow graphs),用于数值计算的开源软件库。节点(Nodes)在图中表示数学操作,图中的线(edges)则表示在节点间相互联系的多维数据数组,即张量(tensor)。

    20 引用 • 19 回帖 • 2 关注