2.4 复制与一致性模型


2.4 复制与一致性模型

复制是把同一份数据放多份的技术手段,一致性模型是"这多份之间对外允诺到什么程度"的语义约定。本节把两者接起来看:主从、多主、链式三种复制拓扑各自能提供哪一档一致性;强一致、顺序一致、因果一致、最终一致四级分别适合什么业务。

复制和一致性:一张桌子分两边放,对外怎么说它是一张

复制这件事说起来简单:多放几份,坏一份换一份就完事。可复制完之后,"同一行记录有好几个版本在跑",怎么让用户看起来还是"一张桌子"?这就是一致性模型要回答的问题。它决定了:刚写进去的新值,多久之后所有读请求都能看到;如果有多个写同时发生,先后顺序怎么算。所以复制和一致性根本不是两件事——复制是物理手段,一致性是对外语义约定,我们得把它们放在一起说,才能看清楚拓扑和档位怎么配。

学习目标

阅读完本节,你应当能够:

  1. 画出主从、多主、链式三种复制拓扑,并说明各自的主要写入点。
  2. 排出强、顺序、因果、最终四级一致性的强弱次序并给出例证。
  3. 把一个业务的一致性强弱要求,翻译成"该用哪种复制拓扑"。

复制的两张脸:手段与约定

复制聊的是"怎么把数据多放几份",一致性模型聊的是"多放了几份之后对外保什么"。很多初学者把两者混为一谈,其实它们一个在物理层、一个在语义层。你可以搭一套主从复制(手段),却并不因此自动获得强一致性(约定)——是否强到"刻读必得新",取决于副本之间同步的究竟是谁、以及读请求往哪份副本走。

一、三种复制拓扑

主从复制:唯一的"主"节点接受全部写入,其余"从"节点只负责读。写入在主节点完成,日志或数据异步同步到从节点。优点:写入路径简单、天然有序,读能力可以水平扩展。缺点:主节点一旦挂掉,需要选举新主(会有短暂不可用窗口),且异步同步下"读从"可能读到旧值。

多主复制:多个主节点都可以接受写入,节点之间互相复制对方的变化。优点是就近写入、无单点、容灾强。但代价是写写冲突:两个主节点同时改同一条记录,到底以哪个为准,需要冲突解决策略;而不同策略会带来不同的一致性品质,处理不好就是数据打架。

链式复制:数据沿一条确定的链路依次传播,比如主节点传到中间节点、再传到末端。因为传播是串行的,能保证链路上的顺序一致,实现简单,但整条链的可用性取决于最脆弱的环节,一旦某段断了链路就受影响。

三种拓扑的写入走向

下面这张 SVG 用节点与箭头,把三种复制拓扑的写入与同步方向画出来:

三种复制拓扑:写入从哪进、往哪传

三种复制拓扑:写入从哪进、往哪传

二、四档一致性:从强到弱排开

复制提供了多份,一致性模型负责给"多份"定契约。按强弱次序排,常见这四档:

强一致(线性一致性):写入一旦提交,任何后续读取(无论去哪个副本)都必然看到这个值。这是最理想的语义,代价是写必须同步到全部(或法定多数)副本才能返回,延迟高、可用性受限。金融账务最喜欢这种。

顺序一致:所有进程看到的是同一个操作顺序,只是这个顺序未必与"墙上的真实时间"一致。它比强一致宽松一档:仍要求全局一个序,但允许与现实时钟有偏差。适合需要一致排序但不苛求即时性的场景。

因果一致:只对有因果关系的操作要求次序——"先发生的必须排在因果相关操作之前",无因果关系的操作可以任意乱序。它非常贴合人类直觉:你发了条朋友圈(A),别人回你(B),那么看到 B 的人一定也看到过 A;但两个无关的操作可以不讲次序。社交内容流大量用这一档。

最终一致:不做任何即时序的诺言,只保证"安静之后会收敛"。它是四档里实现最便宜、可用性最高的一档。

一致性四档的强度刻度

三、拓扑和档位怎么配,一张表就说清

不同复制拓扑配合不同一致性档位,有天生的默契也有别扭。把常见配法列出来,你一看就懂为什么这么配:

拓扑 最常用档位 为什么这么配
主从复制 强一致(读主)/最终一致(读从) 写入只走主,主一致了才放读从,档位天生分层
多主复制 因果一致/最终一致 多主同时写,冲突必然存在,只能降档让应用兜底
链式复制 顺序一致 传播天然有序,做顺序一致几乎不额外花钱

这张配法表的潜台词是:不是拓扑定了就只能配一个档位,但顺着拓扑的天然特性配档位,实现简单、代价又低;非要反着配(多主配强一致),也不是做不到,但复杂度和代价会飙升,不到万不得已别碰。

四、把业务的一致性要求翻译成复制拓扑

判断业务处在哪档,通常绕着一个问题打转:"用户刚写的东西,下一秒是不是必须能被任何人读到?"

  • 必须、错不得 → 强一致,走"写同步到法定副本 + 主从读主"路线。
  • 只关心"事件有先后因果",不追求苛刻即时 → 因果一致,常见于内容/社交。
  • 可以容忍短暂读到旧值、量又大 → 最终一致,主从异步或多主皆可。

记住一句工程心法:复制拓扑决定"在哪一层能保一致",一致性档位决定"业务答应给客户怎样的顺序",两者要配着选。配错了的典型惨案是:你选了多主复制、又想让业务享受强一致——结果写冲突加上异步副本,强一致根本兑现不了,冲突解决策略还让数据偶尔打架。

五、一个真实系统配错的惨案

我见过一个比较典型的反面案例:一个社交平台为了追求多主就近写入,用了多主复制,又要求给用户发消息必须"发完立刻能在另一端看到"——强一致要求。结果上线后写冲突频发,系统为了保证强一致频繁做冲突回滚,用户发十条消息退回去三条,体验非常糟糕。其实拆解下来:发消息本身是典型的因果一致场景,只要对方看到消息前一定看到你的对话,不需要立刻强一致;或者如果非要强一致,就该用主从,让所有写入都走同一个主。拓扑和档位配反了,本来可以很顺滑的体验,做成了每天救火的战场。这个教训告诉我们:选型先看业务要的档位,再找对应拓扑,别先把拓扑定死,再硬套档位。

本节要点回顾

  • 三种拓扑:主从(写集中读扩展)、多主(就近写有冲突)、链式(串行保序)。
  • 四档一致:强、顺序、因果、最终,逐档降强让价。
  • 手段≠约定:复制拓扑只决定哪层能保一致,档位是另一层的事。
  • 配错就翻车:多主复制配强一致,十有八九写冲突让你数据打架。

逻辑层的字典已经备齐:CAP 取舍、BASE 妥协、分布策略、复制与一致性。接下来该进入物理层了——第 3 章看看这些节点实际怎么被装进一台真集群:Shared-Nothing、Shared-Disk、Shared-Memory。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U