熱點賬戶問題和常用解決方案【上】
熱點賬戶:顧名思義,就是會被高頻操作的賬戶!相較於普通的賬戶,熱點賬戶相對數量不多,但操作頻率極高!
熱點賬戶從產生角度又可分兩大類:
- 富二代型:從產生之初就是熱點賬戶,非常穩定。例如 財務中公司的賬戶 ,每一筆資金操作都要經過公司出金賬戶,自然而然操作就會灰常頻繁,此類賬戶還包括: 大V賬戶 , 大KA賬戶 等,此類賬戶所引起的問題是本文重點要解決的
- 暴發戶型:本是普通賬戶,由於熱點問題變為熱點帳戶。例如 微博出軌女豬腳賬戶 , 諾貝爾獎獲得者 等等,由於熱點事件造成的短時間熱點!此類熱點賬戶防不勝防,超出本文的攻擊範圍,暫不討論。
1.2 熱點賬戶問題
熱點賬戶在實際場景中是必然存在的,常常會成為使用者系統的瓶頸!同時,熱點賬戶問題也是高併發問題的延展,由於熱點的不規則性,如何在高併發情況下,削峰填谷,彈性抗壓!
1.3 熱點賬戶通用解決方案的價值
熱點賬戶除了是賬戶體系的一個通用問題,他的解決方案也可以同步遷移到其他高併發,高一致性,分佈不均勻等其他問題的解決上,例如微博熱點問題,支付寶雙11彈性變更,高頻搶購問題等等。期望通過學習熱點賬戶的八種解決方案,能夠舉一反三,應用於不同場景!
二、如何設計一個財務賬戶
在解決熱點賬戶問題之前,先來看下如何設計一個簡單的財務賬戶,來保障記賬的安全!
2.1 業務場景分析
財務賬戶需要 準確 記錄使用者的資金變動過程和結果!因此設計一個簡單財務賬戶至少要能包括兩個部分: 賬戶餘額 和 賬戶流水
便於理解,來張傳統的賬本,流水和餘額一目瞭然
賬戶流水:賬戶流水也就是通俗意義上的帳或者賬單!針對某個賬戶,每一筆資金的變更都需要記錄下來,並且保障 準確,不可更改 !同時如圖所示,流水中需要包含單據產生的原因,來源,變更額等等
賬戶餘額:賬戶餘額記錄使用者某個場景賬戶的當前資金額度!在複雜的業務場景中往往需要拆分出不同的子賬戶和賬戶模型。例如,未結運算元賬戶,可提現子賬戶,凍結子賬戶,授信賬戶等等。
從業務場景上一個賬戶系統核心需要準確記錄餘額和流水,同時,必須保障記錄的 準確,完備,不可變更 !
2.2 技術層面拆解
2.2.1 基本表方案
通過業務場景初步分析,基本的賬戶系統,需要三張基本表
賬戶基本資訊:賬戶資訊表 子賬戶餘額資訊:賬戶餘額表 賬戶流水資訊:賬戶流水錶 三張表基本關係 賬戶資訊表 1:N 賬戶餘額表 賬戶餘額表 1:N 賬戶流水錶 ## 具體賬戶和使用者的關聯可以參考三戶模型
2.2.2 表字段設計
從技術層面設計具體表細節關鍵要解決以下幾個問題
- 防重:冪等健設計
- 防改:鏈式設計
- 防錯:銷賬設計
簡單的滿足上面要求的賬戶設計參考innodb mvcc的設計,核心表字段如下
2.2.3 表字段解讀
2.2.3.1 冪等健設計
通過 資金憑證號+版本號+rollback 三個欄位作為uniq key來保證冪等
資金憑證號:來自業務方,業務方發起資金操作的唯一財務憑證,必須可追溯上游憑證和對賬!
版本號:每次獲取DB最新流水n後,版本號n+1插入,保障在併發情況下,每個子賬戶只有唯一一個版本號:n+1條記錄能夠插入成功!
rollback:回滾標識,保證每條記錄 能且只能銷賬一次 !
對於冪等建設計此處有三條小技巧
- 上游產生 :每一個冪等健如果可能的話,儘可能的上游產生,這樣可以最大限度的避免自產生冪等健的重複問題。如果確實不能上游產生,例如訂單ID,提現單ID,那麼也儘可能的分階段產生,例如提現時,先生成提現單ID,真正提現操作的時候,一定是帶著提現單ID和資訊來的,防止重複造成資損!
- 業務關聯 :冪等健的產生可以用ice生成,但是,最好能夠和業務關聯,因為通過業務強關聯的冪等健可以無限回溯來容災!比如,a使用者的b訂單進行c操作,uniq_key = a_b_c的話,也就是在任何情況下,無論多少次回溯,重試也只會有一個唯一的a_b_c,而ice生成則可能造成自回溯的時候插入多條!
- 寫庫保證 :這條原則是高一致高併發的基本原則!因為讀取a,校驗a,然後插入,必然會存在讀寫之間a變了,或者主從延時a已經變了,讀了歷史a。因此,冪等一定要通過寫庫保證或者最底層保證
2.2.3.2 鏈式設計
鏈式設計是保證操作精準不可篡改的非常有效手段,但不是絕對完美的方式!
通過資金的 before info,after info,版本號 三個要素來保證一條資金記錄一旦插入成功,前後置資訊固化!
鏈式設計的情況下單條修改是不可能的,多條修改需要在保證條目不變的情況下重組資金,但是,整體資金不可變
解決多條修改的方式:分散式儲存,通過選舉來判定最終正確的鏈,來確認是否某條鏈發生了過程修改,這種設計有一個很時髦的名字: 區塊鏈 !而每條流水的核心資訊加密後也有了一個更加時髦的名字: 比特幣 !
2.2.3.3 銷賬設計
銷賬設計在賬戶系統中是一直存在的,現實財務系統可以 紅銷藍抵 ,線上財務系統加了鏈式之後,基本上就只能採用 藍抵
通過增加rollback欄位,並且嚴格限制0|1,保證一條賬務流水只能被抵銷一次!
具體三張表詳細欄位,需要脫敏,就不貼了,參考上面,其中索引,欄位大小,聯合索引等設計根據自身業務場景相容即可!
小結:欲知後事如何,且聽下回分解
本部分簡單介紹了什麼是熱點賬戶和賬戶的基本設計,涵蓋冪等健設計,鏈式設計等等!
下一篇重點分析下熱點賬戶在鏈式設計下的問題,產生原因和八種基本解決方案