支付系統中熱點賬戶的性能問題
熱點賬戶類型 | 賬戶屬性 | 實時需求 | 鎖需求 | 處理方式 | 性能 |
業務大賬戶 | 内部賬戶 | 無實時餘額查詢 無實時提現 | 無需加鎖 | 異步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天内收入隻允許某種業務扣款(内部消費,代駕現金抵扣),但不允許提現扣款。
采用普通賬戶,但是要滿足提現延遲方案?
小商家加的錢必須時時能用. 又要求延遲提現怎麼辦?
隻能通過訂單次元,目前這個訂單現在有多少錢當機中(已退款的錢不應該當機). 展現哪些訂單是當機的,當機金額是多少.
一旦錢被消費了, 賬戶餘額可能少于訂單的當機的金額,可提現餘額可能為負數.
客戶可能來投訴, 因為他自己意識不到錢被消費了(抵扣資訊費)和提現金額變少有關聯.