3. 一致性模型与同步语义

在跨系统主数据同步工程中,真正决定系统行为边界的往往不是“用什么中间件”,而是两件事:一致性模型与同步语义。一致性模型回答“多个副本在任意时刻允许出现多大差异”,同步语义回答“数据以什么方向、什么时机、以何种冲突处理规则流动”。二者组合起来,才构成一份可被开发、测试和运维共同遵守的契约。

一、一致性模型:从强到弱的连续谱

强一致性(线性一致性)要求:一旦写操作返回成功,任何后续读操作都必须读到该值,且所有副本对外表现为单一逻辑副本。它通常依赖同步复制或共识协议(如 Raft、Paxos)实现。代价是写延迟受最慢副本影响,可用性在分区时下降。主数据中适合强一致的对象是“唯一性约束强、错误代价高”的字段,例如客户主键、组织编码、物料唯一标识。

因果一致性是介于强一致与最终一致之间的模型:它不要求全局有序,但要求有因果关系的操作必须被所有节点按相同顺序观察到。例如“先创建客户,再修改客户地址”,任何节点都不能先看到地址修改而看不到客户创建。实现上常借助版本向量(Version Vector)或逻辑时钟(Lamport Clock)标记因果关系。它适合主数据中“有依赖链”的更新,如组织层级调整、物料分类迁移。

最终一致性只保证:若停止写入,经过有限时间后所有副本收敛到相同值。它不约束中间状态,因此读到的可能是旧值。它适合“读多写少、容忍短暂不一致”的属性,如客户标签、物料描述、参考数据。工程上必须配套收敛判据:例如以“同步延迟 P99 ≤ 5s、冲突残留数 = 0”作为验收指标,而不是笼统地说“最终会一致”。

此外还有读己之写(Read-Your-Writes)与单调读(Monotonic Reads)等会话级模型,它们不改变全局一致性,但能显著改善用户体验:用户提交修改后立即刷新页面,应看到自己的修改;用户连续刷新,不应看到版本回退。

二、同步方向:单向与双向的语义差异

单向同步指定一个权威源(System of Record,SoR),数据只从源流向目标。目标系统对主数据字段通常只读。它的语义清晰、冲突少,适合“总部主数据 → 分支系统”“MDM → 数据仓库”等场景。关键约束是:目标系统的本地修改必须被禁止或隔离,否则会在下一次同步时被覆盖。

双向同步允许两端都可写,必须定义冲突解决策略。常见策略包括:

  • 最后写入胜出(LWW):以时间戳判定,实现简单,但依赖时钟同步,可能丢失并发更新。
  • 源优先:指定一端为权威,另一端修改在冲突时让位。
  • 字段级合并:不同字段各自保留,仅对同字段冲突做裁决。
  • 人工仲裁:冲突进入待处理队列,由数据管理员决策。

双向同步还必须处理回环(Loop)问题:A 同步到 B 的数据又被 B 同步回 A,造成重复写入。工程上通过“同步标记 + 来源系统标识 + 版本号”来阻断回环:每条记录携带 origin_system 与 sync_version,当接收端发现来源等于自身或版本未递增时,丢弃该消息。

三、同步时机:实时、准实时与批量的语义定义

实时同步通常指变更发生后毫秒到秒级完成传播,依赖 CDC(变更数据捕获)或事件流。语义上要求“变更即事件”,适合对时效敏感的主数据,如客户状态、价格主数据。它需要处理乱序、重复与背压。

准实时同步指秒到分钟级,常采用微批(Micro-batch)或短周期轮询。它在吞吐与延迟之间取平衡,适合大多数主数据属性同步。

批量同步指小时级或天级,以全量或增量文件方式交换。它实现简单、易对账,但延迟高,且需要处理“批量窗口内的多次变更合并”。批量同步必须定义快照边界:以某个时间点或版本号为准导出,避免窗口内数据漂移。

选择同步时机时,先问三个问题:业务能容忍多长延迟?变更频率多高?失败后能否重放?延迟容忍度低、变更频繁、可重放,优先实时;否则批量更稳。

四、模型与语义的组合决策

一致性模型、同步方向、同步时机不是独立选项,而是需要组合成一份可执行的同步契约。下面这张图把三者的决策关系与典型组合放在一起,便于在方案评审时快速定位。

一致性模型 × 同步方向 × 同步时机:组合决策图 一致性模型 强一致性 写后即读,全局单副本视图 代价:延迟高、分区降可用 适用:唯一标识、编码 因果一致性 有依赖的操作保持顺序 工具:版本向量、逻辑时钟 适用:层级、分类迁移 最终一致性 停止写入后有限时间收敛 需定义收敛判据与延迟指标 适用:标签、描述、参考数据 同步方向 单向同步 权威源 → 目标系统 目标侧主数据只读 冲突少,语义清晰 例:MDM → 数据仓库 约束:禁止本地改写 双向同步 两端可写,必须定冲突策略 LWW / 源优先 / 字段合并 / 人工仲裁 防回环:origin_system + sync_version 校验 例:总部 ↔ 区域系统 风险:并发覆盖、时钟漂移 同步时机 实时 毫秒~秒级,CDC / 事件流 需处理乱序、重复、背压 适用:状态、价格主数据 准实时 秒~分钟级,微批 / 短轮询 吞吐与延迟折中 适用:多数主数据属性 批量 小时~天级,全量 / 增量文件 需定义快照边界与对账 适用:参考数据、历史归档 典型组合:强一致 + 单向 + 实时(编码主数据)|因果一致 + 双向 + 准实时(组织层级)|最终一致 + 单向 + 批量(参考数据)

五、把语义写成可验证的契约

无论选择哪种组合,都必须把语义落到可验证的字段上。以下是一份同步契约的关键字段示例,可直接用于接口文档或配置表:

字段含义示例值
consistency_model一致性模型causal / strong / eventual
sync_direction同步方向one_way / bi_way
sync_timing同步时机realtime / near_realtime / batch
conflict_policy冲突策略(双向必填)lww / source_priority / field_merge / manual
origin_system来源系统标识,用于防回环MDM_HQ
sync_version单调递增版本号10247
convergence_sla收敛时限(最终一致必填)P99 ≤ 5s
snapshot_boundary批量快照边界version=10247 或 ts=2025-03-01T00:00:00Z

以一个客户主数据同步为例:客户编码采用强一致 + 单向 + 实时,由 MDM 生成后立即推送,目标系统只读;客户地址采用因果一致 + 双向 + 准实时,区域系统可修改,但必须携带版本向量,冲突时按字段合并;客户标签采用最终一致 + 单向 + 批量,每天凌晨以快照方式同步,验收标准为“次日 06:00 前标签差异记录数为 0”。

常见误区:把“最终一致”当成“不用管一致”。最终一致必须给出收敛判据、延迟上限和冲突残留检查方法,否则无法验收,也无法排障。

最后,一致性模型的选择应与业务影响对齐:错误代价越高、唯一性越强,越应偏向强一致或因果一致;读多写少、容忍短暂差异的属性,才适合最终一致。同步方向决定冲突责任归属,同步时机决定延迟与吞吐的平衡。三者一旦确定,就应写入契约并配套监控指标——同步延迟、冲突数、回环拦截数、收敛时间,让语义从文档变成可观测的运行事实。