天天看點

支付對賬系統序章:千萬級資料對賬怎麼這麼難?

支付對賬

很早 之前寫過一篇支付對賬相關文章,那時候負責對賬系統日均處理數量比較小。

那最近正在接手現在的對賬系統,由于目前系統日均數量都在千萬級,是以對賬系統架構與之前架構完全不一樣。

那就這個話題,聊聊如何實作千萬級資料支付的對賬系統。

什麼是對賬?

我們先來回顧下什麼是對賬?

也許你對對賬這個概念比較模糊,但是這個場景你肯定碰到過。

上班路上買了一個煎餅,加了根裡脊與王中王,然後你掃了老闆的二維碼付了 10 元錢。

你跟老闆說你已經付了 10 元錢,老闆看了下手機,果然有一條 10 元支付記錄,老闆确認收到錢,然後就把煎餅給你。

這個過程,你說你付了 10 元,老闆确認收到 10 元,這就是一隻簡單的對賬過程。

回到我們支付場景,使用者下單使用微信支付 100 元購買了一個狗頭抱枕,這時我們這邊會生成一條支付記錄,同時微信支付也會生成記錄。

那微信第二天就會生成一個賬單記錄,我們拿到之後把我們的交易記錄跟微信記錄逐筆核對,這就是支付對賬。

為什麼需要對賬?

正常支付的情況下,兩邊(我們/第三方支付管道)都會産生交易資料,那支付對賬過程,兩邊資料一緻,大家各自安好,不用處理什麼。

但是有些異常情況下,可能由于網絡問題,導緻兩邊資料存在不一緻的情況,支付對賬就可以主動發現這些交易。

對賬可以說支付系統最後一道安全防線,通過對賬我們可及時的對之前支付進行糾錯,避免訂單差錯越積越多,最後财務盤點變成一筆糊塗賬。

支付對賬系統

開篇先來一張圖,先來看下整體對賬系統架構圖:

支付對賬系統序章:千萬級資料對賬怎麼這麼難?

整個對賬系統分為兩個子產品

  • 對賬子產品
  • 差錯子產品

對賬子產品,主要負責對賬檔案拉取,資料解析,資料核對,資料彙總等任務。

差錯子產品是對賬子產品後置任務,對賬子產品核對過程産生無法核對成功的資料,這類資料件将會推送給差錯系統。

差錯系統将會根據規則生成差錯訂單,營運人員可以在背景處理這列資料。

今天這篇文章先不聊具體的系統設計,先來回顧下之前的對賬系統設計,簡單了解下對賬的整體流程。

對賬系統設計

對賬系統如果從流程上來講,其實非常簡單,引用一下之前文章流程圖:

https://studyidea.cn/articles/2019/08/26/1566790305561.html

支付對賬系統序章:千萬級資料對賬怎麼這麼難?

整體流程可以簡單分為三個子產品:

  • 本端資料處理
  • 對端資料處理
  • 本端資料與管道端資料核對

本端資料指的是我們應用産生的支付記錄,這裡根據賬期(交易日期)與管道編号擷取單一管道的所有支付記錄。

對端資料指的是第三方支付管道支付記錄,一般通過下載下傳對賬檔案擷取。

支付對賬系統序章:千萬級資料對賬怎麼這麼難?

由于每個管道下載下傳方式,檔案格式都不太一樣,對端資料處理的時候需要将其轉化統一資料格式,标準化在入庫存儲。

網上找了一份通用賬單,可以參考:

支付對賬系統序章:千萬級資料對賬怎麼這麼難?

對端資料轉化存儲之後,對賬流程中,對端資料也需要跟本端資料一樣,擷取目前賬期下所有記錄。

兩端資料都擷取成功之後,接下來就是本地資料逐筆核對。

核對流程可以參考之前寫的流程:

支付對賬系統序章:千萬級資料對賬怎麼這麼難?

上面流程其實也比較簡單,翻譯一下:

查找本端資料/對端資料,然後轉化存儲到 Map 中,其中 key 為訂單号,value 為本端/對端訂單對象。

然後周遊本端資料 Map 對象,依次去對端資料 Map查找。如果能查找到,說明對端資料也有這筆。這筆核對成功,對端資料集中移除這筆。

如果查找不到,說明這筆資料為差異資料,它在本端存在,對端不存在 ,将其移動到差異資料集中。

最後,本端資料周遊結束,如果對端資料集還存在資料,那就證明這些資料也是差異資料,他們在對端存在,本端不存在 ,将其也移動到差異資料集中。

PS:上述流程存在瑕疵,隻能核對出兩邊訂單互有缺失的流程 ,但是實際情況下還會碰到兩邊訂單都存在,但是訂單金額卻不一樣的差異資料。這種情況有可能發現在系統 Bug,比如管道端上送金額機關為元,但是實際上送金額機關為分,這就導緻對賬兩端金額不一緻。

之前對賬系統日均處理的支付資料峰值在幾十萬,是以上面的流程沒什麼問題,還可以抗住,正常處理。

但是目前的支付資料日均在千萬級,如果還是用這種方式對賬,目前系統可能會直接崩了。。。

千萬資料級帶來的挑戰

第一個,查詢效率。

本端/對端資料通過分頁查詢業務資料表擷取當天所有的資料。随着每天支付資料累計,業務表中資料将會越來越多,這就會導緻資料查詢變慢。

實際過程我們發現,單個管道資料量很大的情況下,對賬完成需要一兩個小時。

雖然說對賬是一個離線流程,允許對賬完成時間可以久一點。但是對賬流程是後續其他任務的前置流程,整個對賬流程還是需要在中午之前完成,這樣營運同學就可以在下午處理。

第二個問題,OOM。

上面流程中,我們把把全部資料加載到記憶體中,小資料量下沒什麼問題。

但是在千萬級資料情況下,資料都加載到記憶體中,并且還是加載了兩份資料(本端、對端),這就很容易吃完整個應用記憶體,進而導緻 Full GC,甚至還有可能導緻應用 OOM。

而且這還會導緻級聯反應,一個任務引發 Full GC,導緻其他管道對賬收到影響。

第三個問題,性能問題。

原先系統設計上,單一管道對賬處理流程隻能在單個機器上處理,無法并行處理。

這就導緻系統設計伸縮性很差,伺服器資源也被大量的浪費。

千萬資料級對賬解決辦法

上面系統代碼,實際上還是存在優化空間,可以利用單機多線程并行處理,但是大資料下其實帶來效果不是很好。

那主要原因是因為發生在系統架構上,目前系統使用底層使用 MySQL 處理的。

傳統的 MySQL 是 OLTP (on-line transaction processing),這個結構決定它适合用于高并發,小事務 業務資料處理。

但是對賬業務特性動辄就是百萬級,千萬級資料,資料量處理非常大。但是對賬資料處理大多是一次性,不會頻繁更新。

上面業務特性決定了,MySQL 這種 OLTP 系統不太适合大資料級對賬業務。

那專業的事應該交給專業的人去做,對賬業務也一樣,這種大資料級業務比較适合由 Hive、Spark SQL 等 OLAP去做。

總結

今天本篇文章隻是一個序曲,主要聊聊對賬業務基本流程,聊聊之前系統架構在大資料下存在的問題。

後面文章再會介紹下大資料下對賬系統如何設計,對賬之後差錯資料如何處理,盡請期待。

繼續閱讀