面试官:做过支付资产?那先聊聊热点账户吧
背景
當(dāng)前形勢(shì)不佳,在這種情況下。小貓更是雪上加霜,他被裁了。投了個(gè)把月簡(jiǎn)歷,終于約到一個(gè)面試。
面試官翻了一下簡(jiǎn)歷:“看你簡(jiǎn)歷上寫(xiě)了支付和賬戶(hù)相關(guān)項(xiàng)目,那能否聊一下熱點(diǎn)賬戶(hù)問(wèn)題你們是咋處理的吧”。
小貓懵逼了一會(huì),“額?什么是熱點(diǎn)賬戶(hù)?我們好像模型里面就一個(gè)資產(chǎn)賬戶(hù),然后充值的時(shí)候和消費(fèi)的時(shí)候更新一下該賬戶(hù),并且記錄一下操作明細(xì),然后結(jié)束了?!?/p>
面試官:“哦?;厝サ韧ㄖ伞!?/p>
出來(lái)之后,小貓整個(gè)人都還是懵逼的。
問(wèn)題分析
我們一起來(lái)看一下這樣一個(gè)問(wèn)題,其實(shí)這里面試官想要知道的是,在高并發(fā)的情況下,針對(duì)熱點(diǎn)賬戶(hù)如何進(jìn)行賬戶(hù)金額的沖扣,小貓沒(méi)有g(shù)et到面試官的點(diǎn),可能他負(fù)責(zé)的項(xiàng)目中本身的量不大,壓根就沒(méi)有想過(guò)這類(lèi)問(wèn)題。如果問(wèn)的是你,你該如何應(yīng)對(duì)呢?
接下來(lái),咱們一起從以下幾點(diǎn)來(lái)剖析一下這個(gè)問(wèn)題吧。
什么是熱點(diǎn)賬戶(hù)?
熱點(diǎn)賬戶(hù)一般指被高頻更新的賬戶(hù),比如短時(shí)間內(nèi)大量的賬戶(hù)余額更新請(qǐng)求集中在極少數(shù)賬戶(hù)上。這類(lèi)賬戶(hù)雖然數(shù)量不多,但更新頻率很高,處理不當(dāng)可能會(huì)帶來(lái)嚴(yán)重的性能問(wèn)題,影響其他賬戶(hù)的正常讀寫(xiě)操作。
我們來(lái)看一下熱點(diǎn)商家賬戶(hù)S的例子,可能更容易讓人理解。大量請(qǐng)求并發(fā)打到我們數(shù)據(jù)庫(kù)底層表的時(shí)候,底層賬戶(hù)S究竟發(fā)生了什么。假設(shè)我們現(xiàn)在有用戶(hù)A、用戶(hù)B、用戶(hù)C,等等可能更多,另外有一個(gè)商家賬戶(hù)S,我們暫時(shí)枚舉三個(gè),那么當(dāng)其同時(shí)并發(fā)打到底層數(shù)據(jù)庫(kù)的時(shí)候,就有如下圖所示。
上圖中我們可以看到,對(duì)于同一個(gè)商家賬戶(hù)S,由于實(shí)際的業(yè)務(wù)需要更新可用賬戶(hù)余額,所以單筆沖扣都是在一個(gè)事務(wù)中進(jìn)行的,任何的更新行為都會(huì)對(duì)數(shù)據(jù)庫(kù)上行鎖。由于并發(fā)量大,請(qǐng)求的數(shù)量又多,大家很容易就能想到鎖的等待問(wèn)題會(huì)嚴(yán)重影響性能。
熱點(diǎn)賬戶(hù)的分類(lèi)
上述我們知道了什么是熱點(diǎn)賬戶(hù),并且知道了熱點(diǎn)賬戶(hù)產(chǎn)生的原因。
其實(shí)熱點(diǎn)賬戶(hù)根據(jù)資金的出入可以分成三種。
-
雙頻賬戶(hù) :上圖中我們看到商家賬戶(hù)既有出也有入,那其實(shí)這樣的賬戶(hù)就可以理解為雙頻賬戶(hù)。
雙頻賬戶(hù)指入賬頻次以及出賬頻次都很高的賬戶(hù)。 -
加頻賬戶(hù): 大家可能可快就知道了還有純?nèi)胭~頻次高的,那么這個(gè)就是加頻賬戶(hù)。
-
減頻賬戶(hù): 純出賬的賬戶(hù)那么即為減頻賬戶(hù)。
針對(duì)這樣的三種賬戶(hù)類(lèi)型,大家其實(shí)可以聯(lián)想一下這些賬戶(hù)對(duì)應(yīng)哪些生活中的場(chǎng)景。歡迎大家在評(píng)論區(qū)留言。
熱點(diǎn)賬戶(hù)解決方案
透過(guò)現(xiàn)象看本質(zhì),其實(shí)要解決熱點(diǎn)賬戶(hù)問(wèn)題,其實(shí)就是解決數(shù)據(jù)庫(kù)壓力過(guò)大,數(shù)據(jù)庫(kù)表更新失敗,執(zhí)行效率過(guò)低的問(wèn)題。那么解決該類(lèi)問(wèn)題,閣下該如何應(yīng)對(duì)?(其實(shí)小貓如何可以理解面試官的用意,解決方案應(yīng)該可以想到幾個(gè))
提升硬件設(shè)備性能
如果數(shù)據(jù)庫(kù)壓力過(guò)大,數(shù)據(jù)庫(kù)執(zhí)行效率低,最簡(jiǎn)單的方式就是調(diào)整硬件設(shè)備唄。把連接池優(yōu)化,把CPU優(yōu)化,把磁盤(pán)優(yōu)化,內(nèi)存優(yōu)化等等。在此不展開(kāi)贅述。老貓給他定義了個(gè)別名“大力出奇跡法”。
限流法
這種其實(shí)也很簡(jiǎn)單,但是有點(diǎn)粗暴,數(shù)據(jù)庫(kù)壓力大,那么咱們就讓流量少一點(diǎn)打到數(shù)據(jù)庫(kù)層唄。做個(gè)限流不就結(jié)了么。
這種方式無(wú)論是上述那種類(lèi)型的熱點(diǎn)賬戶(hù),顯然都支持這種優(yōu)化方法。
但是用戶(hù)能滿(mǎn)意么?買(mǎi)個(gè)東西老半天,重試好久都是支付失敗,用戶(hù)估計(jì)會(huì)跳起來(lái)吧。
這種犧牲用戶(hù)體驗(yàn)的方案不是一點(diǎn)用處都沒(méi)有,這種其實(shí)完全可以配合其他方案一起,作為一種最終的兜底方案。
預(yù)寫(xiě)記賬日志(WAL-Write Ahead Log)
很多中間件類(lèi)似于zk、etcd、es等,包括mysql底層以及很多的操作系統(tǒng)其實(shí)都用到了WAL的思想,感興趣的小伙伴可以找一下相關(guān)資料。我們也借鑒這種思想,mysql在執(zhí)行insert語(yǔ)句的時(shí)候的效率,其實(shí)要比Update執(zhí)行效率高得多,更新的時(shí)候需要獲取讀和寫(xiě),但是insert只需要執(zhí)行順序插入即可。因此咱們就有了下面了這樣的設(shè)想方案。
我們先將賬務(wù)明細(xì)插入到MySQL中,再讀取明細(xì),完成賬戶(hù)底層的更新動(dòng)作。
- 優(yōu)點(diǎn): 實(shí)時(shí)的交易全部是insert賬務(wù)明細(xì),能大大提高入賬速度,賬戶(hù)最終更新的頻度我們可以自行把控,減少并發(fā)帶來(lái)的壓力。
- 缺點(diǎn): 賬戶(hù)更新存在延遲,這樣的話(huà)有可能會(huì)造成賬戶(hù)透支的風(fēng)險(xiǎn)。
- 適用: 所以這種方案加頻類(lèi)型的熱點(diǎn)賬戶(hù)非常適用,但是對(duì)于減頻賬戶(hù)以及雙頻賬戶(hù)就需要結(jié)合具體業(yè)務(wù)慎重考慮,因?yàn)闀?huì)存在賬戶(hù)透支可能。
異步削峰緩沖記賬
我們預(yù)寫(xiě)記賬方式其實(shí)通過(guò)異步把控頻率進(jìn)行更新賬戶(hù),異步削峰模式其實(shí)和上述模式有點(diǎn)類(lèi)似,說(shuō)到削峰填谷大家很容易就能想到消息隊(duì)列,于是就有了我們下面的這種方案。
采用消息隊(duì)列的方式,可以緩解突然到來(lái)的大流量。消息多的時(shí)候會(huì)堆積在隊(duì)列中,然后被消費(fèi)慢慢更新下去。
- 優(yōu)點(diǎn):避免了突增的流量給系統(tǒng)帶來(lái)的沖擊。
- 缺點(diǎn):賬戶(hù)更新并不是及時(shí)的,另外的話(huà),如果程序處理不當(dāng)或者其他原因,會(huì)造成消息丟失,從而造成記賬錯(cuò)誤,同樣也存在賬戶(hù)透支風(fēng)險(xiǎn)。
- 適用:對(duì)于加頻類(lèi)型的賬戶(hù)比較適用,對(duì)于減頻賬戶(hù)以及雙頻賬戶(hù)慎用,同樣也會(huì)存在賬戶(hù)透支風(fēng)險(xiǎn)。譬如加頻場(chǎng)景:在B端收單賬戶(hù)與業(yè)務(wù)中間賬戶(hù)處理;減頻場(chǎng)景在C端微信、頭條等春節(jié)搶紅包入賬處理(注意賬戶(hù)透支風(fēng)險(xiǎn))。
匯總明細(xì)記賬
關(guān)于該方案其實(shí)思路是這樣的,既然多次頻繁更新賬戶(hù)余額成為瓶頸,那么我們就將多次更新統(tǒng)計(jì)之后轉(zhuǎn)換為一次更新。如下圖:
這種基于統(tǒng)計(jì)之后更新賬戶(hù)余額的行為,也是異步進(jìn)行的。所以?xún)?yōu)缺點(diǎn)當(dāng)然也是顯而易見(jiàn)的。
- 優(yōu)點(diǎn):化多次賬戶(hù)余額更新操作為一次,減少了數(shù)據(jù)庫(kù)的讀寫(xiě)操作。
- 缺點(diǎn):由于是異步進(jìn)行,交易其實(shí)并不能實(shí)時(shí)入賬,如果是減頻賬戶(hù)場(chǎng)景的話(huà),也還是會(huì)有賬戶(hù)透支風(fēng)險(xiǎn)。
- 適用:非常適用加頻熱點(diǎn)賬戶(hù),對(duì)于減頻賬戶(hù)以及雙頻賬戶(hù)慎用。
賬戶(hù)拆分記賬
既然單個(gè)賬戶(hù)寫(xiě)入的時(shí)候壓力過(guò)大,那么我們就將單個(gè)熱點(diǎn)賬戶(hù)拆分成多個(gè)子賬戶(hù)去分散每個(gè)賬戶(hù)的讀寫(xiě)壓力。
這種方案只要能夠處理好扣款時(shí),子賬戶(hù)余額不夠扣,資金歸集處理得好,那么問(wèn)題其實(shí)也能夠得到很好的解決。
- 優(yōu)點(diǎn):分散了單個(gè)熱點(diǎn)賬戶(hù)的寫(xiě)入量。
- 缺點(diǎn):子賬戶(hù)扣款的時(shí)候余額扣款處理需要做資金歸集,可能出現(xiàn)扣款失敗,但是如果歸集做的好,那么其實(shí)問(wèn)題也不大。
- 適用:這種方案適用于所有類(lèi)型的熱點(diǎn)賬戶(hù)類(lèi)型。
緩存記賬
Mysql的讀寫(xiě)能力不好,那么我們就去尋找比Mysql讀寫(xiě)效率更高的中間件,將結(jié)果預(yù)先計(jì)算好,那么我們很容易就想到了用非關(guān)系型數(shù)據(jù)庫(kù)作為前置賬戶(hù),比如redis,讓計(jì)算結(jié)果先在redis中計(jì)算完成,然后最終異步flush到mysql中。
- 優(yōu)點(diǎn):緩存的吞吐量遠(yuǎn)遠(yuǎn)高于mysql,而且速度很快。
- 缺點(diǎn):數(shù)據(jù)容易丟失。
- 適用:這種方案適用于熱點(diǎn)賬戶(hù)的任意一種類(lèi)型,但是由于其數(shù)據(jù)準(zhǔn)確性的考慮,往往對(duì)金額不是那么敏感的可以采用該方法,例如刷短視頻得積分這種場(chǎng)景。可以采用該類(lèi)方案。
總結(jié)
相信很多小伙伴在一些中小型的企業(yè),面對(duì)高并發(fā),高流量其實(shí)很多時(shí)候都沒(méi)有機(jī)會(huì)接觸到的,雖然很多時(shí)候都是在實(shí)現(xiàn)非常基礎(chǔ)的功能,但是大家有沒(méi)有設(shè)想過(guò)把當(dāng)前的業(yè)務(wù)放在大流量,大并發(fā)的場(chǎng)景下,又會(huì)存在什么樣的問(wèn)題?其實(shí)很多時(shí)候有了前瞻思考,可能才會(huì)有更好的進(jìn)步,面對(duì)突如其來(lái)的問(wèn)題才能成竹于胸,小伙伴們,你們覺(jué)得呢?當(dāng)然如果小伙伴們還有其他更好的方案或者是更好的工具推薦也歡迎大家在評(píng)論區(qū)留言,相互交流,一起進(jìn)步。
總結(jié)
以上是生活随笔為你收集整理的面试官:做过支付资产?那先聊聊热点账户吧的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 文心一言 VS 讯飞星火 VS chat
- 下一篇: 【scikit-learn基础】--『监