jeri??發(fā)表于 2015.3.27659瀏覽0討論
編者按:經(jīng)過2014年一年的醞釀泥栖,2015微信紅包總量創(chuàng)下歷史新高,峰值1400萬次/秒衫樊,8.1億次每分鐘身诺,微信紅包收發(fā)達10.1億次,系統(tǒng)整體運行平穩(wěn), 在這里我分享下微信紅包背后的技術(shù)禾酱。
講師:jeri
核心功能&目標
首先微酬,了解下微信紅包的4個邏輯:搖/發(fā)/搶/拆绘趋。看似簡單颗管,實現(xiàn)可不簡單再review下微信紅包要實現(xiàn)目標:
搖:搖的流暢
快:搶的要快
爽:拆的爽
穩(wěn):能分享出去
系統(tǒng)難點:
1.中國運營商網(wǎng)絡(luò)環(huán)境復(fù)雜陷遮,覆蓋面廣,春節(jié)期間網(wǎng)絡(luò)吃緊垦江,容易出現(xiàn)網(wǎng)絡(luò)故障
2.在尖峰搖時如何避免服務(wù)雪崩
3.在服務(wù)資源有限時帽馋,如何提供柔性服務(wù)
4.如何構(gòu)造有損服務(wù)
5.如何構(gòu)造set模型
6.如何解決并發(fā)搶
7.如何實現(xiàn)實現(xiàn)數(shù)據(jù)一致性
系統(tǒng)整體架構(gòu)圖
跨區(qū)域網(wǎng)絡(luò)解決方案
微信客戶端分布全球,接入點較多比吭,用戶資料靠近接入點绽族,可以加速用戶資料訪問,但是紅包的業(yè)務(wù)邏輯層并不全網(wǎng)分布衩藤,業(yè)務(wù)邏輯層訪問數(shù)據(jù)層比較多吧慢,數(shù)據(jù)層有狀態(tài)強一致性問題,只能同用一個數(shù)據(jù)副本赏表,比如上海用戶與深圳用戶在同個群里检诗,搶同一個紅包,如果訂單數(shù)據(jù)在上海與深圳都有瓢剿,在搶的時候逢慌,無法保證數(shù)據(jù)同步,可用性低间狂,所以攻泼,設(shè)計系統(tǒng)時,一定要梳理清楚系統(tǒng)間的調(diào)用關(guān)系前标,優(yōu)化接入層的業(yè)務(wù)邏輯坠韩,把網(wǎng)絡(luò)耗時降到最小,系統(tǒng)吞吐量才能提升炼列。
跨區(qū)域網(wǎng)絡(luò)問題只搁,在物理實施上,也需要有備份繞行的能力俭尖,這個可以在系統(tǒng)的底層框架中實現(xiàn)氢惋,當指定專線出現(xiàn)故障時,快速切換網(wǎng)絡(luò)稽犁,恢復(fù)服務(wù)
如何構(gòu)建有損服務(wù)
什么是有損服務(wù)焰望?選擇性犧牲一部分數(shù)據(jù)一致性和完整性從而保證核心功能絕大多數(shù)運行,經(jīng)過一段時間窗口已亥,數(shù)據(jù)一致性與完整性能得以恢復(fù)熊赖,這也是騰訊的一直運營策略,在有限資源前提下虑椎,量力而為震鹉,滿足用戶的核心需求
比如俱笛,春晚搖一搖,我們的核心點是搖/拆/分享传趾,那系統(tǒng)的資源優(yōu)先需要保證這些服務(wù)的響應(yīng)迎膜,任何關(guān)聯(lián)系統(tǒng)出現(xiàn)異常的時候馬上進行系統(tǒng)降級,防止引起系統(tǒng)雪崩浆兰。
系統(tǒng)降級可以分為兩個方面磕仅,一是把核心功能調(diào)用鏈路簡化,減少依賴簸呈,通過輔助輕量化的服務(wù)實現(xiàn)榕订,確保最短關(guān)鍵路徑的可行,比方說在接入層置入搖紅包邏輯蝶棋,將每秒千萬級請求轉(zhuǎn)化為每秒萬級的紅包請求卸亮,再傳到紅包服務(wù)的后端邏輯,降低雪崩的可能性玩裙。
柔性服務(wù).打造好的產(chǎn)品體驗
柔性可用是在有損服務(wù)價值觀支持下的方法兼贸,重點在于實際上會結(jié)合用戶使用場景,根據(jù)資源消耗吃溅,調(diào)整產(chǎn)品策略溶诞,設(shè)計幾個級別不同的用戶體驗場景,保證盡可能成功返回關(guān)鍵數(shù)據(jù)决侈,并正常接受請求螺垢,絕不輕易倒下。
比如赖歌,紅包的核心功能拆枉圃,拆完需要記錄用戶頭像昵稱,轉(zhuǎn)帳資金劃轉(zhuǎn)庐冯,同時輸出同個訂單下其它拆記錄孽亲,拆過程這些操作都可能失敗,但是核心操作獲取紅包是成功的展父,此時返劲,我們至少可以告訴用戶搶到金額,不至于讓用戶焦急等待栖茉,不斷重試篮绿,未完成的操作(頭像補全與資金轉(zhuǎn)帳),可以通異步補嘗方式重試吕漂。這樣解決了用戶的問題亲配,也緩解了系統(tǒng)壓力。
如果構(gòu)造set模型
Set模塊就像一個集裝箱,把各模塊標準化弃榨,模塊化菩收,規(guī)睦嬲觯化鲸睛,它為海量服務(wù)運營,特別是設(shè)備管理坡贺、網(wǎng)絡(luò)架構(gòu)官辈,提供了宏觀運營支撐框架,從而極大提高了海量服務(wù)運營效率遍坟。
微信紅包的set模塊拳亿,以拆服務(wù)為例,從接入層開始愿伴,數(shù)據(jù)開始sticky肺魁,按訂單號路由,即按單號分set隔节,同一個set盡可能在一個IDC 里鹅经,減少模塊間調(diào)用的耗時,在同一個set內(nèi)怎诫,邏輯層任何一臺機器瘾晃,調(diào)用方可實時摘除,如果是數(shù)據(jù)層發(fā)生故障幻妓,先在接入層蹦误,把新產(chǎn)生的紅包訂單號屏蔽有故障對應(yīng)的set編號,比如肉津,set1 數(shù)據(jù)庫出現(xiàn)故障强胰,為了避免在故障的set1 上繼續(xù)產(chǎn)生新的支付請求,在訂單生成器直接跳過set1的單號規(guī)則妹沙,把新請求導(dǎo)致其它set, 只有未搶完的部分紅包偶洋,會提示故障,稍后恢復(fù)初烘,阻止了故障引發(fā)的進一步惡化涡真,在故障db上的數(shù)據(jù),通過備機與業(yè)務(wù)邏輯層的數(shù)據(jù)核對肾筐,完成數(shù)據(jù)一致性的修復(fù)哆料。
如何解決并發(fā)搶
群里紅包的規(guī)則是金額隨機搶,在一個大群發(fā)一個紅包出去吗铐,搶并發(fā)請求量高东亦,在同一個資源上操作,需要增加鎖操作,避免一個搶總數(shù)超過發(fā)送紅包總數(shù)典阵,眾所周所奋渔,mysql的加鎖操作,很多搶在一個鎖上等壮啊,性能損耗大嫉鲸,吞吐量下降,對于海量服務(wù)的操作歹啼,是不能滿足要求玄渗。
在set模塊的基礎(chǔ)上,我們把發(fā)/搶的資源請求都會落到同一個資源set狸眼,在最外層藤树,cache紅包的狀態(tài),如果紅包已經(jīng)被搶完了拓萌,即刻返回岁钓,如果紅包未接完,對于一個紅包進去搶環(huán)節(jié)還有限流微王,這是第一級保護屡限,通過一致性hash算法,一一個單到dao層都會路由到同一個機器的同一個進程骂远,dao到mysql在現(xiàn)一個連接上完成搶操作囚霸,把并發(fā)搶修改成串行化,mysql可以無鎖等待激才,性能明顯提升拓型。
如何實現(xiàn)數(shù)據(jù)一致性
談到分布式系統(tǒng),先回顧CAP理論
?
C:Consistency數(shù)據(jù)一致更新瘸恼,所有變動都是同步的
A:高可用劣挫,好的響應(yīng)性能
P: 分區(qū)容忍,可靠性
在我們的系統(tǒng)設(shè)計中东帅,同樣碰到這個問題压固,無法同時滿足三個因子,移動互聯(lián)網(wǎng)系統(tǒng)靠闭,高可用性是必要要求帐我,數(shù)據(jù)分區(qū)也是分布式系統(tǒng)的條件,所以愧膀,我們設(shè)計系統(tǒng)時拦键,只能盡量保證數(shù)據(jù)一致性,只要一定時間窗口內(nèi)檩淋,完成數(shù)據(jù)一致芬为,讓用戶滿意。
微信紅包的數(shù)據(jù)有幾份,訂單數(shù)據(jù)媚朦,用戶數(shù)據(jù)氧敢,還有對應(yīng)的cache數(shù)據(jù),
N:數(shù)據(jù)副本份數(shù)紅包有三份
R: 一次需讀取的副本紅包一次從一個副本可以全部讀取需要數(shù)據(jù)
W: 一次寫入數(shù)據(jù)2份實時寫询张,一分異步化
R(1) + W(2) <=N從公式算出孙乖,我們的數(shù)據(jù)模型也是弱一致性
用戶數(shù)據(jù)是異步更新,更新失敗瑞侮,通過消息中心的圆,異步重試,根據(jù)DB資源負載設(shè)置調(diào)用方的調(diào)用閥值半火,除了實時重試,我們還有準實時數(shù)據(jù)核對季俩,保證數(shù)據(jù)最終一致性钮糖。