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

geek1202 7年前發布 | 10K 次閱讀 數據庫 軟件架構

微信紅包的由來

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

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

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

前端流量控制

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

CGI無狀態

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

資源靜態化

利用騰訊強大的基礎資源優化部署,盡量把動態內容轉為靜態資源。靜態資源和CGI分離,靜態資源通過CDN就近接入,減少用戶和CGI的交互,減少內網、訪問延時和數據請求。

業務流程異步化

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

過載保護

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

多級讀緩存

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

訂單寫緩存

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

存儲層的高可用設計

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

讀寫分離

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

水平切分

數據的水平切分,實質就是分庫分表;選取一張數據表按照主要緯度把數據拆分開。實現存儲層的平行擴展。有效降低了單臺數據庫機器的負載,也減小了服務不可用的可能性。單臺數據庫宕機只會導致部分數據不能訪問。主要需要考慮路由規則的選定,方便擴縮容以及數據的均衡分布。

垂直切分

數據表除了水平切分,行內數據可以按屬性進一步分開。核心表只保留最關鍵的字段,保證數據文件短小緊湊。以紅包為例,昵稱和祝福語這類較長的信息,不屬于核心數據,完全可以切分到別的機器上,進一步提升核心數據庫的容量。不同數據適合的存儲類型也不一樣,這類重復率高的長字符串更適合NoSQL存儲,對存儲空間和性能都是節約極大。

空間換時間

按不同緯度組織表,比如按訂單屬性和用戶屬性進行組織;適應不同的請求場景,避免復雜的查詢。不同緯度的表可以通過對賬對齊,非核心表可以適當冗余,減少多次請求。

鎖的優化

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

冷熱分離

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

異地多活

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

就近接入

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

數據分離

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

異地容災

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

有損服務和柔性降級

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

有損服務

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

柔性可用

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

結束語

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

 

 

來自:http://mp.weixin.qq.com/s/HTDSZWpYrHeqShzDOuz3kg

 

 本文由用戶 geek1202 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!