微信紅包實現原理
信紅包實現原理
以下內容來源于QCon某高可用架構群聊天記錄整理 背景:有某個朋友咨詢微信紅包的架構,在官方或非官方同學的解釋和討論中得出以下討論內容,在此期間有多個同學發紅包做現網算法測試。
搶紅***程
當有人在群里發了一個N人的紅包,總金額M元,后臺大概發生的事情如下:
一、發紅包后臺操作:
-
在數據庫中增加一條紅包記錄,存儲到CKV,設置過期時間;
-
在Cache(可能是騰訊內部kv數據庫,基于內存,有落地,有內核態網絡處理模塊,以內核模塊形式提供服務))中增加一條記錄,存儲搶紅包的人數N
二、搶紅包后臺操作:
-
搶紅包分為搶和拆,搶操作在Cache層完成,通過原子減操作進行紅包數遞減,到0 就說明搶光了,最終實際進入后臺拆操作的量不大,通過操作的分離將無效請求直接擋在Cache層外面。這里的原子減操作并不是真正意義上的原子減操作,是 其Cache層提供的CAS,通過比較版本號不斷嘗試,存在一定程度上的沖突,沖突的用戶會放行,讓其進入下一步拆的操作,這也解釋了為啥有用戶搶到了拆 開發現領完了的情況。
-
拆紅包在數據庫完成,通過數據庫的事務操作累加已經領取的個數和金額,插入一條領取 流水,入賬為異步操作,這也解釋了為啥在春節期間紅包領取后在余額中看不到。拆的時候會實時計算金額,其金額為1分到剩余平均值2倍之間隨機數,一個總金 額為M元的紅包,***的紅包為 M * 2 /N(且不會超過M),當拆了紅包后會更新剩余金額和個數。財付通按20萬筆每秒入賬準備,實際只到8萬每秒。
FAQ
-
既然在搶的時候有原子減了就不應該出現搶到了拆開沒有的情況?
這里的原子減并不是真正意義上的原子操作,是Cache層提供的CAS,通過比較版本號不斷嘗試。 -
cache和db掛了怎么辦?
主備 +對賬 -
有沒有紅包個數沒了,但余額還有情況?
沒有,程序***會有一個take all操作以及一個異步對賬保障。 -
為什么要分離搶和拆?
總思路是設置多層過濾網,層層篩選,層層減少流量和壓力。這個設計最初是因為搶操作是業務層,拆是入賬操作,一個操作太重了,而且中斷率高。 從接口層面看,***個接口純緩存操作,搞壓能力強,一個簡單查詢Cache擋住了絕大部分用戶,做了***道篩選,所以大部分人會看到已經搶完了的提示。 -
搶到紅包后再發紅包或者提現,這里有什么策略嗎?
大額優先入賬策略 -
有沒有從數據上證明每個紅包的概率是不是均等?
不是絕對均等,就是一個簡單的拍腦袋算法。 -
拍腦袋算法,會不會出現兩個***?
會出現金額一樣的,但是手氣***只有一個,先搶到的那個***。 -
發紅包人的錢會不會凍結?
是直接實時扣掉,不是凍結。 -
采用實時算出金額是出于什么考慮?
實時效率更高,預算才效率低下。預算還要占額外存儲。因為紅包只占一條記錄而且有效期就幾天,所以不需要多大空間。就算壓力大時,水平擴展機器是。