天天看點

微信紅包訂單存儲架構變遷的最佳實踐

作者:莫曉東,微信支付進階DBA。擅長大規模MySQL資料庫的架構、優化和高可用;目前專注于社交支付的存儲層運維和架構優化。

責編:仲培藝,關注資料庫領域,糾錯、尋求報道或者投稿請緻郵:[email protected]。

本文為《程式員》原創文章,未經允許不得轉載,更多精彩文章請訂閱2017年《程式員》

微信紅包的由來

南方企業一直有過年找老闆“逗利是”的習俗,每年春節後開工的第一天,騰訊大廈都會排上長長的隊伍,集體上樓找老闆們領紅包。按照廣東習俗,已經結婚的同僚也要給未婚同僚發紅包,這一天騰訊員工就在春茗和尋找紅包中度過。

由此孵化了一個内部項目,通過微信來收發紅包,把這個公司全員娛樂活動與最活躍的IM平台微信結合起來。最初這個項目并沒有預期對外,但是入口不小心開放後,成為了現象級産品。2014年開始爆發性增長,每年的發放量都是上一年的若幹倍。根據騰訊公布的資料,到2016年春節,已經是每秒十萬次支付,每天近十億訂單的系統。

微信紅包本質是小額資金在使用者帳戶流轉,有發、搶、拆三大步驟。在這個過程中對事務有高要求,是以訂單最終要基于傳統的RDBMS,這方面是它的強項,最終訂單的存儲使用網際網路行業最通用的MySQL資料庫。支援事務、成熟穩定,我們的團隊在MySQL上有長期技術積累。但是傳統資料庫的擴充性有局限,需要通過架構解決。

前端流量控制

發十億紅包,難在哪裡?大量使用者在同一時間發搶紅包,瞬間産生每秒數萬次的請求,除夕可能成百千萬次;這個量級的請求如果不加以疏導處理直接到達背景,必定會導緻後端服務過載甚至崩潰。主要思路是縮短關鍵業務流程,分離可以通過異步、緩存等方式解決的問題,減輕系統壓力,加快響應速度,在存儲層前面建上一座大壩。

CGI無狀态

接入層無狀态,邏輯層也無狀态,可以友善地水準擴充。但依賴MySQL事務保證交易完整,保證紅包系統的精簡,減少瓶頸的存在。

資源靜态化

利用騰訊強大的基礎資源優化部署,盡量把動态内容轉為靜态資源。靜态資源和CGI分離,靜态資源通過CDN就近接入,減少使用者和CGI的互動,減少内網、通路延時和資料請求。

業務流程異步化

微信紅包的發、搶、拆背後都有多個内部環境,關鍵流程精簡,非關鍵流程和後續業務邏輯進入異步隊列進行處理,減少了使用者的等待時間,也極大降低了峰值雪崩的機率。繁多的非關鍵鍊路也不會影響到主流程。

過載保護

前端保護後端,能在前端處理,就不傳遞到後端。前端需要按後端能力做削峰限流;用戶端、接入層、邏輯層逐層控制流量;前端更容易容錯處理,全力保護存儲層。微信的過載保護在用戶端已提前預埋了政策,在連接配接失敗或逾時情況下會有相應提示,減少使用者重複請求次數。接入層針對頻繁送出請求的用戶端限制響應速度,并對系統負載劃分出若幹等級,達到不同門檻值時引導用戶端使用不同限速速率;在異常情況出現時,異步限流降速減輕伺服器端壓力防止過載。

多級讀緩存

發一個群紅包,搶紅包的請求量遠大于發紅包,如果已經領過完全可以拒絕。邏輯層增加緩存,類似可以緩存的請求都緩存起來,進一步減少存儲層流量。

訂單寫緩存

訂單系統有很多請求不會真正完成全流量,建立這些廢單不但浪費存儲資源,還會擠占邏輯層和資料層的處理能力,影響其他交易。訂單在完成支付前可以先落在緩存中,完成支付後再持久化。

微信紅包訂單存儲架構變遷的最佳實踐

存儲層的高可用設計

在數百倍千倍的業務增長下,存儲層很難簡單無限擴容,一方面裝置成倍增加的成本巨大,另一方面存儲層瓶頸堆積不一定能解決問題。

讀寫分離

寫請求需要在主機上,實時讀也需要走主機。有大量對延時不那麼敏感,又影響性能的查詢,完全可以放到從機。讀寫分離政策是MySQL分布式的入門,簡潔地提高了系統容量。

水準切分

資料的水準切分,實質就是分庫分表;選取一張資料表按照主要緯度把資料拆分開。實作存儲層的平行擴充。有效降低了單台資料庫機器的負載,也減小了服務不可用的可能性。單台資料庫當機隻會導緻部分資料不能通路。主要需要考慮路由規則的標明,友善擴縮容以及資料的均衡分布。

垂直切分

資料表除了水準切分,行内資料可以按屬性進一步分開。核心表隻保留最關鍵的字段,保證資料檔案短小緊湊。以紅包為例,昵稱和祝福語這類較長的資訊,不屬于核心資料,完全可以切分到别的機器上,進一步提升核心資料庫的容量。不同資料适合的存儲類型也不一樣,這類重複率高的長字元串更适合NoSQL存儲,對存儲空間和性能都是節約極大。

空間換時間

按不同次元組織表,比如按訂單屬性和使用者屬性進行組織;适應不同的請求場景,避免複雜的查詢。不同次元的表可以通過對賬對齊,非核心表可以适當備援,減少多次請求。

鎖的優化

多人争搶紅包通過資料庫事物來保證,必然存在競争MySQL行鎖。核心事物必須盡量精簡,避免死鎖。同一個訂單的所有請求,盡量在邏輯層程序預排隊後通過一個連接配接發送請求到資料庫。

冷熱分離

核心資料庫存放高頻資料,其他資料可以定時移到成本低的冷資料庫中。這樣可以為核心資料庫使用最好的SSD裝置,快速裝置容量較小較貴,不可能在全量資料上使用。同時可以保證資料表的容量不會一直積累,大表也會導緻性能下降。

微信紅包訂單存儲架構變遷的最佳實踐

異地多活

當系統足夠大時,就必須開始考慮異地部署的問題,讓資料盡可能離使用者更近。而且進一步的高可用不能局限在同一地域,必須跨資料中心跨城多活才能抵禦系統性風險。因為跨城的幾十毫秒延時,微信紅包的異地活動設計為多資料中心互相獨立。非災難灰階不會将其他資料中心的資料導入到線上。

就近接入

以微信紅包系統的異步部署為例,第一個好處是使用者就近接入,減少跨城的穿越流量。根據發送者的地域标志資料落地到不同資料中心,在不同地域實作業務閉環。

資料分離

目前的網絡技術限制,使用光纖也無法保證跨城資料的同步延時問題。是以微信紅包的跨城資料中心并不進行資料實時同步。不同區域各自承載業務流量,地域上實作平衡,各地的訂單資料各自獨立存儲。

異地容災

如果出現地域性故障,我們需要有機制去保證服務可用性。有了異步部署,假如深圳出現系統性故障,那麼我們可以直接把請求接入上海。各資料中心獨立部署,如果某地系統達到最大容量,可以進行跨地域分流。

有損服務和柔性降級

我們遇到最多的問題就是海量請求,通過分布式系統來實作海量請求,根據CAP理論不能同時保證一緻性和高可用,必須有取舍。我們首先保證可用性,同時實作最終一緻性。有以下原則。

有損服務

要追求高可用性,可以犧牲部分資料一緻性和完整性進而保證核心功能。在資源一定的前提下,滿足使用者的核心需求。微信紅包的核心點是搶、拆紅包,系統必須盡最大可能保證核心步驟流暢,但在瓶頸時立即降級防止引起系統雪崩。但是要保證資料能最終對齊,金融屬性的系統資料安全硬要求。

柔性可用

柔性可用是在有損服務價值觀支援下的方法,結合具體場景提供不同級别的使用者體驗,保證盡可能成功傳回關鍵資料。把握使用者在每一個場景中的核心需求,設計不同層次滿足核心訴求的辦法。系統首先要實作容災和自動切換;其次邏輯資源應該隔離;服務過載時必須自動快速拒絕。

結束語

本文簡單介紹了微信紅包的存儲層服務設計準則,在業務從起步到小跑再到騰飛的過程中,背後的海量服務能力将對其最終成敗有着越來越深遠的影響。在網際網路爆發性增長中,海量服務能力決定項目成敗,必須在項目初期就做好海量服務的準備。

訂閱2017年程式員(含iOS、Android及印刷版)請通路 http://dingyue.programmer.com.cn

微信紅包訂單存儲架構變遷的最佳實踐

訂閱咨詢:

• 線上咨詢(QQ):2251809102

• 電話咨詢:010-64351436

• 更多消息,歡迎關注“程式員編輯部”