(二)微信紅包高并發(fā)系統(tǒng)設計方案(1)

2017年1月28日,正月初一,微信公布了用戶在除夕當天收發(fā)微信紅包的數量——142億個,而其收發(fā)峰值也已達到76萬每秒。百億級別的紅包,如何保障并發(fā)性能與資金安全?這給微信帶來了超級挑戰(zhàn)。面對挑戰(zhàn),微信紅包在分析了業(yè)界“秒殺”系統(tǒng)解決方案的基礎上,采用了SET化、請求排隊串行化、雙維度分庫表等設計,形成了獨特的高并發(fā)、資金安全系統(tǒng)解決方案。實踐證明,該方案表現穩(wěn)定,且實現了除夕夜系統(tǒng)零故障運行。概要:

一、業(yè)務特點:海量的并發(fā)要求;嚴格的安全級別

二、技術難點:并發(fā)請求搶鎖;事務級操作量級大;事務性要求嚴格

三、解決高并發(fā)問題通常使用的方案

1.使用內存操作替代實時的DB事務操作(優(yōu)點:內存操作替代磁盤操作,提高了并發(fā)性能。)

2使用樂觀鎖替代悲觀鎖。應用于微信紅包系統(tǒng),則會存在下面三個問題:滾并返回失??;并發(fā)大失敗,小成功。DB壓力大。

四、微信紅包系統(tǒng)的高并發(fā)解決方案

1.系統(tǒng)垂直SET化,分而治之。

2.邏輯Server層將請求排隊,解決DB并發(fā)問題。

3.雙維度庫表設計,保障系統(tǒng)性能穩(wěn)定

一、微信紅包的兩大業(yè)務特點

類似“秒殺”活動,群里發(fā)一個紅包=“秒殺”商品上架;搶紅包的動作=“秒殺”的查詢庫存;拆紅包=“秒殺”

首先,微信紅包業(yè)務比普通商品“秒殺”有更海量的并發(fā)要求。

同一時間有10萬個群里的用戶同時在發(fā)紅包,那就相當于同一時間有10萬個“秒殺”活動發(fā)布出去。10萬個微信群里的用戶同時搶紅包,將產生海量的并發(fā)請求。

其次,微信紅包業(yè)務要求更嚴格的安全級別。

微信紅包是微信支付的一個商戶,提供資金流轉服務。

用戶發(fā)紅包=購買一筆“錢”(在微信紅包這個商戶上),并且收貨地址是微信群。當用戶支付成功后,紅包“發(fā)貨”到微信群里,群里的用戶拆開紅包后,微信紅包提供了將“錢”轉入折紅包用戶微信零錢的服務。

資金交易業(yè)務比普通商品“秒殺”活動有更高的安全級別要求。普通的商品“秒殺”商品由商戶提供,庫存是商戶預設的,“秒殺”時可以允許存在“超賣”、“少賣”的情況。但是對于微信紅包,100元不可以被拆出101元;領取99元時,剩下的1元在24小時過期后要精確地退還給發(fā)紅包用戶,不能多也不能少。

二、 微信紅包系統(tǒng)的技術難點

在介紹微信紅包系統(tǒng)的技術難點之前,先介紹下簡單的、典型的商品“秒殺”系統(tǒng)的架構設計,如下圖所示。


該系統(tǒng)由接入層、邏輯服務層、存儲層與緩存構成。Proxy處理請求接入,Server承載主要的業(yè)務邏輯,Cache用于緩存庫存數量、DB則用于數據持久化。

一個“秒殺”活動,對應DB中的一條庫存記錄。當用戶進行商品“秒殺”時,系統(tǒng)的主要邏輯在于DB中庫存的操作上。一般來說,對DB的操作流程有以下三步:

a. 鎖庫存

b. 插入“秒殺”記錄

c. 更新庫存

a.鎖庫存是為了避免并發(fā)請求時出現“超賣”情況。同時要求這三步操作需要在一個事務中完成(難點:并發(fā)請求搶鎖)。

第一個事務完成提交之前這個鎖一直被第一個請求占用,后面的所有請求需要排隊等待。同時參與“秒殺”的用戶越多,并發(fā)進DB的請求越多,請求排隊越嚴重。

紅包系統(tǒng)的設計上,除了并發(fā)請求搶鎖之外,還有以下兩個突出難點

首先,事務級操作量級大。上文介紹微信紅包業(yè)務特點時提到,普遍情況下同時會有數以萬計的微信群在發(fā)紅包。這個業(yè)務特點映射到微信紅包系統(tǒng)設計上,就是有數以萬計的“并發(fā)請求搶鎖”同時在進行。這使得DB的壓力比普通單個商品“庫存”被鎖要大很多倍。

其次,事務性要求嚴格。微信紅包系統(tǒng)本質上是一個資金交易系統(tǒng),相比普通商品“秒殺”系統(tǒng)有更高的事務級別要求。

三、解決高并發(fā)問題通常使用的方案

普通商品“秒殺”活動系統(tǒng),解決高并發(fā)問題的方案,大體有以下幾種:

方案一,使用內存操作替代實時的DB事務操作。

如圖2所示,將“實時扣庫存”的行為上移到內存Cache中操作,內存Cache操作成功直接給Server返回成功,然后異步落DB持久化。

優(yōu)點:提高了并發(fā)性能。

缺點:在內存操作成功DB持久化失敗,或者內存Cache故障的情況下,DB持久化會丟數據,不適合微信紅包這種資金交易系統(tǒng)。

方案二,使用樂觀鎖替代悲觀鎖。

商品“秒殺”系統(tǒng)中,樂觀鎖的具體應用方法,是在DB的“庫存”記錄中維護一個版本號。在更新“庫存”的操作進行前,先去DB獲取當前版本號。在更新庫存的事務提交時,檢查該版本號是否已被其他事務修改。如果版本沒被修改,則提交事務,且版本號加1;如果版本號已經被其他事務修改,則回滾事務,并給上層報錯。

這個方案解決了“并發(fā)請求搶鎖”的問題,可以提高DB的并發(fā)處理能力。

應用于微信紅包系統(tǒng),則會存在下面三個問題

1.在并發(fā)搶到相同版本號的拆紅包請求中,只有一個能拆紅包成功,其他的請求將事務回滾并返回失敗,給用戶報錯,用戶體驗完全不可接受。

2.將會導致第一時間同時拆紅包的用戶有一部分直接返回失敗,反而那些“手慢”的用戶,有可能因為并發(fā)減小后拆紅包成功,這會帶來用戶體驗上的負面影響。

3.會帶來大數量無效更新請求、事務回滾,給DB造成不必要的額外壓力。

四、微信紅包系統(tǒng)的高并發(fā)解決方案

1.系統(tǒng)垂直SET化,分而治之。

微信紅包用戶發(fā)一個紅包時,微信紅包系統(tǒng)生成一個ID作為這個紅包的唯一標識。接下來這個紅包的所有發(fā)紅包、搶紅包、拆紅包、查詢紅包詳情等操作,都根據這個ID關聯。

紅包系統(tǒng)根據這個紅包ID,按一定的規(guī)則(如按ID尾號取模等),垂直上下切分。切分后,一個垂直鏈條上的邏輯Server服務器、DB統(tǒng)稱為一個SET。

各個SET之間相互獨立,互相解耦。并且同一個紅包ID的所有請求,包括發(fā)紅包、搶紅包、拆紅包、查詳情詳情等,垂直stick到同一個SET內處理,高度內聚。通過這樣的方式,系統(tǒng)將所有紅包請求這個巨大的洪流分散為多股小流,互不影響,分而治之,如下圖所示。

這個方案解決了同時存在海量事務級操作的問題,將海量化為小量。

2.邏輯Server層將請求排隊,解決DB并發(fā)問題。

紅包系統(tǒng)是資金交易系統(tǒng),DB操作的事務性無法避免,所以會存在“并發(fā)搶鎖”問題。但是如果到達DB的事務操作(也即拆紅包行為)不是并發(fā)的,而是串行的,就不會存在“并發(fā)搶鎖”的問題了。

按這個思路,為了使拆紅包的事務操作串行地進入DB,只需要將請求在Server層以FIFO先進先出)的方式排隊,就可以達到這個效果。從而問題就集中到Server的FIFO隊列設計上。

微信紅包系統(tǒng)設計了分布式的、輕巧的、靈活的FIFO隊列方案。其具體實現如下:

首先,將同一個紅包ID的所有請求stick到同一臺Server。

上面SET化方案已經介紹,同個紅包ID的所有請求,按紅包ID stick到同個SET中。不過在同個SET中,會存在多臺Server服務器同時連接同一臺DB(基于容災、性能考慮,需要多臺Server互備、均衡壓力)。

為了使同一個紅包ID的所有請求,stick到同一臺Server服務器上,在SET化的設計之外,微信紅包系統(tǒng)添加了一層基于紅包ID hash值的分流,如下圖所示。

其次,設計單機請求排隊方案。

將stick到同一臺Server上的所有請求在被接收進程接收后,按紅包ID進行排隊。然后串行地進入worker進程(執(zhí)行業(yè)務邏輯)進行處理,從而達到排隊的效果,如下圖所示。

最后,增加memcached控制并發(fā)。

為了防止Server中的請求隊列過載導致隊列被降級,從而所有請求擁進DB,系統(tǒng)增加了與Server服務器同機部署的memcached,用于控制拆同一個紅包的請求并發(fā)數。

具體來說,利用memcached的CAS原子累增操作,控制同時進入DB執(zhí)行拆紅包事務的請求數,超過預先設定數值則直接拒絕服務。用于DB負載升高時的降級體驗。

通過以上三個措施,系統(tǒng)有效地控制了DB的“并發(fā)搶鎖”情況。

3.雙維度庫表設計,保障系統(tǒng)性能穩(wěn)定

紅包系統(tǒng)的分庫表規(guī)則,初期是根據紅包ID的hash值分為多庫多表。隨著紅包數據量逐漸增大,單表數據量也逐漸增加。而DB的性能與單表數據量有一定相關性。當單表數據量達到一定程度時,DB性能會有大幅度下降,影響系統(tǒng)性能穩(wěn)定性。采用冷熱分離,將歷史冷數據與當前熱數據分開存儲,可以解決這個問題。

系統(tǒng)在以紅包ID維度分庫表的基礎上,增加了以循環(huán)天分表的維度,形成了雙維度分庫表的特色。

具體來說,就是分庫表規(guī)則像db_xx.t_y_dd設計,其中,xx/y是紅包ID的hash值后三位,dd的取值范圍在01~31,代表一個月天數最多31天。

通過這種雙維度分庫表方式,解決了DB單表數據量膨脹導致性能下降的問題,保障了系統(tǒng)性能的穩(wěn)定性。同時,在熱冷分離的問題上,又使得數據搬遷變得簡單而優(yōu)雅。

綜上所述,微信紅包系統(tǒng)在解決高并發(fā)問題上的設計,主要采用了SET化分治、請求排隊、雙維度分庫表等方案,使得單組DB的并發(fā)性能提升了8倍左右,取得了很好的效果。

http://www.infoq.com/cn/articles/2017hongbao-weixin

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容