交易對賬算法 原

一、目前對賬的算法:

1、從上游渠道(銀行、銀聯等金融機構)獲取對賬文件,程序逐行解析入庫

2、在存儲過程中,以上游對賬文件的表爲基準,程序逐行讀取並與我們系統的交易記錄/賬務記錄(有賬務系統情況下,合理方案應該是於賬務記錄)對比,查找出差異記錄。

3、以我們系統的交易記錄/賬務記錄爲基準,程序逐行讀取與上游對賬文件對比,查找出差異記錄

二、目前對賬算法問題:

1、使用存儲過程,對賬過程都在數據庫端完成,對數據庫性能影響較大,而且對賬邏輯擴展極爲麻煩

2、逐行比對算法效率較低,但算法上並無好的優化餘地。如果採用數據庫INTERSECT、MINUS對數據庫壓力也高。

3、在業務量大的情況下(例如有上百家上游渠道需要對,每一家都有幾十萬條交易記錄),對賬服務器及數據庫服務器負荷較高。即便採用讀寫分離,對賬時候使用讀庫,壓力一樣很大。

4、導入批量文件,逐行入庫效率較爲低下(每一次都需要建立網絡連接、關閉連接)

三、對賬算法優化思路:

1、涉及網絡傳輸的,儘量採用批量方式操作,減少網絡消耗及時間消耗

2、使用Redis等NOSQL數據庫,降低數據庫服務器的壓力。同時在擴展上也容易,一臺Redis服務器不夠,可以無限制增加用於對賬用的服務器。

3、使用Redis的set集合的sdiff功能,利用Redis sdiff算法的高性能,比對上游記錄和我方記錄的差異

四、對賬算法說明:

1、利用Oracle/Mysql的load data infile將對賬文件批量導入到數據庫

2、程序讀取上游賬務記錄表,對上游賬戶記錄執行select  concat(channel_id, “:” , order_id , “:” , HASH_MD5(channel_id , order_id , amount , status , timestamp1 , timestamp2 ,…) )  as hashid from table ,得到對應的SET集合。

這裏思路是將需要對賬的記錄拼成格式爲:channel_id:order_id:hashid形式的串,以便作爲Redis SET集合的item。

其中channel_id和order_id用於標識對應的渠道及訂單,只是例子,根據實際需要補充。之所以要在hashid前面帶上channel_id和order_id,主要目的是在sdiff後,能夠作爲主鍵,根據set結合的item查找出對應的數據庫記錄。

3、對我方的交易記錄表/賬戶歷史表採用上一步的類似算法,得到對應的SET結合

4、採用Redis的pipeline功能(Redis的各種客戶端,包括java客戶端jedis 都提供此功能),將上游賬務記錄SET集合和我方的交易記錄/賬務歷史記錄SET集分別批量執行sadd插入Redis,得到兩個SET集合。

由於單條記錄sadd 插入Redis效率較差(每一次都涉及網絡open、close、傳輸消耗),因此使用Redis的pipeline功能,已實現批量入庫功能。

可以參考: http://redis.io/topics/mass-insert

5、利用redis的sdiff功能查找出上游賬務集合與我方記錄集合的差值

6、從sdiff 集合中channel_id:order_id:hash,定位對應的數據庫記錄,更新對賬狀態。

具體性能及實現可以在實現後測試對比一下,應該會有大幅的性能提升。

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