巧用 TiCDC Syncpiont 構建銀行實時交易和準實時計算一體化架構

本文闡述了某商業銀行如何利用 TiCDC Syncpoint 功能,在 TiDB 平臺上構建一個既能處理實時交易又能進行準實時計算的一體化架構,用以優化其零售資格業務系統的實踐。通過遷移到 TiDB 並巧妙應用 Syncpoint,該銀行成功解決了原有多個 MySQL 集羣所面臨的數據分佈複雜性和跨庫關聯查詢的挑戰,實現了數據處理效率和應用性能的顯著提升,確保了實時交易的快速響應和數據分析處理的計算資源需求。


場景概述

某商業銀行的零售資格業務系統專門設計用於計算和管理客戶的消費積分及優惠。每當用戶完成一筆交易,系統內的關鍵模塊便會自動整合用戶的歷史消費數據,迅速進行積分計算,並將當前可用的優惠信息及時推送給用戶,例如通知當前能夠兌換的優惠或贈品,提示額外消費達到一定額度後能夠獲得的特定獎勵等。該系統旨在通過提供實時的優惠信息和激勵措施,增強客戶的消費體驗。

用戶的消費信息按照用戶 ID 進行分組,存儲在 30 多個 MySQL 集羣。隨着業務的增長,以及需要開放第三方應用使用數據,完成資格的計算。分庫分表的 MySQL 就不滿足業務需求了。一方面,分庫分表後數據分佈複雜;另外,分庫分表難以實現跨 MySQL 庫的關聯查詢。 如果把這些 MySQL 庫的數據匯聚到 HBase 等大數據平臺,即不能保障用戶交易以事務的粒度同步到大數據平臺,也很難保證數據的時效性(大數據通常都只做 T+1 的計算)。

爲了優化應用性能和數據處理效率,行方決定將應用遷移到 TiDB 平臺,並採取策略將實時交易和準實時計算分配到兩個不同的 TiDB 數據庫集羣中。資格落地模塊用來完成準實時資格的計算。因爲落地數據計算量大,並且有準實時性的要求,爲了不影響實時業務,落地計算是通過 TiDB 備集羣 2 進行計算,該集羣的數據來自 TiCDC 從實時集羣同步過來的準實時數據。

這樣的架構設計旨在平衡交易的即時性和數據處理的計算需求,確保實時交易的快速響應,同時爲數據分析和處理提供足夠的計算資源。

TiCDC 和 Syncpoint 特性簡介

本文以商業銀行零售資格業務系統爲例,向大家介紹怎樣通過 TiCDC 的 Syncpiont 功能,來確定目標端的同步進度,並且以此爲依據,計算每筆業務對用戶資格數據的貢獻。

 

圖 1:實時交易和準實時計算一體化架構

“TiDB 主集羣”爲實時集羣;“TiDB 備集羣 2”是專門爲資格落地準備的準實時集羣;“TiDB 備集羣 1”是容災集羣

衆所周知,在業界,幾乎所有的變更數據捕獲(CDC)產品都通過異步方式進行數據同步,這導致主集羣與備集羣之間不可避免地會出現數據延遲。TiCDC 採用分佈式架構設計,也會受到主備之間延遲的影響,不能保證目標端的事務提交順序和源端的事務提交順序完全一致,無法動態地獲取主備集羣的一致性關係。

行方原先考慮在源端提交以後,等待一分鐘左右時間,再去備集羣計算,但是,如果遇到大的事務,或者集羣因爲某些原因提交緩慢,即使等待 N 分鐘,也不能保證備集羣能完成同步。

圖 2:TiCDC 分佈式同步架構

在使用 TiCDC 構建 TiDB 主從集羣的過程中,有時需要在不中斷數據同步的情況下,進行數據的一致性快照讀取或驗證。由於 TiCDC 採用的是分佈式架構,其標準同步模式僅確保數據的最終一致性,而不能保證在同步過程中的數據一致性。這就使得對實時變化的數據進行一致性讀取變得具有挑戰性。爲了解決這個問題,TiCDC 引入了 Syncpoint 功能,它允許用戶在特定時間點獲取數據的一致性視圖,從而進行一致性讀取和數據驗證,滿足了對數據一致性有嚴格要求的業務場景。

Syncpoint 通過利用 TiDB 提供的 snapshot 特性,讓 TiCDC 在同步過程中維護了一個上下游具有一致性 snapshot 的 ts-map。把校驗動態數據的一致性問題轉化爲了校驗靜態 snapshot 數據的一致性問題,達到了接近數據一致性實時校驗的效果。當啓用 Syncpoint 功能後,就可以使用一致性快照讀和數據一致性校驗。

巧用 Syncpoint

要開啓 Syncpoint 功能,只需在創建同步任務時把 TiCDC 的配置項 enable-sync-point 設置爲 true。開啓 Syncpoint 功能後,TiCDC 會向下遊 TiDB 集羣寫入如下信息:

在數據的同步過程中,TiCDC 會定期(使用 sync-point-interval 參數配置)對齊上下游的快照,並將上下游的 TSO 的對應關係保存在下游的 tidb_cdc.syncpoint_v1 表中。

同步過程中,TiCDC 還會定期(使用 sync-point-interval 參數配置)通過執行 SET GLOBAL tidb_external_ts = @@tidb_current_ts ,在備用集羣中設置已複製完成的一致性快照點。

Syncpoint 表結構如下:

select * from tidb_cdc.syncpoint_v1;
+------------------+-------------+--------------------+--------------------+--------------------+
| ticdc_cluster_id |  changefeed | primary_ts         | secondary_ts       | created_at         | 
+------------------+-------------+--------------------+--------------------+--------------------+ 
|  default         | test-2      | 435953225454059520 | 435953235516456963 | 2022-09-1308:40:15 | 
+------------------+-------------+--------------------+--------------------+--------------------+

ticdc_cluster_id:插入該條記錄的 TiCDC 集羣的 ID。

changefeed:插入該條記錄的 Changefeed 的 ID。通過 ticdc_cluster_id 和 Changefeed 的 ID 來確 認一個 Changefeed 所插入的 ts-map。

primary_ts:上游數據庫 snapshot 的時間戳。

secondary_ts:下游數據庫 snapshot 的時間戳。

created_at:插入該條記錄的時間。

通過查詢 ts-map 的方式選取之前的時間點進行快照讀。syncpoint_v1 中的 primary_ts,就代表備集羣,當前已經完成的事務,對應到主集羣的時間戳。

資格應用在實時集羣完成一筆業務後,只需要記下業務完成時的時間戳,然後在備集羣中去查詢 tidb_cdc.syncpoint_v1 中 max(primary_ts),如果獲取到的 primary_ts 大於當時業務記錄的完成時間戳,就代表該業務已經在備集羣完成,應用就可以針對該筆業務,計算用戶當前的資格。

因爲資格下游集成了很多子系統,並且 syncpoint_v1 是按照一定的時間間隔更新的,所以沒有必要每筆交易、下游子系統都查詢一次 tidb_cdc.syncpoint_v1,這樣會對數據庫造成性能影響,所以根據業務需求,資格系統將以一定時間間隔讀取 tidb_cdc.syncpoint_v1,緩存 primary_ts,通過緩存提供給下游業務使用。具體流程如下圖所示:

圖 3:啓用 Syncpoint 後的資格落地計算流程

通過以上的流程 ,資格下游的應用就可以準確的得到每筆業務產生的資格更新。Syncpoint 的啓用步驟如下:

  1. 編輯 changefeed.toml,增加如下內容
# 開啓 SyncPoint
enable-sync-point = true
# 每隔 30s對齊一次上下游的 snapshot
sync-point-interval = "30s"
# 每隔 1 小時清理一次下游 tidb_cdc.syncpoint_v1 表中的 ts-map 數據
sync-point-retention = "1h"
  1. 動態啓用配置文件

TiCDC 支持非動態修改同步任務配置,修改 changefeed 配置需要按照 :暫停任務 -> 修改配置 -> 恢復任務的流程

cdc cli changefeed pause -c test-cf --server=http://10.0.10.25:8300
cdc cli changefeed update -c test-cf --server=http://10.0.10.25:8300 --sink-uri="mysql://127.0.0.1:3306/?max-txn-row=20&worker-number=8" --config=changefeed.toml
cdc cli changefeed resume -c test-cf --server=http://10.0.10.25:8300
  1. 獲取 ts-map

在下游 TiDB 中執行以下 SQL 語句,從結果中可以獲取上游 TSO (primary_ts) 和下游 TSO (secondary_ts) 信息。

select  *  from tidb_cdc.syncpoint_v1  limit 1;
+------------------+------------+--------------------+--------------------+--------------------+
| ticdc_cluster_id | changefeed | primary_ts         | secondary_ts       | created_at         | 
+------------------+------------+--------------------+--------------------+--------------------+ 
| default          | test-2     | 435953225454059520 | 435953235516456963 | 2022-09-1308:40:15 | 
+------------------+------------+--------------------+--------------------+--------------------+

獲取當前最後一個一致性的時間戳。

 select max(primary_ts) from  tidb_cdc.syncpoint_v1

注意事項

同個數據庫的多張表,可以通過不同的 changefeed 來進行同步,這樣可以分攤一些 workload,但是由於 syncpoint 一致性是以 changefeed 爲最小粒度的,所以要求,有事務關聯性的所 有表, 必須在同一個 changefeed 裏面同步 。如果涉及多個 changefeed 的情況下 ,取 primary_ts 要帶上 changefeed 字段,如果 TiCDC 還涉及多個 TiDB Cluster 同步數據,那還應該帶上 ticdc_cluster_id,如:

select max(primary_ts ) from tidb_cdc.syncpoint_v1 where changefeed=’test-2’
select max(primary_ts ) from tidb_cdc.syncpoint_v1 where changefeed=‘test-2’and ticdc_cluster_id=‘default’

關於 TiCDC 使用的優化點:

  1. 首先,應用端應該儘量避免使用大事務,TiCDC 只有在源端事務已經提交後,纔會在目標端開始執行事務(源端 pre-write 階段,數據會緩存在 TiCDC,並不會在目標端也 pre-write,只有等到源端提交後,目標端纔開始執行),所以如果源端的事務執行時間比較久,目標端並不一定會比源端執行時間短。
  2. 因爲是分佈式系統,可以通過增加 changefeed 的 worker 的數量,來加快下游同步的速度,具體需要根據業務的實際情況來設定,worker-num 默認爲 16。

關於使用 syncpoint 取到的數據,最大延時計算參考:

tidb_cdc.syncpoint_v1 表中的數據,刷新間隔是按照 sync-point-interval 設置的時間間隔刷新的,所以從該表中獲取的最新快照的時間,最大的延時近似於 sync-point-interval+實際延時。

總結

在需要對 TiCDC 上下游動態變更的數據執行一致性讀取的應用場景中,啓用 Syncpoint 功能是一種有效的解決方案。通過查詢下游 tidb_cdc.syncpoint_v1 表中的 primary_ts 字段,用戶能夠獲取到下游事務的確切完成時間點。這一機制顯著提升了計算的準實時性,確保了數據讀取的時效性,爲用戶提供了可靠的準實時數據處理方案。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章