Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

附加章八:数据一致性

复习

  • 副本:同一份数据可能被复制到多个位置保存
  • 网络通信:网络中的通信可能延迟、丢失或乱序

TL;DR

  • 一致性描述多个副本对数据状态达成怎样的约定
  • 并发写入会带来冲突,需要规则化解
  • 强一致更可靠但往往更慢,最终一致更快但会短暂不一致
  • 一致性、可用性与分区容忍,很难同时全部满足

正文

  为了让数据更可靠、访问更快,我们常常把它复制到多个地方:多块磁盘、多台服务器、多个机房。可副本一多,新问题就来了:当有人修改数据时,这些副本怎样才能保持一致?

  这就是数据一致性(data consistency)要回答的问题。

副本带来的麻烦

  单个副本时,读写都对着同一份数据,没什么好争的。可一旦有多个副本,情况立刻复杂起来:

  • 一个副本刚更新,另一个还是旧值,读它们会得到不同结果
  • 两个人几乎同时改写同一份数据,谁说了算
  • 更新还没同步完,网络就断了,副本之间开始“各说各话”

  于是,我们必须为“一致”定一个明确的含义:到底什么情况下,系统才允许你对某个副本的读取,与整体状态相符?

强一致与最终一致

  一致性不是一个“有或没有”的开关,而是一条光谱。两端常被拿来对比:

  • 强一致:任何时刻读到的都是最新写入的值,像是只有一份数据。安全,但往往要等待多数副本确认,延迟高、可用性差
  • 最终一致:先允许短暂的不一致,但保证经过一段时间后,所有副本会收敛到同一个值。响应快、可用性高,但中间可能读到旧数据

  选哪一端,取决于业务。银行转账往往要强一致,宁可慢一点也不能算错;社交平台的点赞数晚几秒更新,通常无伤大雅。

并发冲突怎么解

  当多个操作同时作用于同一份数据,就会产生冲突。常见的化解手段有:

  • 事务:把一组操作打包成“要么全做、要么全不做”,并保证彼此隔离
  • 版本与时间戳:给每次修改编号,冲突时按规则取舍

  这些机制的目的,都是让“同时发生”的操作有一个可预期的结果,而不是听天由命。

三者不可兼得

  分布式系统里有一条著名的经验——CAP:一致性(Consistency)、可用性(Availability)、分区容忍(Partition tolerance)三者,最多同时满足两个。

  由于网络分区几乎无法避免,现实系统通常被迫在“一致”和“可用”之间做取舍:要么暂停服务以确保数据一致,要么继续服务但容忍暂时的不一致。

  这也解释了我们前面看到的一些设计:备份、缓存、多副本、区块链,本质上都在用不同方式回答同一个问题——当无法同时拥有全部好处时,你更愿意牺牲哪一样?

思考题

  为什么“强一致”和“低延迟”常常难以兼得?

小结

知识点

  • 一致性约定多副本对数据状态的看法
  • 强一致与最终一致是一光谱的两端
  • 事务、版本等机制化解并发冲突
  • CAP 说明三者难以同时全部满足

参考资料

  1. Wikipedia(zh):一致性 (计算机科学):多副本数据状态的约定
  2. Wikipedia(zh):CAP定理:分布式系统三者不可兼得
  3. Wikipedia(zh):最终一致性:允许短暂不一致、最终收敛的模型

思考题答案(仅供参考)

  因为强一致通常要求写入被多个副本确认后才算完成,而跨副本的通信存在网络延迟,必须等待它们回应。等待越多,响应就越慢。想在保证强一致的同时又追求极低延迟,就要面对这一对难以调和的矛盾。

协议

  本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

封面图

设计师 | 南国微雪