支付系統中熱點賬戶的性能問題
熱點賬戶類型 |
賬戶屬性 |
實時需求 |
鎖需求 |
處理方式 |
性能 |
業務大賬戶 |
內部賬戶 |
無實時余額查詢 無實時提現 |
無需加鎖 |
異步MQ延時處理 |
滿足 |
大代理商賬戶
|
對外賬戶 |
無實時余額查詢 無實時提現 |
沒有加鎖需求 |
異步MQ延時處理 |
滿足 |
熱門商戶(推廣) |
對外賬戶 商戶賬戶 |
實時余額查詢 實時提現 |
有加鎖需求 |
串行化同步 |
亟待提升 |
一、按業務場景盡量拆分熱點賬戶,分散壓力
1)賬戶拆分,拆分主賬戶
此時解決方法就是再辦一張同行的卡,或者其它銀行的卡,一起承擔存錢和提現的需求
2)新增多個子賬戶,
向銀行申請,為該主卡辦理多個子卡,用子卡進行分流
3)按功能進行划分
申請一個專門接收打款的卡
申請一個專門接受提現的卡
二、異步方式
4)異步隊列延時處理
先把所有的打款、提現的請求入隊列,延時處理賬戶余額更新
5)實在沒招了,合並處理
把某個特征相似的操作進行合並處理。即把別人一萬次打款請求合並為一個打款請求,此時最終只需要申請一次打款,其它人的卡逐個扣款
提現就不好解決了,可以增加一個提現緩沖卡,但是迫不得已,可以把多次提現請求,合並為一個請求,先從該賬戶把錢提到提現緩沖卡,再由提現緩沖卡分發給其它目標賬戶。
支付結算賬戶系統針對上述問題做了如下處理:
我們把熱點賬戶按照金額變動方向分為加頻賬戶(余額增加頻繁)、減頻賬戶(余額扣減頻繁)、雙頻賬戶(余額增加扣減均頻繁)。
加頻賬戶處理
准實時更新余額。先將金額變動插入臨時表中,由定時任務按照一定頻率匯總發生額,並更新賬戶余額,而后刪除臨時記錄。當加頻賬戶減錢余額不足時,主動去匯總發生額。這里需要考慮主動匯總發生額和定時任務處理的並發情況,我們在該定時任務執行時設置redis鎖,防止並發,主動匯總時會去判斷這個redis鎖是否存在,如存在證明定時任務正在執行,無需主動匯總,可能是真的余額不足。主動匯總同樣會設置redis鎖,定時任務同樣會判斷。
減頻賬戶處理
將減頻賬戶拆分多個子賬戶,減頻子賬戶設置金額報警,如果某個減頻子賬戶余額不足觸發報警,會對該子賬戶做資金歸集,將其他子賬戶余額歸集到該子賬戶(每個子賬戶設置可歸集金額限制)。如在交易過程中發現該子賬戶余額不足,轉向使用其他子賬戶記賬。由於拆分子賬戶,余額查詢時需要匯總各個子賬戶余額返回;記錄主賬戶流水需要記賬后余額,這里需要異步計算匯總。當減頻賬戶加錢時,需要平均分配入賬到不通的子賬戶。
雙頻賬戶處理
將雙頻賬戶拆分多個子賬戶。加錢時,准實時更新余額,先將子賬戶金額變動插入臨時表中,由定時任務按一定頻率匯總發生額,將匯總的發生額更新進對應的子賬戶,並刪除金額變動記錄;減錢按照之前減頻賬戶的邏輯執行。
支付寶需要有個賬戶記賬,現在很多業務已經出現了很多熱點賬戶。比如互聯網大商家,\\\
賬號有余額,主要用於不能扣成負數。 大並發交易下余額快速變化,導致數據庫競爭等待。
原則: 不同的業務要求,不同的設計,同時會影響業務需求.
三大需求,是否都容易滿足:
1.減款
2.加款
3.讀取總金額
最簡單設計: 帳戶表+流水表. 每次帳戶加減款都需要增加流水,和帳戶變動.
業務需求: 高並發帳戶.
技術選擇 1. 悲觀鎖(高並發帳戶), 樂觀鎖(普通並發帳戶). 3. 順序化 同步轉異步,mq 降低峰值.
存儲選擇: redis 還是 數據庫. redis本身並發能力就是比數據庫要好. 但是單機支持的數據量不如數據庫大. 只存放account的值的話到還好.
賬戶轉賬分兩個接口,一個可扣成負數,一個不能扣成負數.
1 如何消除余額競爭呢?
方案一:變成兩個賬戶 模仿 擔保交易,設置兩個賬戶 1. 扣款賬戶 2. 加款賬戶
1.1. 商家都是頻繁加款 ,加款賬戶只記流水,不計算余額. 避免頻繁競爭
1.2. 加款帳戶的流水定時匯總到扣款帳戶上.
1.3 扣款賬戶用於退款和提現, 因為頻率不高. 即保證余額控制,也沒有並發問題. 退款有些業務能扣成負數,有些業務不能.
缺點: 進入的錢不一定能時時能用. (對小商家不適用,比較計較)
優點: 這樣就避免了熱點賬戶的余額計算。
方案二: 賬戶分普通賬戶,加頻賬戶,減頻賬戶,雙頻賬戶
類型為加錢頻繁賬戶,加錢不改變余額,定時任務收集改變。 撿錢操作時時進行。
減頻賬戶,拆分子賬戶。
扣款只賬戶會有個問題,前面扣掉了,但是最后不夠扣。
最佳方案,回滾,即逆操作,加款。
次佳方案, 使用只能扣成一次負數
雙頻賬戶:加款依然如此,減款同上。
延遲提現問題:即2天內收入只允許某種業務扣款(內部消費,代駕現金抵扣),但不允許提現扣款。
采用普通賬戶,但是要滿足提現延遲方案?
小商家加的錢必須時時能用. 又要求延遲提現怎么辦?
只能通過訂單維度,目前這個訂單現在有多少錢凍結中(已退款的錢不應該凍結). 展現哪些訂單是凍結的,凍結金額是多少.
一旦錢被消費了, 賬戶余額可能少於訂單的凍結的金額,可提現余額可能為負數.
客戶可能來投訴, 因為他自己意識不到錢被消費了(抵扣信息費)和提現金額變少有關聯.
原文鏈接:https://blog.csdn.net/xiaohanzuofengzhou/article/details/100938038