Vector Clock:多个副本同时修改,系统怎样知道是先后还是冲突?

TL;DR

向量时钟用每个副本的计数记录因果历史,通过逐项比较识别祖先版本与并发冲突,为多副本合并提供依据。

向量时钟用每个副本的计数记录因果历史,通过逐项比较识别祖先版本与并发冲突,为多副本合并提供依据。

Vector Clock:多个副本同时修改,系统怎样知道是先后还是冲突?

当一个分布式数据库有多个副本时,两个客户端可能同时修改同一条记录。系统看到的不是简单的“后来覆盖先来”,而是要判断两个版本存在先后关系,还是彼此并发、需要合并。Vector Clock(向量时钟)就是用来记录这种因果关系的工具。

把每个副本想成一本自己的日记。每发生一次本地更新,它就把自己的计数加一;向另一个副本发送版本时,也把整本计数摘要带上。收到消息的副本会逐项比较两个向量:如果一个向量在所有位置都不小于另一个,它就包含了后者的历史;如果各自有一部分更大,则表示两次更新存在并发分支。

例如副本 A 的向量是 A:3、B:1,副本 B 的向量是 A:3、B:2,那么后者可以看作前者之后发生的版本。但如果一个版本是 A:4、B:1,另一个是 A:3、B:2,谁也没有在所有维度上领先,它们就是并发冲突。系统可以保留两个版本交给应用合并,也可以根据业务规则选择结果。

向量时钟的优点是语义清楚,能显式表示祖先和并发。缺点是向量大小通常随参与副本数增长;副本频繁加入、离开或版本传播不完整时,管理成本会变高。实际系统可能压缩向量、限制版本历史,或者使用其他逻辑时间结构做折中。

它提醒我们,“时间更晚”不一定等于“逻辑上覆盖”。在分布式系统中,因果链和并发分支是两种不同事实。向量时钟不替业务解决冲突,但它先把冲突识别准确,让应用知道什么时候可以覆盖,什么时候必须合并。

当副本数量很大时,完整向量会显得笨重,因此系统常用稀疏表示、截断历史或改用近似结构。无论采用哪种压缩,都要清楚它可能丢失哪些因果信息:如果把两个本来并发的版本错误合并,冲突就会从“可见的分支”变成“悄悄丢数据”。

资料来源:Amazon Dynamo:Highly Available Key-value Store

KEEP READING