天天看點

微信紅包背景系統可用性設計實踐

微信紅包業務量級的高速發展,對背景系統架構的可用性要求越來越高。在保障微信紅包業務體驗的前提下,紅包背景系統進行了一系列高可用方面的優化設計。本次演講介紹了微信紅包背景系統的高可用實踐經驗,主要包括背景的set化設計、異步化設計、訂單異地存儲設計、存儲層容災設計與平行擴縮容等。聽衆可以了解到微信紅包背景架構的設計細節,共同探讨高可用設計實踐上遇到的問題與解決方案。

微信紅包介紹

微信紅包從2014年開始發展到現在2017年,中間經曆了3年時間。在這三年的時間裡,整個系統可用性産生了較大的提升。2015年年初的時候,每天晚上九點鐘是微信紅包的業務高峰期,系統經常性地出現性能問題。到了2017年的今天,即使在節假日高峰期,系統也不會出現問題。

微信紅包背景系統可用性設計實踐

如上圖所示,微信紅包的業務包含包、發、搶、拆、查詢發送紅包和收紅包數量,其中最關鍵的步驟是發紅包和搶紅包。

微信紅包是微信支付的商戶,微信紅包這個商戶出售的是錢。發紅包使用者在微信紅包平台使用微信支付購買一份錢,微信紅包将錢發放到相對應的微信群。群裡的使用者搶紅包得到微信零錢。這個過程中,微信紅包和微信支付之間的關系是商家和第三方支付平台的關系。

微信紅包和微信支付之間的互動,與普通商家與微信支付的互動一樣,需要經過六個步驟。使用者發紅包時,進入微信紅包下一筆訂單,系統記錄發紅包使用者、發紅包金額、紅包數量和要發送到的用微信群。然後微信紅包系統請求微信支付伺服器進行下單,使用者使用微信支付進行支付。

支付成功後,微信支付背景系統通知微信紅包背景系統支付成功結果,微信紅包背景系統收到的通知後推送微信紅包消息到微信群。微信群裡使用者便可搶紅包。這就是微信紅包和微信支付的關系以及互動過程。

微信紅包系統架構

微信紅包的系統流程:

微信紅包背景系統可用性設計實踐

上圖是微信紅包系統角度上的流程,業務主流程是包、發、搶、拆四個操作,每個操作包括幾個關鍵的步驟。

包紅包,系統為每個紅包配置設定一個唯一ID,即紅包發送訂單号,然後将發紅包使用者、紅包個數、紅包數額寫入存儲,最後去微信支付下單。

發紅包,使用者使用微信支付完成付款,微信紅包背景系統收到微信支付系統的支付成功通知。紅包系統将紅包發送訂單狀态更新為使用者已支付,并寫入使用者發紅包記錄(使用者發紅包記錄,就是微信錢包中,檢視到的使用者每一年總共發出及收到的紅包記錄)。最後微信紅包背景系統發送微信紅包消息到微信群。

搶紅包,指微信群裡的使用者收到微信紅包消息後,點開紅包消息。這個過程,微信紅包背景系統會檢查紅包是否已被搶完,是否已經搶過。

拆紅包是最複雜的業務操作。包括查詢這個紅包發送訂單,判斷使用者是否可拆,然後計算本次可拆到的紅包金額。然後寫入一條搶紅包記錄。如果把拆紅包過程類比為一個秒殺活動的過程,相當于扣庫存與寫入秒殺記錄的過程。更新庫存對應于更新紅包發送訂單,寫入秒殺記錄對應于寫入這個紅包的領取紅包記錄。另外,還要寫入使用者整體的紅包領取記錄。最後請求微信支付系統給拆到紅包使用者轉入零錢,成功後更新搶紅包的訂單狀态為已轉賬成功。

微信紅包的整體架構

微信紅包背景系統可用性設計實踐

上圖所示,是微信紅包的系統架構。包括微信統一接入層,下面是微信紅包系統API,包括發、搶、拆、查紅包詳情、查紅包使用者清單。再下面是封裝微信紅包關鍵業務的邏輯服務;最下面一層是資料存儲層,微信紅包最主要的資料是訂單資料,包括發紅包訂單和拆紅包訂單兩部分。業務邏輯和存儲伺服器之間是資料接入層,它最重要的作用是封裝資料庫操作的領域邏輯,使得業務邏輯服務不需要感覺對MySQL的連接配接管理、性能、容災等問題。

微信紅包資料的通路熱度,随着時間流逝會急劇降低,也就是資料的通路時間段非常集中,一般紅包發出三天後,99%的使用者不會再去點開這個紅包了。是以微信紅包系統采取按時間做冷熱資料分離,降低資料的存儲成本,同時提升了熱資料的通路性能。

資料平台用于對紅包資料的分析計算,比如朋友圈的文章,統計從2016年1月1日到2017年1月一個使用者總共搶紅包的金額,在全國的排名情況,發紅包數最多的城市等。另外一個作用就是對賬,紅包的訂單和微信支付的訂單需要對賬,以保證最終資金的一緻性;訂單的資料和訂單的cache需要做對賬,以保證資料的完整性;訂單資料和使用者的收發記錄需要對賬,以保證使用者清單完整性。

微信紅包系統的可用性實踐

系統可用性影響因素

系統的可用性影響因素可分成兩類,一類計劃外,一類計劃内。計劃外包含很多因素,系統用到的所有東西都可能産生故障,都可能成為影響可用性的因素。從這個角度上來講,可以說故障是無法避免的,系統的運作一定會産生故障,尤其是伺服器有成千上萬個的時候。計劃内的影響因素,主要有與更新相關、運維相關的操作,以及日常的備份等。這一類影響因素,通過精細地設計方案,是可以避免對可用性造成影響的。

微信紅包系統可用性設計方向

基于上面兩個分析結論,可以總結出微信紅包背景系統的可用性的設計方向。就是在不能避免意外故障的情況下,盡可能降低出現意外故障時對可用性的影響。另一方面,絕大多數計劃内的日常維護可以通過方案的設計避免影響可用性,其中平行擴容特指關于存儲層的平行擴容。

下面從降低故障影響和微信紅包系統的平行擴容兩方面進行分析。

首先是降低意外故障的影響,重點講解訂單存儲層在訂單DB故障的情況下如何降低對紅包系統可用性的影響。

業務邏輯層——部署方案設計

首先是業務邏輯層的部署方案。業務邏輯層是無狀态的,微信紅包系統的業務邏輯層,部署在兩個城市,即兩地部署,每一個城市部署至少三個園區,即三個IDC。并且每個服務需要保證三個IDC的部署均衡。另外,三個IDC總服務能力需要備援三分之一,當一個IDC出現故障時,服務能力仍然足夠。進而達到IDC故障不會對可用性産生影響。

業務邏輯層——異步化設計

微信紅包背景系統可用性設計實踐

第二是異步化設計。如上圖所示,微信紅包的某些步驟不實時完成也不會影響使用者對紅包業務可用性的體驗。比如拆紅包,正常的業務流程很長,但關鍵步驟隻有訂單相關的幾步。至于轉零錢、寫紅包記錄等操作不需要實時。使用者搶到紅包時,一般不會實時去錢包檢視微信零錢,而是在微信群中點開消息檢視本次搶到的金額和他人搶紅包金額。是以拆紅包時隻需要從cache查詢使用者是否拆過紅包,然後寫入拆紅包的訂單記錄,更新發紅包訂單,其他的操作都可以優化。當然,不是每個業務都可以進行異步優化,需要進行業務分析,判斷是否存在非關鍵步驟之外的事情可以将其異步化,并通過異步對賬保證最終一緻。

微信紅包背景系統可用性設計實踐

接下來是微信紅包訂單存儲設計。上圖是2014年微信紅包存儲層的模型。業務邏輯層請求資料層操作時,使用訂單号hash路由到訂單SERVER。訂單SERVER與每一組MySQL資料庫連接配接。

微信紅包的訂單号是在發紅包時系統生成的唯一辨別,使用序列号服務生成唯一ID,後面拼接三位微信紅包的訂單分庫表的辨別。是以,總共可以分一百個邏輯庫,每個邏輯庫含有十張表。一百個邏輯庫均勻地分布到十組實體DB,每組DB存十個邏輯庫。

這個架構最大的問題是,一組DB故障時,會影響其他DB。2014-2015年期間,微信紅包量漲得特别快,擴容速度跟不上業務增長速度。一組DB的性能出現瓶頸時,資料操作變慢,拆紅包的事務操作在MySQL排隊等待。由于所有十組DB機器與所有的訂單SERVER連接配接,導緻所有的訂單SERVER都被拖住,進而影響紅包整體的可用性。這個架構的另一個問題是擴容不友善,後面會介紹。

為解決DB間的互相影響,需要将DB間互相隔離,訂單存儲層SET化。SET化指訂單DB和訂單接入SERVER垂直stick一起。業務邏輯層通路訂單時,根據訂單倒數第二、三位數字找到所屬訂單SET,一個SET的請求不能路由到其他SET。

找到對應的訂單接入伺服器之後,在伺服器内的多個程序中找到指定程序,讓同個紅包的所有拆請求串行化。當一組DB出現故障,隻會影響該組DB對應的SERVER。

這裡有一個問題,DB故障拖住某些訂單SERVER,會不會也拖住更上層業務邏輯服務?業務邏輯層為什麼不一起SET化?業務邏輯層承載了使用者次元相關的業務操作,不可以按照訂單的次元分業務邏輯,例如業務邏輯層會請求使用者頭像、昵稱等,如果繼續按照訂單分業務邏輯層,會導緻跨地域調用。

微信紅包系統采取的方案是,在訂單SERVER服務端增加快速拒絕服務的能力。SERVER主動監控DB的性能情況,DB性能下降、自身的CPU使用升高,或者發現其他的監控次元超标時,訂單SERVER直接向上層報錯,不再去通路DB,以此保證業務邏輯層的可用性。

一組DB故障不會影響整個系統的可用性。有影響的,隻有十分之一,若擴成100組,影響便隻有一百分之一。是以通過SET化得到的好處是,控制DB連接配接數、隔離故障影響和分流并發。

微信紅包背景系統可用性設計實踐

完成SET化之後,DB故障仍對業務有十分之一的影響,那麼這十分之一該怎麼解決?通過對系統進行研究分析之後,發現DB可以做到故障自愈。

如上圖所示,所設尾号90-99的SET故障時,如果業務邏輯服務後續不再生成屬于這個SET的訂單,那後續的業務就可以逐漸恢複。

也就是在發生故障時,業務邏輯層釋出一個版本,屏蔽故障号段的單号生成,就可以恢複業務。進一步想,除了人為發版本,有沒有辦法可以讓DB故障時自愈?在DB故障導緻業務失敗時,業務邏輯層可擷取到故障DB的号段,在發紅包時,将這些故障的号段,換一個可用的号段就可恢複業務。訂單号除了最後三位,前面的部分已能保證該紅包的唯一性,後面的數字隻代表着分庫表資訊,故障時隻需要将最後三位換另外一個SET便可自動恢複。

完成這個設計後,即使DB出現故障,業務的可用性也不會有影響。這裡還有一點,新的發紅包請求可避免DB故障的影響,但那些故障之前已發出未被領取的紅包,紅包消息已發送到微信群,單号已确定,拆紅包時還是失敗。對這種情況,由于不會有增量,采用正常的主備切換解決即可。

平行擴縮容設計

微信紅包背景系統可用性設計實踐

上圖是微信紅包早期的擴縮容方式。這個擴容方式,對擴容的機器數有限制。前面講到,紅包系統按紅包單号後面兩個數字分多SET,為了使擴容後資料保持均衡,擴容隻能由10組DB擴容到20組、50組或者100組。另外,這個擴容方式,過程也比較複雜。首先,資料要先從舊資料庫同步複制到新擴容的DB,然後部署DB的接入SERVER,最後在淩晨業務低峰時停服擴容。

這個擴容方式的複雜性,根本原因是資料需要從舊SET遷到新SET。如果新産生資料與舊資料沒關系,那麼就可以省掉這部分的遷移動作,不需停服。分析發現,需要把資料遷移出來的原因是訂單号段00-99已全部使用,每個實體資料庫包含了10個邏輯庫。如果将訂單号重新設計,預留三位空間,三位數字每一個代表獨立的實體DB,原來10組DB分别為000-009号段。

這種設計,縮容時,比如要縮掉000這組,隻需在業務邏輯服務上不生成訂單号為000的紅包訂單。擴容時,比如擴為11組,隻需多生成010的訂單号,這個資料便自動寫入新DB。當然縮容需要一個前提條件,也就是冷熱分離,縮容後資料變為冷資料,可下線熱資料機器。以上就是紅包的平行擴縮容方案。

微信紅包背景系統可用性設計實踐

寫在最後

微信紅包系統的可用性實踐,主要包括了部署設計、SET化設計、異步化設計、DB故障自愈能力建設、平行擴容設計。在完成這些設計後,微信紅包系統的可用性得到了很大提升,在2017年春節實作了0故障,在平常的運作中達到99.99%可用性。

繼續閱讀