讓“熱點賬戶”清涼一夏

編輯導讀:“熱點賬戶”來源於銀行領域,指的是銀行或支付賬戶等需要進行代收付等業務的中間內部賬賬戶。本文作者圍繞“熱點賬戶”展開分析,提出一些常見的解決思路和案例,希望對你有幫助。

讓“熱點賬戶”清涼一夏

我們經常聽到一個概念“熱點賬戶”,可能很多人不陌生什麼是熱點賬戶,但是對如何解決熱點賬戶問題並沒有系統性的完整的思路。

事物總是發展的,事物所處的場景也是在不斷變化的,基於有限的經驗去解決無限的可能性是很好的技能。我們試圖從認識熱點賬戶開始,再瞭解幾個常見的解決思路和案例,開啟對熱點賬戶的世界。

一、關於賬戶

什麼是賬戶這個話題就不展開討論了,我們之前也寫過很多跟賬戶相關的內容。

瞭解賬戶的結構是“入賬請求、賬戶流水、賬戶餘額”;入賬請求產生了賬戶流水,賬戶流水更新賬戶餘額;所以其中我們要關注賬戶流水的建立以及賬戶餘額的更新,這裡賬戶餘額的更新要重點關注,這是後續造成熱點賬戶發生的主要的環節。

賬戶的賬務處理主要分三類:收錢,付錢,賬戶間轉賬;收錢針對一個賬戶的餘額增加,付款是一個賬戶的餘額減少,轉賬是兩個賬戶之間一個增加一個減少。

讓“熱點賬戶”清涼一夏

賬戶處理的存在最大併發量,超過這個併發量賬務處理就會出問題;賬戶賬務處理過程的執行緒控制,無論是收錢、付錢還是轉賬,為了保證賬務的準確性,每次賬務處理都是一個單獨的事務,就算是多個請求同時發生,對賬戶的操作也是一個一個的來;當一筆入賬請求開始處理時賬戶資源會被加鎖,等該筆請求處理完以後會釋放鎖;這樣的話就意味著每一筆賬務處理都會獲得一個時間佔用,這個時間內其他入賬是不能操作的,這樣就出現了資源的瓶頸,也就是賬戶的入賬必然存在一個併發的最大閾值,一旦超過這個閾值,就會出現賬戶的效能問題。

讓“熱點賬戶”清涼一夏

熱點欄位和熱點事件;在交易併發過程中,有些欄位的使用頻率很高,比如流水號、餘額、發生額等欄位,這些使用頻率很高的欄位稱為熱點欄位;導致熱點欄位的事件稱為熱點事件,比如商家結算日,需要給商家結算付款,這時候造成付款專戶的付款併發,這個就是一個熱點事件。

二、熱點賬戶定義

業務發生以後會產生業務事件,比如下單支付,業務事件需要申請入賬;當在短時間內產生了大量的業務事件,或者狹義的看有大量的交易產生時,造成高併發的入賬請求,高併發引起了賬戶系統的效能瓶頸而產生了效能問題,進而造成入賬延遲、失敗、賬務準確性等各種賬務問題;而這個過程中涉及到的賬戶我們就稱為熱點賬戶;所以說熱點賬戶是由於高併發交易時頻繁更新賬戶產生效能問題而造成的,所以這裡一個關鍵的前提是“高併發”,那麼熱點賬戶的標準是什麼呢,在一些文獻裡提到以下標準。

賬戶每秒有10次以上更新需求

序列化時賬戶處理延遲高於1秒以上

我想熱點賬戶產生的根本機理跟城市交通高峰時段的擁堵地段是一個機理,怎麼解決高峰問題,錯峰出行,限號限流,分流等等;同樣熱點賬戶也是,既然是高併發造成的擁堵,我們就可以以降低賬戶上的併發為目的,也就是降低熱點賬戶的操作併發以降低賬戶熱度;像可以快取記賬,可以批次彙總記賬,可以將賬戶拆分分攤併發,可以進行記賬排隊等等手段都可以降低對賬戶的高併發操作,從而降低賬戶熱度。

三、熱點賬戶常見發生場景

既然產生熱點賬戶的原因是高併發造成的賬戶被頻繁更新,所以我們探索熱點賬戶的發生場景就轉換成了探索交易高併發的場景,這些高併發場景都有可能造成熱點賬戶,比如很容易想到“雙11購物節”“微信發紅包”“某自營電商平臺的秒殺搶購”“小米官網新品的預售”等。

這裡的場景有的是因為高併發收款造成的,有些是高併發付款造成的;而且收款和付款的熱點賬戶解決方案往往會存在差異,不同場景的收款和付款解決方案也會有差異;就像淘寶雙11收款,淘寶中間賬戶其實因為不外漏給使用者,後續商家履約週期也長,所以時效性要求並不高,可以考慮批次定時入賬、非同步入賬、快取入賬等,不採用實時入賬;所以我們可以將業務場景分為高頻入賬場景和高頻扣款場景;像淘寶雙11的中間擔保賬戶就是高頻入賬造成的熱點賬戶。

我們來分析一下淘寶雙11產生熱點賬戶的場景。

我們在淘寶購物時都清楚,錢是不會直接給到商家的,而是先收到中間擔保賬戶,等履約完成以後才會由擔保賬戶結算給商家,所以這裡對於擔保賬戶來說有兩個過程,一個是使用者購買商品時的收款,另一個是服務履約以後的結算付款,而其中雙11期間的使用者付款就成了熱點事件,從而中間擔保賬戶的收款造成了擔保賬戶成為熱點賬戶。

讓“熱點賬戶”清涼一夏

上面我們介紹了,淘寶擔保賬戶是內部賬戶,並不外漏給使用者或者商家,這樣的話,只需要實時告訴使用者和商家已經付款成功即可,至於擔保賬戶的入賬可以慢慢的處理;這裡我們也得到了一個思路,解決熱點賬戶要關注兩個問題。

一個是給使用者的反饋:對交易參與者的反饋策略,參與者需不需要實時知道賬戶的處理情況,是隻需要知道結果即可還是需要實時看到賬戶餘額的變化,顯然對於淘寶中間賬戶來說,賬戶參與者是不需要知道賬戶餘額更新情況的,只需要知道支付成功的反饋結果即可,而這個結果可以依賴渠道的反饋通知,而內部記賬可以不反饋給使用者,這樣的話擔保賬戶就有了足夠的時間和選擇來規避併發問題。

另一個是賬務要求:賬務更新時效性要求高不高,賬務的準確性要求高不高,這裡中間擔保戶對時效性要求不高,準確性肯定是所有賬戶要求都是很高的。

這樣我們可以使用批次的延遲更新中間擔保賬戶的方式來規避雙11高併發交易的入賬請求,以規避熱點賬戶的發生。

這裡我們要知道個事實,資料庫插入資料的併發支援是非常大的,一般不會造成資料庫效能問題,批次插入即可,只是更新賬戶餘額需要進行鎖處理,會造成效能問題,所以解決淘寶中間賬戶的關鍵是解決賬戶餘額更新問題。

首先我們先將高併發的交易的入賬請求插入到入賬流水錶,這時並不著急去更新中間擔保賬戶餘額,此時這些流水我們標記一個入賬狀態“未入賬”;定時的去掃描這個流水錶,將掃描到的資料進行加鎖,確保不會被後續入賬或其他處理影響,然後彙總求和,用這個求和的總值去更新中間擔保賬戶的餘額,然後將這一批“未入賬”流水更新為已入賬,然後釋放鎖,這樣就以很小的併發完成了對中間賬戶的更新。

讓“熱點賬戶”清涼一夏

下面我們介紹幾種常見的解決熱點賬戶的方案,並且針對每個方案我們列舉一個實際的案例為補充;對於熱點賬戶的方案設計過程中,我們需要重點關注幾個問題:

收支:賬戶是收入熱點賬戶還是支出熱點賬戶

內外:賬戶是使用者熱點賬戶還是內部熱點賬戶

時效:賬戶是高時效性實時入賬還是不需要高時效性

結果:使用者是否需要實時知道入賬結果還是不需要

餘額:使用者是否需要實時知道賬戶餘額更新還是不需要

對於方案的設計和選擇可以先做以上幾個方面的分析,然後選擇合適的解決方案;比如上面淘寶中間擔保賬戶對時效性要求不高,使用者不需要感知餘額的場景我們就可以選擇延遲批次彙總入賬。

對於方案的設計,我們就可以基於以上幾個問題從解決“賬戶的單位併發”為核心突破點,因為併發造成的頻繁更新是熱點賬戶產生的根本原因,所以解決的熱點賬戶併發的問題也就可以解決熱點賬戶的問題。

四、限號限流-直接控制併發

第一性原理,不想太多,直接解決產生問題的問題本身;併發不是造成熱點賬戶麼,那麼反向思考,這個併發閾值是多少,在賬戶之前設到屏障控制這個閾值,開閘放水,門就這麼大,只能進來這麼多水,就像很多城市的限號限流一樣,最終的結果肯定是損害一部分車主的體驗;雖然是立竿見影的效果,但是這也是自損800的方案;這裡我們不妨稱之為“熱點閥”。

讓“熱點賬戶”清涼一夏

所以給賬戶安裝“熱點閥”可以解決熱點賬戶問題;但是問題還是比較明顯的,除非你很強勢,比如交通控制,否則以服務為第一客戶優先的企業這種方式一般不會採用。

五、變多為少-明細彙總記賬

資料庫插入資料是可以支援非常高併發,可能達到3。2w/s,所以插入流水不是熱點賬戶瓶頸所在,而是餘額更新;所以我們就將“降低賬戶的單位併發”設計思路縮小到了“降低餘額更新併發”的範圍;對於餘額更新就是基於流水去增加或者減少餘額,瞭解C語言的應該知道,無非就是下面的這個函式(不一定準確,但是這麼個意思)。

balance=balance+發生額

就像新餘額等於當前餘額加上或減去該流水的發生額,降低餘額的更新頻率我們自然就可以想到,可以降低發生額的更新頻率,也就是你們這個多人來更新我,我實在是忙不過來,都堵在門口,不如你們派一個代表10分鐘進來一次,彙總大家的要求我一次性解決;這樣就是我們說的“彙總明細記賬”的方法,這樣的話這個函式從意義上就變成了。

balance=balance+sum(一段時間內全部明細的發生額)

讓“熱點賬戶”清涼一夏

這個方案的適用場景就是不需要實時更新餘額,且主要是增加賬戶餘額的場景如果是扣款類場景,可能彙總入賬會造成賬戶餘額透支,不過如果允許賬戶透支,出款類場景也是可以考慮,只不過對資金管理的時效就會變差,你無法從賬戶餘額直接看到剩餘可用頭寸。

六、排隊辦理-緩衝記賬

現在大家經常做核酸,因為併發較大,檢測人員有限不能實時採集樣本,所以大家需要排一個很長的隊伍;同時因為一個人一個人檢測成本也高,效率也低,所以10個人一組進行混採;混採就像我們上面說的指派代表的彙總記賬一樣;所以說我們可以為賬戶設定一個排隊機制,出現高併發賬戶更新不過來時大家進行排隊辦理。

讓“熱點賬戶”清涼一夏

就算排隊可以解決賬戶的併發問題,但是肯定是有天花板的,就像10個人取樣,100萬人排隊,那要做到什麼時候,也可能發生抱怨和投訴;所以怎麼辦呢?增加檢測點是一個很好的辦法,1000個人取樣,就可以分攤這麼多的要檢測的排隊的人;這就是我們下面要講的“子賬戶拆分”分攤壓力。

七、臨時存放點-快取入賬

高併發請求可以先進行快取,然後定時將快取更新到資料庫;這個看起來跟緩衝記賬異曲同工,但這裡有個區別,緩衝記賬時賬務請求還在排隊入賬,而快取記賬實際上賬務請求已經實時在快取中完成了記賬;快取記賬具備緩衝記賬和彙總明細記賬的雙重優點。

讓“熱點賬戶”清涼一夏

這裡要注意因為快取需要具備賬戶餘額部分的管理,所以賬戶系統的餘額要賦予快取模組,快取模組在此餘額基礎上進行出金和入金的記賬操作;定期將快取同步到賬戶系統完成最終的記賬,記賬完成的快取部分可以進行清空,然後獲得最新的賬戶餘額,以此迴圈。

八、增加點位-子賬戶拆分

當即要解決高併發的熱點賬戶問題又要保證實時性要求時,上面的會影響賬戶更新時效的方案自然就不是首選了,那麼就需要一個能夠支援實時餘額更新的方案了;既然一個賬戶的更新出現了瓶頸,那是不是可以考慮為他找更多的幫手分攤壓力呢?答案是肯定的;我們可以將賬戶進行按需拆分,拆分成多個子賬戶,將高併發請求分配給各個子賬戶,從而每個子賬戶的併發就降下來了;這裡要明確一個問題,這個子賬戶更多是不能讓使用者感知的,只是內部的處理方案,對使用者來說還是一個賬戶,所以流水和賬戶餘額反映給使用者的都是一個;這就意味著:

賬戶作為一個整體被使用者感知。

讓“熱點賬戶”清涼一夏

這樣的話勢必要增加很多賬戶設計的複雜程度,比如入賬的時候入哪個子賬戶,是平均入賬還是按序入賬,出賬的時候怎麼出,有個別子賬戶餘額不足但是總賬戶餘額充足時怎麼處理;所以說這裡會有一個複雜的賬務處理模型;不管這個模型怎麼設計,要保證金業務上順利完成賬務記錄要求以及使用者的使用體驗,從而確保業務的正常進行。

我之前設計的賬戶系統,每個商家可能會有七八個子賬戶,出款的時候是按照順序出款,就是先扣完一個賬戶扣下一個賬戶。

想起在某支付機構做了斷直連線入網聯的改造專案,其實網聯的專案方案裡提到了其要作為人行支付系統的前置系統做人行熱點賬戶系統的前置緩衝,我想這個設計方法是不是可以借鑑到工作當中。

九、小弟先上-前置緩衝

為解決備付金集中存管所形成的熱點賬戶問題,實現對已對映額度管理,網聯構建了“備付金熱點賬戶前置系統”即“RCMP”,用於支付機構透過網聯平臺(EPCC)的業務辦理。

讓“熱點賬戶”清涼一夏

前置系統分為額度管理模組及賬戶管理模組,網聯將為各支付機構在前置系統中建立賬戶,用於可用額度的監控、已對映額度的管理。

因為網聯是“實時清算,定時結算”,在一個清算週期內淨額軋差了支付機構的支付指令,最後提交給人行的結算請求筆數一個週期從每個機構的上千萬筆到一筆,這個看起來有點像彙總明細記賬,而這個彙總處理的操作是網聯代人行支付系統完成的。

那這麼看,是不是我們工作當中也需求這樣一個前置系統,來幫助賬戶系統完成壓力的分擔,比如要求業務方建設前置模組,按照要求進行處理加工後請求入賬;特別是賬戶中臺,面對眾多業務線時,是不是可以考慮每個業務線在某些場景下都做賬戶前置,完成初步加工後再請求中臺賬戶系統,這樣就可以分擔中臺的壓力,又不損害賬戶的中臺核心能力,業務線也不用完整建設賬戶系統;這裡的思路就是中臺不能一攬子大包,一些能力要分攤給業務線,比如業務線的個性化部分,需要業務線做前置層。

十、打鐵還需自身硬-技術性能升級

技術層面就不過多討論了,作為非專業人士,或者說產品視角提些建議“能多增加幾臺伺服器麼,可以擴充下硬碟麼,你這個cpu可不可以換成頂尖的……”

事物總是變化的,場景也是不斷地更新,面對新的場景,新的問題,歷史的經驗只能作為解決新問題的參考;不妨在遇到虛擬問題時多思考一下真實的世界,也許會有意料之外的答案!

#專欄作家#

陳天宇宙,微信公眾號:陳天宇宙,人人都是產品經理專欄作家。多平臺支付領域專欄作者,十年資深產品;天使投資人;專注為10萬支付產品經理和支付機構以及企業提供深度支付內容和服務!

本文原創釋出於人人都是產品經理。未經許可,禁止轉載。

題圖來自Unsplash,基於CC0協議。

頂部