动态

详情 返回 返回

架構師必備:實時對賬與離線對賬 - 动态 详情

背景

在跨系統之間的數據寫入場景下,上下游系統極有可能因為網絡超時/抖動、或寫本地DB與調外部接口不能同時成功等原因,而出現數據不一致的問題,因此需要有及時發現不一致問題、並自動修復的能力。下面結合筆者的經驗,把對賬做個總結。

需要注意的是,這裏提的對賬不特指資金對賬,而是跨系統的字段對賬,如B端與C端系統之間的對賬。

對賬的指標

判斷對賬是否做得好,主要看這幾個指標:

  • 完備性:確保所有字段都有對賬
  • 時效性:越高越好,秒級 > 分鐘級 > 小時級 > 天級
  • 自動修復:對賬發現不一致後自動修復,然後再次對賬,確保修復後是最終一致的,形成閉環

下面分別介紹一下實時對賬、離線對賬,最好是兩個都做。

1. 實時對賬(秒級到分鐘級對賬)

實時對賬可以儘快發現不一致,一般由數據寫入方發起對賬,數據接收方提供對賬查詢接口(例如查從庫)。

觸發方式分2種:

  • (不推薦)數據庫變更事件觸發:監聽業務主表的binlog變更
  • (推薦)業務消息觸發:監聽業務消息變更

推薦由業務消息觸發,是因為數據庫變更事件觸發有侷限:

  • 如果有的寫入操作不更新業務主表,比如只更新了擴展表,則需要新消費擴展表的binlog事件消息。
  • 如果存在中間狀態,則需要等到記錄變成終態後才能對賬,需要過濾很多無效消息。

實現方案:

  1. 監聽業務消息變更。業務消息需做成事務消息,即業務操作完成必發出、不完成不發出。業務消息可以攜帶多個表的信息,能減少一定的查DB請求。
  2. 延遲、批量消費變更消息,然後批量查詢本地DB數據、以及上下游接口。
  3. 最後逐個字段做比較。

image

之所以要寫入方發起對賬,而不是接收方,是因為寫入方調接收方的接口可能失敗,接收方在寫入失敗時無法觸發對賬。

之所以要延遲消費,是為了避免短時間內的不一致造成誤告警(例如數據庫主從延遲、接口超時重試等原因),比如延遲15秒再消費。

之所以要積攢一批消息做批量消費,是為了避免對賬查詢qps過高,給本服務和上下游系統帶來較大負載。

2. 離線對賬(小時級到天級對賬)

有了在線對賬,為什麼還需要離線對賬呢?

  • 離線對賬作為在線對賬的兜底,可以定期跑歷史存量數據
  • 離線對賬不影響在線業務的穩定性
  • 外部第三方系統,一般只能定期提供離線數據,無法提供對賬查詢接口。典型的如第三方支付系統的對賬單

實現方案:

  1. 離線採集:導出各系統的數據到hive表,可以是mysql表、或者是對賬單
  2. 歸一化數據:解析出所有的對賬字段,按統一格式生成新的寬表a、寬表b
  3. 離線對比:
    (1)需要比較條數是否一致
    (2)以及數據內容是否一致:通過左連接找到只存在於左表的數據,通過右連接找到只存在於右表的數據,通過內連接並比較各個字段來找到存在差異的數據

下面看sql例子。

-- (1)比較兩個表的條數是否一致
select count(1) from table_a; -- 查出左表的條數
select count(1) from table_b; -- 查出右表的條數

-- (2)比較數據內容是否一致
-- (2.1)只存在於左表的數據:左連接查詢,左表記錄都會保留,右表字段為空則説明右表缺少數據:
select * from
table_a left outer join table_b
on table_a.biz_field=table_b.biz_field
where table_b.biz_field is null;

-- (2.2)只存在於右表的數據:右連接查詢,右表記錄都會保留,左表字段為空則説明左表缺少數據:
select * from
table_a right outer join table_b
on table_a.biz_field=table_b.biz_field
where table_a.biz_field is null;

-- (2.3)兩個表存在差異的數據,內連接查詢,比對各個字段是否一致:
select * from
table_a inner join table_b
on table_a.biz_field=table_b.biz_field
where
(table_a.field_1 <> table_b.field_1
or table_a.field_2 <> table_b.field_2
or table_a.field_3 <> table_b.field_3);

3. 自動修復

一般是寫入方發現不一致後,需要做自動修復。流程如下:

  1. 記錄差異,供後續定位排查
  2. 自動修復
  3. 修復後再次對賬,確保數據最終一致

結論

實時對賬和離線對賬,互為補充、缺一不可。新需求除了保證功能正確性,還要同時做好對賬,避免有不一致問題時發現不了,或很久才發現。

對賬發現不一致後自動修復,能保證系統的最終一致性。

user avatar u_17514447 头像 fannaodeliushu 头像
点赞 2 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.