有贊業務對帳平臺的探索與實踐

1、引子

根據CAP原理,分佈式系統沒法在保證了可用性(Availability)和分區容忍性(Partition)以後,繼續保證一致性(Consistency)。咱們認爲,只要存在網絡調用,就會存在調用失敗的可能,系統之間必然存在着長或短的不一致狀態。在服務化流行的今天,怎樣及時發現系統服務間的不一致狀態,以及怎樣去量化衡量一個系統的數據一致性,成爲每一個分佈式環境下的開發者須要考慮並解決的問題。spring

2、背景

以交易鏈路爲例,存在着以下一些潛在的不一致場景:服務器

  • 訂單支付成功了,可是訂單狀態卻仍是「待付款」
  • 物流已經發貨了,可是訂單上面仍是「待發貨」
  • 銀行退款已經到帳了,可是訂單上面仍是「退款中」
  • 訂單發貨已經超過7天了,可是卻沒有自動完成

上述每一個業務場景,均可能產生用戶反饋,給用戶帶來困擾。業務對帳平臺的核心目的,就是及時發現相似問題,並及時修復。使問題在反饋前即被提早處理。網絡

3、挑戰

那麼一個業務對帳平臺,會面臨着哪些挑戰?架構

圖片描述

咱們對於一個業務對帳平臺的核心訴求,主要包括要方便業務系統快速接入,要能處理業務方海量的數據,並保證必定的實時性。這會深入影響業務對帳平臺的系統設計。併發

4、架構

從局部到總體,本文先從解決上面三個問題的角度,來看有贊業務對帳平臺的局部設計,再來看總體系統結構。異步

4.1 易於接入

咱們認爲全部的對帳流程,均可以分解爲「數據加載」、「轉換解析」、「對比」、「結果處理」這 4 步。爲了適應多樣化的業務場景,其中的每一步都須要作到可編排,放置各類差別化的執行組件。在每個流程節點,須要經過規則能夠自由選擇嵌入哪一個組件。其次,須要把數據從原始格式,轉換到對帳的標準格式(基於標準格式,就能作標準的通用對比器)。總結起來,咱們認爲對帳引擎須要具有如下的能力:分佈式

  • 流程編排能力
  • 規則能力
  • 插件化接入能力

目前業務對帳平臺的對帳引擎結構以下:高併發

圖片描述

其中的 ResourceLoader 、 Parser 、 Checker 、 ResultHandler 均爲標準接口,全部實現了對應接口的 spring bean ,都能被編排到對帳流程之中,包括業務方本身實現的 plugin。這樣就實現了插件化和可編排。每一個流程節點的功能以下:工具

  • ResourceLoader :基於各類數據源(DB、FILE、RPC、REST等)提供加載器工廠,加載各個數據源的原始數據。加載的方式支持驅動加載、並行加載、多方加載等方式。業務方也能夠本身實現加載器,利用流程編排能力嵌入到對帳流程中。
  • Parser :對已加載的原始數據進行建模,轉換爲對帳標準模型。利用規則引擎,提供腳本化(Groovy)的轉換方式。
  • Checker :按照配置對指定字段、按指定規則進行比較,併產生對帳結果。支持 findFirst(找出第一個不一致)、full(找出全部不一致)等對比策略。
  • ResultHandler :使用指定的handler對結果進行處理,常見的處理器包括持久化、發送報警郵件、甚至直接修復數據等等。

經過統一的 facade,將整個對帳流程進行串聯。在執行不一樣節點時,根據配置選擇不一樣的默認組件或者插件來執行。能夠在管理後臺,對每一個流程節點進行編排:大數據

圖片描述

4.2 高吞吐量

一些離線定時對帳場景,單次對帳的數據量可能達到百萬級,甚至千萬級。這對對帳平臺的吞吐量形成了挑戰。咱們面對海量數據問題的一般解決思路,就是「拆」。分佈式任務拆分+單機內任務拆分,將數據塊變小。同時,也能夠利用一些大數據的工具來幫咱們減輕負擔。

圖片描述

目前的對帳有 2 種模式:一種常規模式,是經過數據平臺(包含了全部要進行對帳的原始主鍵數據,如訂單號)將數據 push 到對帳中心的 DB ,而後訂單中心集羣經過分片策略,並按分頁分批加載,加載數據進行對比。另外一種,則是當數據量超過千萬時,利用數據平臺的 spark 引擎從 hive 表中獲取數據,而後投遞到 nsq(自研消息隊列)。nsq 會選擇其中一個 consumer 進行投遞(不會投遞到多個consumer)。這樣千萬級的數據會變成消息被分散的對帳服務器執行。

對帳任務通常會選擇在業務量較小的凌晨進行,是由於在對帳過程當中會須要經過反查業務接口,來獲取實時數據。而更好的狀況是,對帳時能去除對業務接口的反查。所以,會須要對業務數據進行準實時同步,提早進入對帳中心的 DB 集羣。

圖片描述

主要思路是基於業務 DB 的 binlog 日誌或者業務系統自身的消息,進行數據同步。後續流程則相似。

4.3 高實時性

一些特定的業務場景,好比買家已經付款成功了,可是因爲銀行第三方的支付狀態回調延遲,致使訂單狀態仍是待付款。這種狀況,買家會比較焦急,可能產生投訴。面對這樣一些場景,就須要進行實時對帳,也能夠叫作秒級對帳。

秒級對帳每每基於業務消息進行觸發,須要在事件觸發後的短期內執行完對帳任務。且事件消息的觸發,每每具備高併發的特色,所以須要相應的架構來進行支持。

圖片描述

設計中主要加入了 EventPool 來緩衝處理高併發的事件消息,並加入限流、取樣、路由、處理的 pipeline。同時在進入事件處理線程池以前,須要進入阻塞隊列,避免大量的請求直接耗盡線程資源,同時實現事件處理的異步化。處理線程批量定時從阻塞隊列獲取任務來執行。同時,利用延遲阻塞隊列,還能夠實現延遲對帳的特性。(咱們認爲出現不一致的狀況時,若是當即去進行對比,每每仍是不一致的。因此就須要根據狀況,在事件發生後的一段時間內,再觸發對比)

4.4 總體設計

上面介紹了業務對帳平臺的各個局部設計,下面來看下總體結構。

圖片描述

總體上主要採用調度層+對帳引擎(core+plugin)+基礎設施的分層架構。調度層主要負責任務觸發、任務拆分、調度;對帳引擎則負責執行可編排的對帳流程;基礎設置層則提供規則引擎、流程引擎、泛化調用、監控等基礎能力。

5、健康度

對帳中心能夠拿到業務系統及其所在整個鏈路的數據一致性信息。基於此,對帳平臺具有了給予業務系統和鏈路健康度反饋的能力。

圖片描述

6、共建

前面有提到,對帳的流程被拆分爲四個固定的流程節點,且有四個對應的標準接口。經過流程引擎和規則引擎的能力,能夠根據 spring bean name,來將系統默認組件或者插件編排到對帳流程之中。基於這種開放性的設計,業務對帳平臺支持與業務團隊進行共建。

首先,對帳平臺提供標準接口的 API jar 包,業務方經過引入 jar,實現相關接口,並將 impl 打包。這樣,對帳平臺經過 spi 的方式,能夠引入業務方的插件包,並加載到對帳中心的 JVM 中執行。

7、將來

業務對帳平臺,是面向業務場景創建,但同時屬於數據密集型應用。平臺上線以來,已經接入公司各團隊數十個對帳任務,天天處理千萬級的數據。展望將來,業務對帳平臺的使命會從主要進行離線數據分析處理,演進到利用應用系統的健康度數據幫助系統進行實時調整的方向。在分佈式環境下,沒有人能迴避數據一致性問題,咱們對此充滿着敬畏。歡迎聯繫 zhangchaoyue@youzan.com,交流心得。

圖片描述

相關文章
相關標籤/搜索