因果一致性

保证有因果关系的操作在所有节点上按相同顺序可见,无因果关系的操作可乱序;比强一致代价低,又避免“评论早于帖子”这类明显异常。

什么是因果一致性

因果一致性保证有因果关系的操作在所有节点上按相同顺序被观察到:同一客户端的写入、读后写的依赖、以及传递关系都必须保序;没有因果关系的并发操作可以乱序。它比线性一致性代价低,又避免了「回复先于原帖可见」这类明显违反直觉的异常,是社交与协作类系统的常见折中。

基本信息

保序范围同一客户端顺序、读写依赖、传递关系
不保证并发且无因果关系的操作之间的全局顺序
实现手段版本向量、因果上下文传递、依赖跟踪与暂存
代价元数据随请求传递,存储与比较开销高于最终一致

典型使用场景

  • 社交互动:回复、点赞不会先于原帖对用户可见
  • 协作编辑:同一位用户的连续修改保持顺序,避免「撤销后旧内容回来」
  • 评论与审核:审核动作与其结果之间的顺序关系不被颠倒
  • 消息与会话:同一会话内的消息顺序对参与者可预期
  • 跨地域部署:避免全局协调的前提下消除最刺眼的顺序异常
  • 缓存与读路径:把因果上下文随请求传递,跨节点读不出现回退

依赖检查示意

依赖检查示意
# 每个副本维护版本向量:记录自己与各节点已见事件数
# 收到消息时先检查依赖
if not 本地已包含消息的全部依赖:
    暂存该消息,等待缺失依赖到达后再应用   # 不提前展示给用户
else:
    应用消息并更新本地版本向量
# 效果:回复不会先于原帖对用户可见;无因果关系的操作仍可乱序
# 注意:上下文需要随请求与消息一起传递,跨节点后不能丢

一致性模型对照

模型保序范围典型代价
最终一致无顺序保证,只保证最终收敛元数据最少
因果一致有因果关系的操作保序需传递因果上下文
线性一致全部操作全局实时顺序需要协调,延迟与可用性代价高
因果顺序不是全局顺序:跨用户比较事件先后时不能依赖它,需要全局顺序的场景要另加机制。
因果上下文必须在整条链路传递:网关、消息队列或异步任务丢掉元数据后,因果关系会在跨节点时静默失效。

易错点

  • 把因果顺序当成全局顺序使用,跨用户比较事件先后时得出错误结论
  • 因果上下文未随请求与消息传递,跨节点后依赖丢失,顺序异常回归
  • 到处使用因果一致而不评估元数据开销,存储与比较成本超出预期
  • 只在读路径做暂存,写路径仍可提前可见,用户看到状态来回跳变

数据来源与参考

  • 《数据密集型应用系统设计》(Kleppmann)第 5 章
  • Jepsen 一致性模型参考
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌