时钟同步
1、物理时钟
2、时钟同步方法 (1)Cristian's algorithm (2)Berkeley algorithm
现如今:更典型的问题
1、逻辑时钟
2、因果关系
-- 向量时间戳
3、全局状态和终止检测
逻辑时钟
1、对于很多问题来说,内部时间的一致性是很重要的
--- 绝对时间不那么重要
--- 使用逻辑时钟
2、关键点:
--- 时钟同步不一定是绝对的
--- 如果两台机器没有交互,那么不需要对它们进行时钟同步
--- 更重要的是,多个线程之间需要达到一致的是事件发生的顺序而不是这些事件发生的时间
事件顺序
1、问题:定义一个系统中所有的事件发生的全局顺序
2、 事件在单台处理器中是完全有序的
3、在一个分布式系统中:
--- 没有全局时钟,本地时钟可能是不一致的
--- 无法用本地时钟来对发生在不同机器中的事件进行排序
4、关键点【Lamport】
--- 进程间交换信息
--- 消息发送一定是先于消息接收的
--- 发送/接收 用来对事件进行排序(和同步时钟)
Happened Before 关系
1、如果A和B是在同一个进程中的事件,如果A发生在B之前,那么A->B
2、如果A表示的是信息的发送,B是信息的接收,那么A->B
3、关系是传递性的:A->B and B->C 可以得到A->C
4、关系在不进行消息交换的进程中无需定义
--- 对事件的部分排序
用HB进行事件排序
1、目标:定义事件的时间概念
--- 如果A->B,那么C(A) < C(B)
--- 如果A和B同时发生,那么C(A) <,=,> C(B)
2、解法:
--- 每一个机器维护一个本地的逻辑时钟 LCi
--- 当机器i一个本地事件发生,LCi = LCi + 1
--- 当i发送消息给j时,消息中带上LCi
--- 当j接收到i发送过来的消息时
--- 如果LCj < LCi 那么 LCj = LCi + 1,否则什么都不用干
--- 观点 : 这个算法符合上述目标
Lamport's 逻辑时钟
例子:完全有序的多播
因果关系
1、Lamport's 逻辑时钟
--- 如果A->B那么C(A) < C(B)
--- 反过来就不成立了!!
--- 通过比较时间戳,不能得到任何关于事件的说法
--- if C(A) < C(B),那么??
2、需要保持因果关系
--- 如果a ->b那么a与b有因果关系
--- 因果关系传递: if send(m) -> send(n) => deliver(m) -> deliver(n)
--- 捕获机器组之间的因果关系
--- 需要一个这样的时间戳机制
--- 如果T(A) < T(B) 那么 A 应该是因果上先于B的
向量时钟
1、每一个进程i维护一个向量Vi
--- Vi[i] : 进程i上发生的事件数量
--- Vi[j]:进程i知道的发生在进程j中的事件数量
2、更新向量时钟按如下所示:
--- 本地有事件发生时,对Vi[i] ++
--- 发送信息时,带上进程i上的全量向量时钟V
--- 接收信息时:Vj[k] = max(Vj[k],Vi[k])
--- 接收者被告知发送者知道的发生在进程k中发送的事件数量
--- 同时 Vj[i] = Vj[i] +1
3、练习:证明如果V(A) < V(B),那么A 因果关系上先于B
全局状态
1、一个分布式系统的全局状态
--- 每一个进程的本地状态
--- 发送但未收到的消息(队列状态)
2、很多应用需要知道这个系统的状态
--- 失败恢复,分布式的死锁检测
3、问题:怎么得到一个分布式系统的状态
--- 每一个进程都是相互独立的
--- 没有全局的时钟或同步机制
4、分布式快照:一个一致的全局状态
全局状态(1)
分布式快照算法
1、假设每一个进程与另一个进程使用单向点对点通道进行通信(例如TCP 通道)
2、任何进程都可以初始化这个算法
--- 对本地状态进行checkpoint
--- 在每个传出通道上发送标记
3、当接收到一个标记时:
--- 如果是第一个标记对这个状态进行checkpoint并且保存信息在所有的其它通道上直
到向所有的传出通道发送了这个标记
--- 通道上的后续标记:不用为那个通道保存状态