一致性协议和数据一致性有什么区别?
简化版
共识协议解决一组节点在故障和并发下对同一条有序日志或状态达成一致,例如 Raft、Paxos。 数据一致性描述系统对客户端承诺的读写语义,例如线性一致、因果一致、最终一致。 使用共识可以构建线性一致复制状态机,但不代表整个业务自动强一致;跨分片事务、缓存、异步消息和客户端会话仍需单独设计。
详细版
共识关注“哪些值、按什么顺序被多数派接受”,安全性要求不能产生两个冲突的已提交历史,活性依赖多数节点和网络最终恢复。 数据一致性关注“读到什么、何时可见、顺序如何”,模型可以强也可以弱。
单个 Raft 组可让其日志具有全序,并在正确读协议下提供线性一致 KV。 但两个独立 Raft 分片之间没有共同原子边界;数据库事务也可能选择快照隔离而非可串行化。 回答时要分清协议层、存储层与业务层,避免用一句“底层是 Raft”替代端到端保证。
完整版教学
一、两个术语所在层次不同
共识是分布式节点之间的协调问题。 一致性模型是系统对使用者暴露的行为契约。 前者常作为实现机制,后者是可观察语义。
共识回答“副本如何决定”,一致性回答“客户端能观察到什么”。
二、共识协议的核心目标
共识协议通常要求 agreement、validity 和一定条件下的 termination。 工程中的 Raft 把客户端命令排成日志,经多数派提交后按序应用。
client command -> leader log
-> majority replication -> commit
-> deterministic state-machine apply
节点宕机、消息重复和乱序不能造成两个冲突的提交结果。
三、常见数据一致性模型
| 模型 | 核心承诺 | 常见代价 |
|---|---|---|
| 线性一致 | 遵守真实时间的单一操作顺序 | quorum/Leader 协调 |
| 因果一致 | 因果相关操作顺序一致 | 跟踪因果上下文 |
| 会话一致 | 单会话读己之写、单调读 | 会话路由或 token |
| 最终一致 | 无新写时副本最终收敛 | 允许短时旧值 |
模型强弱取决于业务接口,不由产品名称自动决定。
四、共识如何帮助实现强一致
单个共识组给写命令确定全序。 客户端只在多数派提交后收到成功,读取再通过 ReadIndex、租约或日志屏障确认新鲜度,可实现线性一致状态机。 如果读直接落到任意落后 Follower,即使写用了 Raft,外部读仍可能陈旧。 所以写复制协议和读路径必须一起分析。
五、为什么有 Raft 仍可能不一致
订单分片和账户分片分别使用 Raft,各自内部安全。 一次业务操作先写订单再扣余额,中间失败仍会跨分片不一致。 缓存未失效、CDC 延迟、搜索索引落后也会让用户看到不同版本。 这需要事务、Saga/补偿、Outbox、版本校验或明确的最终一致体验。
六、共识也不等于可用
5 节点集群可容忍 2 个节点故障,但失去 3 个节点后不能安全提交。 这不是协议失败,而是为避免脑裂主动停止写。 异步多副本可能在分区中更可用,却需要冲突解决。 CAP 权衡应结合操作和故障场景,不要把系统永久贴成 CP/AP 标签。
七、端到端保证如何说明
先标出权威数据、分片边界、复制协议、提交成功点和读取路径。 再说明缓存、消息、索引和客户端重试是否处于同一原子边界。 例如“单分片读写线性一致,跨分片事务严格可串行化,搜索索引 5 秒内最终一致”比“系统强一致”准确。 监控应覆盖 quorum、复制延迟、事务冲突和派生数据滞后。
八、常见误区与追问
- 误区:用了 Raft,所有业务数据就强一致。 Raft 只覆盖其共识组和正确接入的读写路径。
- 误区:最终一致不需要协议。 仍需版本、反熵、幂等与冲突解决。
- 误区:共识只是在副本间同步文件。 它决定安全的值和顺序,并处理任期与领导权。
- 误区:数据一致就是副本字节完全相同。 一致性模型关注客户端可观察历史。
- 追问:Raft 能直接提供跨分片事务吗? 不能,需事务协调或重构边界。
- 追问:写走 Raft、读 Follower 是什么一致性? 默认可能读旧,除非有安全索引或会话约束。
- 追问:共识与复制区别是什么? 复制搬运数据,共识在故障下安全决定哪份数据及顺序有效。
九、加强记忆
- 共识是节点间决定机制。
- 一致性是客户端看到的语义。
- 共识组加正确读协议可构建线性一致状态机。
- 跨组、缓存和异步派生数据不自动继承保证。
- 面试必须给出保证的范围、成功点和故障条件。