軟件制作活動中,時不時會遇到需要數據同步的場景,同步需要什么前提,同步有幾種實現的方案,這方案有什么特點,本方試圖全面來梳理一下。數據總量很小的情況下,可以每次都全量同步,多數情況下數據量較大,采用增量同步的方式。為方便描述,這里規定數據從 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秒的數據。犧牲及時性,換來完整性。