软件制作活动中,时不时会遇到需要数据同步的场景,同步需要什么前提,同步有几种实现的方案,这方案有什么特点,本方试图全面来梳理一下。数据总量很小的情况下,可以每次都全量同步,多数情况下数据量较大,采用增量同步的方式。为方便描述,这里规定数据从 source 同步到 target。典型的 source 和 target 是两个数据库。
方案
- 自增ID方案
同步时记录Max(ID)
,下次同步只处理大于Max(ID)
的数据。 CreateTime
方案
Source新增记录时写CreateTime
,同步时记录Target的Max(CreateTime)
,下次同步只处理大于等于Max(CreateTime)
的数据,但要用PK(主键)排除等于Max(CreateTime)
的重复数据。注意事务的隔离性。UpdateTime
方案
Source新增/更新/删除时都要写UpdateTime
,同步时记录Target的Max(UpdateTime)
,下次同步只处理大于等于Max(UpdateTime)
的数据,但要用PK排除等于Max(UpdateTime)
的重复数据。注意事务的隔离性。- 伪删除方案
删除要作删除标记,而不是真删除。 - 日志方案(本质上是将增删改转化成日志的增)
增、删、改都写日志,通过日志同步。日志可以只记录操作类型(增/删/改)和主键。日志自身以 自增ID方案 或 CreateTime方案 同步。若只有一个target,可以同步完成一条日志,删除一条日志,每次都从最小ID/CreateTime开始处理,无须排除最近时间变化的数据,从而及时性比较高。(感谢@AgileBoy提供完善此方案的资料) - 通知方案
在增、删、改时source方将消息向target方推送。消息格式是:操作类型+数据内容,其中 操作类型=删除 的数据内容只须传PK。注意事务的原子性。
方案的选取
- 需要同步:增
日志方案 OR 通知方案 OR 自增ID方案 ORcreateTime
方案 ORupdateTime
方案 - 需要同步:增+删
日志方案 OR 通知方案 OR (updateTime
方案 AND 伪删除方案) - 需要同步:增+改
日志方案 OR 通知方案 ORupdateTime
方案 - 需要同步:增+删+改
日志方案 OR 通知方案 OR (updateTime
方案 AND 伪删除方案)
多级同步方案的updateTime
方案
- 这里多级同步是指超过2个节点串联的同步,比如A库同步到B库,B库同步到C库
- 需要一个
updateTime
记录原始数据的更新时间,此值在各库间同步,始终保持值不变。可用于对比多条记录哪条最新。 - 需要另一个
updateTime
记录本地数据的更新时间,作为同步到下一级的时间范围限定条件。此值用于增量同步限定同步的数据范畴。 - 不严谨场合的简化方案:仅用一个
updateTime
记录本地数据的更新时间。
更多的思考
- 如何支持删除,以及删除后的恢复?支持恢复就要求源和目标都是伪删除模式。本质上是将删除转成更新,从而支持正向删除和反向删除。
- 考虑到事务的隔离性,可能在抽取数据时,有事务未提交数据,所以,同步要故意排除最近时间变化(创建/修改/删除)的数据,比如排除最近60秒的数据。牺牲及时性,换来完整性。