线性一致的判定标准
线性一致性(Linearizability)是单对象上最强的一致性保证之一:每个操作看起来在“调用与返回之间的某一时刻”原子生效,并且所有客户端观察到同一个操作顺序。它的判定要点是两条——生效点必须落在该操作的调用区间内,且该顺序不能与实时先后关系矛盾。完成过线性一致操作的两个操作,后续操作必须能看到前者的效果。多对象的线性一致不能自动组合,跨对象事务需要额外保证。
基本信息
| 别名 | 原子一致性、可线性化 |
|---|---|
| 判定要点 | 操作生效点落在调用区间内,且与实时顺序一致 |
| 实现代价 | 通常需要共识协议或多副本同步写 |
| 组合性 | 多个线性一致的单对象仍可组合,但跨对象的原子性要单独保证 |
典型使用场景
- 选主与租约:确认同一时刻只有一个主节点持有租约
- 分布式锁实现评估:判断锁服务在分区时是否仍然正确
- 跨副本读取语义:决定读请求是否需要走共识组
- 数据库隔离级别选择:明确业务需要的是线性一致还是可串行化
- 故障验证:用历史检查工具验证存储系统在故障注入下的行为
怎么判定
判定方法:把并发执行的操作按调用与返回区间整理,尝试构造一个串行顺序,使每个读都返回最近一次写的结果;找不到这样的顺序即违反线性一致。历史检查工具(如 Jepsen)即按此思路自动判定。
违规示例
违规示例
客户端 A:write(x, 1) 完成 ────────────────
客户端 B: 读取 x → 返回 0 ← 违规
B 的读发生在 A 的写完成之后,
却读到旧值,无法构造出合法串行顺序
# 注意:读返回旧值也可能是可接受的,取决于一致性模型一致性模型对照
| 模型 | 关注对象 | 典型实现 |
|---|---|---|
| 线性一致 | 单对象的实时顺序 | 共识复制(Raft 等)与同步写多数派 |
| 顺序一致 | 单对象顺序,但不要求与实时顺序一致 | 部分内存一致性模型 |
| 可串行化 | 多对象事务等价于某个串行执行 | 数据库可串行化隔离级别 |
| 严格可串行化 | 可串行化 + 线性一致 | 分布式数据库的强一致事务 |
线性一致 ≠ 可串行化:前者关注单对象实时顺序,后者关注多对象事务的等价串行执行;需要跨对象原子与实时顺序时,要的是严格可串行化。
仅单个对象满足线性一致,不能推断整个事务满足任何一致性保证;跨对象读取之间仍可能看到不一致的中间状态。