劉 平,王治國(guó),曹 剛,吳 迪,彭 升
(中國(guó)網(wǎng)絡(luò)電視臺(tái),北京 100142)
《第27次中國(guó)互聯(lián)網(wǎng)絡(luò)發(fā)展?fàn)顩r統(tǒng)計(jì)報(bào)告》顯示,截至2010年12月,中國(guó)網(wǎng)民規(guī)模達(dá)到4.57億,較2009年底增加7330萬(wàn)人;互聯(lián)網(wǎng)普及率攀升至34.3%,較2009年提高5.4個(gè)百分點(diǎn)。另外,《報(bào)告》顯示,中國(guó)網(wǎng)民的互聯(lián)網(wǎng)應(yīng)用表現(xiàn)出商務(wù)類(lèi)應(yīng)用用戶規(guī)模繼續(xù)領(lǐng)漲、網(wǎng)絡(luò)娛樂(lè)漸入平穩(wěn)期、社交類(lèi)應(yīng)用保持較快發(fā)展速度的特點(diǎn)[1]。
Web2.0[2]的浪潮席卷了整個(gè)互聯(lián)網(wǎng),帶來(lái)了人們對(duì)互聯(lián)網(wǎng)應(yīng)用的徹底轉(zhuǎn)變?;诹瓤臻g理論發(fā)展起來(lái)的社會(huì)化網(wǎng)絡(luò)服務(wù)或社交網(wǎng)站(Social Network Service,SNS),是Web2.0的典型代表。SNS通過(guò)網(wǎng)絡(luò)服務(wù)不僅幫助人們找到朋友、合作伙伴,而且能夠?qū)崿F(xiàn)個(gè)人數(shù)據(jù)處理、個(gè)人社會(huì)關(guān)系管理、信息共享和知識(shí)分享,最終幫助用戶利用信任關(guān)系拓展自己的社交網(wǎng)絡(luò),達(dá)成更有價(jià)值的溝通和協(xié)作,從而帶來(lái)豐富的商業(yè)機(jī)會(huì)和巨大的社會(huì)價(jià)值。
從2005年開(kāi)始,以Facebook為代表的SNS類(lèi)網(wǎng)站在一夜之間火遍全球,無(wú)數(shù)類(lèi)似的網(wǎng)站出現(xiàn)在互聯(lián)網(wǎng)上。2010年上半年,F(xiàn)acebook的訪問(wèn)量首次超過(guò)Google,成為全球流量最大的網(wǎng)站。在國(guó)內(nèi),SNS也在蓬勃發(fā)展,成為過(guò)去兩年最熱門(mén)的網(wǎng)站類(lèi)型之一。
動(dòng)態(tài)(feeds)是將用戶在網(wǎng)站的活動(dòng)進(jìn)行記錄并推送到其好友主頁(yè)的功能,目前已經(jīng)廣泛用于社交網(wǎng)站。動(dòng)態(tài)功能很好地把用戶和內(nèi)容結(jié)合起來(lái),大幅提高了用戶的互動(dòng)。當(dāng)用戶在站內(nèi)進(jìn)行某些操作行為后,該用戶相關(guān)的好友會(huì)收到相應(yīng)的此用戶行為的消息通知。筆者認(rèn)為用戶看見(jiàn)好友的行為通知后很可能也跟進(jìn)一個(gè)的類(lèi)似或相關(guān)的行為,這就是“黏度”的體現(xiàn)。因此,好友動(dòng)態(tài)系統(tǒng)是大型互動(dòng)平臺(tái)的核心,承載著各個(gè)業(yè)務(wù)系統(tǒng)與用戶之間的互動(dòng)。
本文分析了大型互動(dòng)平臺(tái)中好友動(dòng)態(tài)系統(tǒng)架構(gòu)面臨的調(diào)整,確定了架構(gòu)設(shè)計(jì)的模式和原則,并詳細(xì)介紹了好友動(dòng)態(tài)系統(tǒng)架構(gòu)的設(shè)計(jì)與實(shí)現(xiàn)。
對(duì)于網(wǎng)站運(yùn)營(yíng)來(lái)說(shuō),以下場(chǎng)景在網(wǎng)站的整個(gè)生命周期里很有可能出現(xiàn),而且一旦出現(xiàn)都是系統(tǒng)的噩夢(mèng):
1)場(chǎng)景一:某硬件或服務(wù)故障可能導(dǎo)致整個(gè)網(wǎng)站不可用
系統(tǒng)上線運(yùn)營(yíng)后,各項(xiàng)業(yè)務(wù)都逐漸進(jìn)入上升軌道,活躍用戶也穩(wěn)步增加,各項(xiàng)數(shù)據(jù)都表明網(wǎng)站在年輕人群中的社會(huì)影響力與日俱增,此時(shí)系統(tǒng)中一個(gè)機(jī)器發(fā)生宕機(jī),開(kāi)始有用戶的某些操作無(wú)響應(yīng),然后更多相關(guān)的服務(wù)獲取不到數(shù)據(jù),最后甚至用戶根本無(wú)法登錄系統(tǒng)。故障已經(jīng)發(fā)生,用戶已受到影響,當(dāng)務(wù)之急是快速恢復(fù)機(jī)器工作,縮短故障時(shí)間。如果機(jī)器只是掉電宕機(jī),設(shè)備并無(wú)大礙,重新啟動(dòng)系統(tǒng)后一切恢復(fù)正常;如果磁盤(pán)等硬件發(fā)生故障,需要將應(yīng)用遷移到備份服務(wù)器,快速啟動(dòng)備用服務(wù)器。
如何避免單點(diǎn)故障或者將單點(diǎn)故障的影響降到最低呢?
2)場(chǎng)景二:新增業(yè)務(wù)規(guī)則或?qū)σ郧皹I(yè)務(wù)規(guī)則的升級(jí)導(dǎo)致重新開(kāi)發(fā)系統(tǒng)
系統(tǒng)經(jīng)過(guò)一兩年的運(yùn)營(yíng)逐步趨于穩(wěn)定,但產(chǎn)品團(tuán)隊(duì)和開(kāi)發(fā)團(tuán)隊(duì)之間的爭(zhēng)論卻越來(lái)越多,產(chǎn)品團(tuán)隊(duì)開(kāi)始抱怨新的創(chuàng)意無(wú)法得到快速響應(yīng),開(kāi)發(fā)團(tuán)隊(duì)沒(méi)日沒(méi)夜加班仍然有干不完的活,對(duì)系統(tǒng)功能的改造總是牽一發(fā)動(dòng)全身,更別說(shuō)開(kāi)發(fā)新的業(yè)務(wù)。
如何讓架構(gòu)能夠適應(yīng)未來(lái)業(yè)務(wù)的發(fā)展,為潛在的擴(kuò)展點(diǎn)進(jìn)行設(shè)計(jì)?
3)場(chǎng)景三:春節(jié)期間活躍用戶激增導(dǎo)致系統(tǒng)性能下降
春節(jié)前,營(yíng)銷(xiāo)團(tuán)隊(duì)在電視媒體、平面媒體、網(wǎng)絡(luò)媒體等進(jìn)行了全方位的營(yíng)銷(xiāo)宣傳,而且效果非常明顯,春節(jié)期間活躍用戶數(shù)快速增長(zhǎng),甚至超過(guò)去年整年的增長(zhǎng),但隨之而來(lái)的是,隨著用戶數(shù)的增長(zhǎng),以前沒(méi)有發(fā)現(xiàn)的問(wèn)題開(kāi)始暴露出來(lái),運(yùn)營(yíng)團(tuán)隊(duì)不得不每天堅(jiān)守崗位,甚至采用輪班制,但網(wǎng)站的響應(yīng)時(shí)間還是下降了,而且開(kāi)始出現(xiàn)間隔性的中斷服務(wù),用戶開(kāi)始抱怨,開(kāi)始選擇其他平臺(tái)。
如何應(yīng)對(duì)潛在的用戶數(shù)激增對(duì)系統(tǒng)服務(wù)質(zhì)量的影響?
大型互動(dòng)平臺(tái)中好友動(dòng)態(tài)系統(tǒng)的架構(gòu)挑戰(zhàn)主要來(lái)自于設(shè)備、服務(wù)和用戶,因此假設(shè):1)所有的硬件和服務(wù)總會(huì)有故障;2)業(yè)務(wù)規(guī)則在運(yùn)營(yíng)過(guò)程總會(huì)發(fā)生變化;3)用戶數(shù)會(huì)在某個(gè)時(shí)間呈現(xiàn)爆炸式增長(zhǎng)。
好友動(dòng)態(tài)的架構(gòu)實(shí)現(xiàn)有兩種選擇:拉模式和推模式(見(jiàn)表1)。推模式,指用戶發(fā)表一條動(dòng)態(tài)時(shí),動(dòng)態(tài)系統(tǒng)將這條動(dòng)態(tài)拷貝N次分發(fā)給他的粉絲或好友;用戶讀取時(shí),直接從“我的動(dòng)態(tài)”和“好友動(dòng)態(tài)”中讀取動(dòng)態(tài)列表。拉模式,指當(dāng)用戶查詢動(dòng)態(tài)消息時(shí),從所有好友的動(dòng)態(tài)隊(duì)列中獲取動(dòng)態(tài),拿到這些動(dòng)態(tài)后再做排序和合并操作;用戶發(fā)表動(dòng)態(tài)時(shí),直接發(fā)布到自己的隊(duì)列中。
表1 推模式與拉模式的比較
結(jié)合項(xiàng)目的實(shí)際需求,項(xiàng)目組認(rèn)為推模式架構(gòu)簡(jiǎn)單,能夠給用戶提供更好的產(chǎn)品體驗(yàn),而多占用的存儲(chǔ)空間是可以接受的。
針對(duì)好友動(dòng)態(tài)系統(tǒng)架構(gòu)面臨的調(diào)整,項(xiàng)目組為架構(gòu)設(shè)計(jì)確定如下架構(gòu)原則[3]:
1)可靠性
可靠的服務(wù)是系統(tǒng)的基礎(chǔ),隨著系統(tǒng)中設(shè)備數(shù)量、服務(wù)數(shù)量的增加,服務(wù)大規(guī)模分布式部署,可靠性的成本越來(lái)越高。服務(wù)的可靠性也不再局限于設(shè)備的可靠,設(shè)計(jì)可靠的軟件架構(gòu)才能從根本上提高系統(tǒng)可靠性。
2)可伸縮性
可伸縮性就是通過(guò)增加資源使服務(wù)容量產(chǎn)生線性(理想情況下)增長(zhǎng)的能力??缮炜s應(yīng)用程序的主要特點(diǎn)是:附加負(fù)載只需要增加資源,而不需要對(duì)應(yīng)用程序本身進(jìn)行大量修改??缮炜s性包括兩個(gè)方面,向上伸縮(Scale-Up)和水平伸縮(Scale-Out)。
向上伸縮指通過(guò)使用性能更好、速度更快和成本更高的硬件來(lái)實(shí)現(xiàn)可伸縮性。包括添加更多內(nèi)存、添加更多或更快的處理器,或者只是將應(yīng)用程序遷移到功能更強(qiáng)大的單個(gè)計(jì)算機(jī)。通常,該方法能夠在不改變?cè)创a的情況下增加容量。從管理角度而言,情況并未發(fā)生變化,因?yàn)橐芾淼娜匀恢皇且慌_(tái)計(jì)算機(jī)。
水平伸縮的實(shí)現(xiàn)需要使用多臺(tái)計(jì)算機(jī),但計(jì)算機(jī)集合本質(zhì)上是作為單個(gè)計(jì)算機(jī)運(yùn)行的。通過(guò)使若干臺(tái)計(jì)算機(jī)專(zhuān)門(mén)執(zhí)行常見(jiàn)的任務(wù),增加了應(yīng)用程序容錯(cuò)。當(dāng)然,從管理員的角度看,外擴(kuò)使計(jì)算機(jī)的數(shù)目增多,從而提出了更大的管理挑戰(zhàn)。
考慮到高性能設(shè)備成本昂貴,服務(wù)器都采用普通的PC或PC服務(wù)器,可伸縮性需要更多依賴水平伸縮,即通過(guò)更多的普通設(shè)備擴(kuò)展系統(tǒng)整體容量。
3)高并發(fā)性
系統(tǒng)的注冊(cè)用戶數(shù)決定了必須解決大量用戶并發(fā)訪問(wèn)系統(tǒng)的問(wèn)題,而且隨著網(wǎng)站整體影響力的擴(kuò)展,用戶數(shù)會(huì)更大。此外,為了提供更豐富的用戶體驗(yàn),在用戶登錄網(wǎng)站期間會(huì)定期訪問(wèn)好友動(dòng)態(tài)系統(tǒng),獲得更新的數(shù)據(jù)。以1000萬(wàn)注冊(cè)用戶為例,10萬(wàn)用戶同時(shí)在線,每個(gè)用戶10 s刷新一次動(dòng)態(tài)數(shù)據(jù),那么每秒將會(huì)有10000個(gè)并發(fā)請(qǐng)求,這樣的規(guī)模是傳統(tǒng)網(wǎng)絡(luò)不可比擬的,也是好友動(dòng)態(tài)系統(tǒng)架構(gòu)的重點(diǎn)。
4)大數(shù)據(jù)量
一個(gè)用戶的每一個(gè)操作都會(huì)以消息的形式通知給其全部數(shù)量的好友;同樣其全部好友的每一個(gè)操作也將以消息的形式通知給用戶。好友動(dòng)態(tài)系統(tǒng)的特點(diǎn)決定了好友越多系統(tǒng)的數(shù)據(jù)量就會(huì)越大。數(shù)據(jù)顯示,在Facebook網(wǎng)站等級(jí)的粉絲,全球最具人氣的人物是當(dāng)紅女歌星La?dy Gaga,她的注冊(cè)粉絲達(dá)到了2200萬(wàn)。
5)業(yè)務(wù)規(guī)則可擴(kuò)展
好友動(dòng)態(tài)系統(tǒng)是互動(dòng)平臺(tái)的核心引擎,幾乎所有應(yīng)用都需要通過(guò)好友動(dòng)態(tài)系統(tǒng)與用戶進(jìn)行互動(dòng),每個(gè)應(yīng)用的業(yè)務(wù)邏輯和數(shù)據(jù)標(biāo)準(zhǔn)又有很大的差異;而且為了保證消息質(zhì)量,具有良好的可閱讀性必須對(duì)用戶的消息進(jìn)行合并。因此需要架構(gòu)設(shè)計(jì)支持靈活的業(yè)務(wù)規(guī)則。
好友動(dòng)態(tài)系統(tǒng)整體上采用分布式系統(tǒng)架構(gòu)方法,消息按流水線的方式進(jìn)行處理,分別由轉(zhuǎn)發(fā)服務(wù)器、分發(fā)服務(wù)器和消息服務(wù)器處理,其中最重要的好友關(guān)系信息從好友關(guān)系系統(tǒng)獲得,并緩存在關(guān)系緩存集群中。另外,為了實(shí)現(xiàn)自動(dòng)化運(yùn)營(yíng),好友動(dòng)態(tài)系統(tǒng)提供了服務(wù)監(jiān)視系統(tǒng)和配置管理系統(tǒng),如圖1所示。轉(zhuǎn)發(fā)服務(wù)器將客戶端發(fā)布的動(dòng)態(tài)消息轉(zhuǎn)發(fā)到分發(fā)服務(wù)器;分發(fā)服務(wù)器對(duì)客戶端的消息進(jìn)行預(yù)處理,并根據(jù)好友關(guān)系將動(dòng)態(tài)消息推送到各個(gè)好友的消息服務(wù)器;好友關(guān)系緩存服務(wù)器為分發(fā)服務(wù)器提供好友關(guān)系緩存,提高分發(fā)服務(wù)器消息推送性能;消息服務(wù)器接收分發(fā)服務(wù)器推送的消息,對(duì)消息進(jìn)行合并處理,存儲(chǔ)用戶的動(dòng)態(tài)消息,并為用戶提供動(dòng)態(tài)檢索服務(wù)。
3.2.1 水平伸縮
大型互動(dòng)系統(tǒng)的特點(diǎn)是用戶基數(shù)大,而且無(wú)法預(yù)測(cè)將來(lái)的用戶數(shù)會(huì)達(dá)到什么水平,因此設(shè)計(jì)之初就考慮采用水平伸縮方案。當(dāng)用戶規(guī)模增長(zhǎng)后,不需要修改系統(tǒng)的源代碼,只需要增加普通的PC或PC服務(wù)器,部署更多的分布式服務(wù),就可以擴(kuò)充系統(tǒng)的容量,提升系統(tǒng)的性能。
系統(tǒng)的整體架構(gòu)上,各個(gè)關(guān)鍵服務(wù)都支持水平伸縮,包括轉(zhuǎn)發(fā)服務(wù)器、分發(fā)服務(wù)器、消息服務(wù)器。
客戶端隨機(jī)選擇轉(zhuǎn)發(fā)服務(wù)器發(fā)布消息。當(dāng)用戶數(shù)增加,要求轉(zhuǎn)發(fā)服務(wù)器集群提供更高的并發(fā),更快的響應(yīng)時(shí)間時(shí),可以部署更多的轉(zhuǎn)發(fā)服務(wù)器,降低單個(gè)服務(wù)器的負(fù)載,提升響應(yīng)時(shí)間。
用戶ID與分發(fā)服務(wù)器進(jìn)行綁定,綁定的算法有靜態(tài)綁定算法、哈希求余算法、一致性哈希算法等,這些算法的復(fù)雜度依次提高,而進(jìn)行依次下降,但服務(wù)器數(shù)量擴(kuò)展的友好型也依次提高。根據(jù)好友動(dòng)態(tài)系統(tǒng)用戶ID線性增長(zhǎng)的特點(diǎn),最終采用簡(jiǎn)單有效的靜態(tài)綁定算法。轉(zhuǎn)發(fā)服務(wù)器將用戶的消息發(fā)布到該用戶綁定的分發(fā)服務(wù)器。當(dāng)用戶數(shù)增加,要求分發(fā)服務(wù)器集群提供更高的并發(fā),更快的響應(yīng)時(shí)間時(shí),可以部署更多的分發(fā)服務(wù)器,這樣單個(gè)分發(fā)服務(wù)器承載的用戶數(shù)沒(méi)有變化,響應(yīng)時(shí)間也不會(huì)受到影響。
用戶ID與消息服務(wù)器進(jìn)行綁定,仍然采用靜態(tài)綁定,一個(gè)消息服務(wù)器只為某個(gè)號(hào)段的用戶提供服務(wù)。當(dāng)新注冊(cè)用戶增加時(shí),最后一個(gè)服務(wù)器的壓力會(huì)不斷增加,再增加一臺(tái)服務(wù)器將新注冊(cè)的用戶號(hào)段劃分到這個(gè)服務(wù)器,從而控制最后一臺(tái)服務(wù)器的壓力;當(dāng)某個(gè)號(hào)段的用戶活躍程度顯著增加時(shí),可以將該號(hào)段重新劃分,進(jìn)行負(fù)載均衡。
3.2.2 消息隊(duì)列
隊(duì)列使系統(tǒng)的各個(gè)模塊之間實(shí)現(xiàn)松耦合,將同步業(yè)務(wù)調(diào)用轉(zhuǎn)化為異步處理過(guò)程。在系統(tǒng)架構(gòu)方面,關(guān)鍵業(yè)務(wù)模塊之間都是通過(guò)消息隊(duì)列實(shí)現(xiàn)異步消息處理,如圖2所示。
在此架構(gòu)中,因?yàn)楦鱾€(gè)服務(wù)只關(guān)心與其交換的消息隊(duì)列,中間處理的各個(gè)服務(wù)的故障都不會(huì)影響都之前或之后的業(yè)務(wù)處理,而且服務(wù)恢復(fù)后能夠繼續(xù)提供服務(wù)。因此消息中間件的穩(wěn)定性和性能是衡量中間件的關(guān)鍵指標(biāo)。Kestrel是twitter開(kāi)源的消息隊(duì)列中間件[4],在twit?ter以及大量網(wǎng)站中經(jīng)過(guò)實(shí)踐檢驗(yàn),穩(wěn)定性和性能都非常不錯(cuò),內(nèi)部測(cè)試也證明可以滿足項(xiàng)目的需求,因此項(xiàng)目組選擇kestrel作為消息中間件。而且Kestrel采用mem?cached兼容的協(xié)議,這也是大多消息隊(duì)列中間件支持的協(xié)議接口,即使系統(tǒng)運(yùn)行中發(fā)現(xiàn)Kestrel隊(duì)列存在問(wèn)題,也可以快速遷移到其他消息中間件。
各個(gè)服務(wù)模塊采用無(wú)狀態(tài)的服務(wù)模式,即服務(wù)模塊每次都根據(jù)消息隊(duì)列中的消息進(jìn)行處理,這樣即使遇到一些惡意的非法消息也能夠正常處理,不會(huì)影響其他消息的處理。
此外消息隊(duì)列還有蓄洪的作用。好友動(dòng)態(tài)系統(tǒng)中,當(dāng)發(fā)生特殊事件時(shí)用戶會(huì)有一個(gè)爆發(fā)效應(yīng),比如世界杯期間活躍用戶數(shù)會(huì)有爆炸式增長(zhǎng)。消息隊(duì)列的作用是,當(dāng)洪峰到來(lái)時(shí),快速容納大量請(qǐng)求,從而不影響隊(duì)列前端應(yīng)用的性能,然后隊(duì)列后端的應(yīng)用慢慢處理隊(duì)列中的消息。對(duì)于動(dòng)態(tài)系統(tǒng)來(lái)說(shuō),只是延遲了動(dòng)態(tài)被好友感知的時(shí)間,而且這種延遲好友是很難感知的,但對(duì)系統(tǒng)的負(fù)載能力的提升非常明顯。
3.2.3 緩存機(jī)制
眾所周知,內(nèi)存的訪問(wèn)速度遠(yuǎn)遠(yuǎn)高于硬盤(pán)的訪問(wèn)速度,因此緩存的效果對(duì)網(wǎng)站的響應(yīng)時(shí)間至關(guān)重要。緩存將系統(tǒng)中需要大量計(jì)算或頻繁訪問(wèn)的資源由硬盤(pán)轉(zhuǎn)移到內(nèi)存中,降低系統(tǒng)IO的處理的時(shí)間,從而提高訪問(wèn)的響應(yīng)時(shí)間。
系統(tǒng)架構(gòu)方面緩存主要應(yīng)用在分發(fā)服務(wù)器和消息服務(wù)器。
分發(fā)服務(wù)器中,每個(gè)消息的處理都需要用戶的好友關(guān)系,這些信息存儲(chǔ)在好友關(guān)系數(shù)據(jù)庫(kù)中,如果每次處理都直接訪問(wèn)數(shù)據(jù)庫(kù),每秒大概需要2000次并發(fā)的數(shù)據(jù)庫(kù)訪問(wèn),這樣的壓力對(duì)數(shù)據(jù)庫(kù)來(lái)說(shuō)是致命的,很快就會(huì)發(fā)現(xiàn)已經(jīng)連不上數(shù)據(jù)庫(kù),而且查詢數(shù)據(jù)庫(kù)的響應(yīng)時(shí)間也會(huì)很長(zhǎng)。因此將好友關(guān)系加載到內(nèi)存中,將極大地提升查詢性能,而且好友關(guān)系的緩存命中率也決定了分發(fā)服務(wù)器的消息處理性能。
為用戶關(guān)系緩沖設(shè)計(jì)了兩個(gè)功能模塊,緩存服務(wù)器集群和用戶關(guān)系變更通知服務(wù)。前者將好友關(guān)系數(shù)據(jù)庫(kù)中的好友信息緩存在內(nèi)存中;后者在好友關(guān)系數(shù)據(jù)庫(kù)發(fā)生變更時(shí),及時(shí)將變更的信息更新到緩存服務(wù)器集群。
消息服務(wù)器一方面接收分發(fā)服務(wù)器寫(xiě)入的消息,另一方面響應(yīng)客戶端的查詢消息,而且兩者都存在大量的并購(gòu),對(duì)響應(yīng)時(shí)間也有一定要求,因此都設(shè)計(jì)了緩存機(jī)制。
為了提高分發(fā)服務(wù)器寫(xiě)入消息的性能,消息服務(wù)器在接收消息后立即將消息寫(xiě)入內(nèi)部的消息緩存隊(duì)列中,而不用等待消息合并到用戶的消息隊(duì)列中。
在大量注冊(cè)用戶中,有一部分用戶比較活躍,另外一部分用戶相對(duì)沉寂,客戶端的查詢請(qǐng)求大并發(fā)是活躍用戶的請(qǐng)求,而且活躍用戶往往會(huì)連續(xù)發(fā)送多次查詢請(qǐng)求,因此消息服務(wù)器會(huì)緩存活躍用戶的消息隊(duì)列。對(duì)活躍用戶判斷是否準(zhǔn)確也決定了緩存的效果,那么如何判斷活躍用戶?本文采用最近訪問(wèn)作為判斷依據(jù),即如果用戶訪問(wèn)時(shí)用戶的消息隊(duì)列不在內(nèi)存中,那么訪問(wèn)過(guò)后將會(huì)被加載到內(nèi)存中,下次訪問(wèn)時(shí)直接從內(nèi)存中讀取。當(dāng)內(nèi)存不足時(shí),將會(huì)替換內(nèi)存中最長(zhǎng)時(shí)間未被訪問(wèn)的內(nèi)容。
3.2.4 數(shù)據(jù)格式
數(shù)據(jù)采用互聯(lián)網(wǎng)廣泛應(yīng)用的JSON格式,在流水線的處理過(guò)程中數(shù)據(jù)格式也在不斷發(fā)生變化。
客戶端采用轉(zhuǎn)發(fā)服務(wù)器的數(shù)據(jù)格式發(fā)送消息,格式如圖3所示。
分發(fā)服務(wù)器將轉(zhuǎn)發(fā)服務(wù)器的數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)換成分發(fā)服務(wù)器數(shù)據(jù)機(jī)構(gòu),并分發(fā)到消息服務(wù)器,格式如圖4所示。
分發(fā)服務(wù)器的消息經(jīng)消息服務(wù)器處理后,轉(zhuǎn)換成消息服務(wù)器的數(shù)據(jù)格式,格式如圖5所示。
3.2.5 協(xié)議接口
各個(gè)服務(wù)模塊主要提供對(duì)動(dòng)態(tài)消息讀寫(xiě)、刪除接口,而且動(dòng)態(tài)消息的排序、合并都按內(nèi)部確定的合并規(guī)則執(zhí)行。此外,服務(wù)器內(nèi)部狀態(tài)的監(jiān)視接口為服務(wù)器狀態(tài)監(jiān)視提供了方便,控制接口則讓服務(wù)升級(jí)更加安全。
通信協(xié)議有很多選擇,如支持REST架構(gòu)風(fēng)格的HTTP協(xié)議、SOAP協(xié)議和memcached協(xié)議,即時(shí)通信領(lǐng)域的XMPP協(xié)議等,但最終本文選擇了memcached協(xié)議,其一該協(xié)議支持REST架構(gòu)風(fēng)格,適合于資源訪問(wèn)類(lèi)服務(wù);其二該協(xié)議支持廣泛的客戶端開(kāi)發(fā)語(yǔ)言,如Java、C++、Php、Python、Perl等;其三,系統(tǒng)中消息隊(duì)列和內(nèi)存緩存中間件支持該協(xié)議,因此采用memcached協(xié)議的開(kāi)發(fā)成本和風(fēng)險(xiǎn)是最小的。
轉(zhuǎn)發(fā)服務(wù)器的主要難點(diǎn)在于支持大量客戶端并發(fā)訪問(wèn)。Apache Mina是一個(gè)Java NIO框架,為用戶開(kāi)發(fā)高性能和高擴(kuò)展的網(wǎng)絡(luò)應(yīng)用服務(wù)器帶來(lái)的方便,因此本文選擇基于Mina框架設(shè)計(jì)轉(zhuǎn)發(fā)服務(wù)器。本文的測(cè)試數(shù)據(jù)顯示,基于Mina的轉(zhuǎn)發(fā)服務(wù)器可以支持每秒1000次網(wǎng)絡(luò)消息處理,通過(guò)接收緩沖區(qū)大小還可以進(jìn)一步提高消息的吞吐量。
分發(fā)服務(wù)器中最重要的設(shè)計(jì)是消息處理擴(kuò)展框架,支持靈活的業(yè)務(wù)擴(kuò)展。
消息的預(yù)處理框架,需要針對(duì)每種業(yè)務(wù)類(lèi)型進(jìn)行單獨(dú)的處理,并且要考慮以后新增業(yè)務(wù)類(lèi)型或修改業(yè)務(wù)處理規(guī)則時(shí),盡可能不影響系統(tǒng)其他組件。因此消息處理擴(kuò)展框架基于OSGi框架進(jìn)行設(shè)計(jì)。
OSGi又叫做Java語(yǔ)言動(dòng)態(tài)模塊系統(tǒng)[5-6],它為模塊化應(yīng)用的開(kāi)發(fā)定義了一個(gè)基礎(chǔ)架構(gòu)。在OSGi中,軟件是以Bundle的形式發(fā)布的。一個(gè)Bundle由Java類(lèi)和其他資源構(gòu)成,它可為其他的Bundle提供服務(wù),也可以導(dǎo)入其他Bundle中的Java包。
消息處理流程如圖6所示,各個(gè)Business Processor組織成一個(gè)處理鏈,有Message Processor Center進(jìn)行調(diào)度,并根據(jù)當(dāng)前Business Processor的處理返回值決定下一步調(diào)用哪個(gè)Processor,最后一個(gè)Business Processor將處理后的消息寫(xiě)入輸出消息隊(duì)列。
Business Processor支持兩種范圍類(lèi)型:Next、Term和ProcessorID。 當(dāng) Business Processor返 回 Next,Message Processor Center調(diào)用預(yù)定義的下一個(gè)Business Proces?sor;當(dāng) Business Processor返回 Term,Message Processor Center終止當(dāng)前消息處理鏈,處理下一條消息。
消息處理過(guò)程中,Business Processor可以將消息輸出到其他系統(tǒng),并不影響下一步業(yè)務(wù)的處理;也可以將消息丟棄,從而實(shí)現(xiàn)消息過(guò)濾器的作用。
4.3.1 動(dòng)態(tài)消息數(shù)據(jù)庫(kù)
動(dòng)態(tài)消息數(shù)據(jù)庫(kù)通過(guò)分庫(kù)來(lái)優(yōu)化性能,包括緩存庫(kù)、索引庫(kù)和消息庫(kù)。
消息分發(fā)時(shí),首先將消息分發(fā)到緩存庫(kù),然后由消息處理進(jìn)程分批處理;而在動(dòng)態(tài)查詢時(shí),首先訪問(wèn)索引庫(kù)獲取用戶的消息隊(duì)列(我的動(dòng)態(tài)隊(duì)列或好友動(dòng)態(tài)隊(duì)列)獲取動(dòng)態(tài)的索引,然后根據(jù)動(dòng)態(tài)ID從消息庫(kù)中獲取動(dòng)態(tài)消息,并將結(jié)果合并返回給用戶。
采用增加消息緩存庫(kù)主要出于兩方面考慮,一方面隔離了分發(fā)系統(tǒng)和消息服務(wù)器,分發(fā)服務(wù)器發(fā)布消息與消息服務(wù)器處理消息可以異步處理,只需要將消息發(fā)布到緩存庫(kù),而不必等待消息服務(wù)器處理消息,提高分發(fā)系統(tǒng)的性能。另一方面緩存庫(kù)在不影響消息讀寫(xiě)性能的情況下,又保證了消息可靠性,消息被持久化保存在緩存庫(kù)。
將索引庫(kù)和消息庫(kù)分離,降低了推模式下消息數(shù)據(jù)庫(kù)中重復(fù)消息的數(shù)量。一個(gè)動(dòng)態(tài)的索引大約23~42 byte,而一個(gè)動(dòng)態(tài)消息平均大小是1 kbyte,這樣一個(gè)消息庫(kù)只保存一份動(dòng)態(tài)消息,每個(gè)消息將節(jié)約980 byte。比如一個(gè)名人在消息服務(wù)器上的好友10萬(wàn)個(gè),那么該名人每條動(dòng)態(tài)將節(jié)約98 Mbyte數(shù)據(jù)。
4.3.2 備份與遷移
采用NoSQL數(shù)據(jù)庫(kù)帶來(lái)了高性能,同時(shí)也要面臨NoSQL數(shù)據(jù)庫(kù)備份遷移工具缺乏的現(xiàn)狀,為此開(kāi)發(fā)了針對(duì)動(dòng)態(tài)消息數(shù)據(jù)庫(kù)的備份和遷移工具。
備份工具支持動(dòng)態(tài)消息數(shù)據(jù)庫(kù)熱備份、增量備份,因此設(shè)置計(jì)劃任務(wù)每天執(zhí)行本機(jī)備份,并將備份數(shù)據(jù)自動(dòng)遷移到備份服務(wù)器。消息服務(wù)器故障時(shí),可以快速部署消息服務(wù)器應(yīng)用,并從備份服務(wù)器下載相應(yīng)的動(dòng)態(tài)消息數(shù)據(jù)庫(kù),快速恢復(fù)服務(wù)。
遷移工具支持根據(jù)用戶空間進(jìn)行消息數(shù)據(jù)庫(kù)合并。由于用戶ID與消息數(shù)據(jù)庫(kù)采用靜態(tài)綁定策略,重新劃分用戶空間將涉及到歷史數(shù)據(jù)的遷移,比如系統(tǒng)運(yùn)行一段時(shí)間后,發(fā)現(xiàn)某些消息服務(wù)器中活躍用戶數(shù)少,負(fù)載小,可以將這些消息服務(wù)器合并成一臺(tái)消息服務(wù)器。
系統(tǒng)測(cè)試數(shù)據(jù)顯示,好友動(dòng)態(tài)系統(tǒng)架構(gòu)能夠滿足大量用戶并發(fā)訪問(wèn)、響應(yīng)時(shí)間較快,而且架構(gòu)能夠通過(guò)水平伸縮快速擴(kuò)容系統(tǒng)支持用戶規(guī)模,在穩(wěn)定性方面單個(gè)服務(wù)或硬件的故障對(duì)系統(tǒng)影響較小或只影響一定范圍的用戶。到目前為止,好友動(dòng)態(tài)系統(tǒng)已經(jīng)上線運(yùn)行兩個(gè)多月,表現(xiàn)穩(wěn)定可靠,友好地支撐了互動(dòng)平臺(tái)好友動(dòng)態(tài)的分發(fā)。
[1]CNNIC第27次互聯(lián)網(wǎng)報(bào)告:個(gè)人互聯(lián)網(wǎng)應(yīng)用狀況[EB/OL].(2011-01-19)[2011-04-01].http://it.people.com.cn/GB/119390/118340/212787/212790/13765052.html.
[2]中國(guó)互聯(lián)網(wǎng)協(xié)會(huì).中國(guó)Web2.0發(fā)展?fàn)顩r和調(diào)查報(bào)告[R].北京:中國(guó)互聯(lián)網(wǎng)協(xié)會(huì),2006.
[3]郭欣.構(gòu)建高性能Web站點(diǎn)[M].北京:電子工業(yè)出版社,2009.
[4]鄧侃.解剖Twitter:Twitter系統(tǒng)架構(gòu)設(shè)計(jì)分析[EB/OL].(2010-03-27)[2011-04-01].http://www.tektalk.org.
[5]基于OSGi實(shí)現(xiàn)分布式服務(wù)框架歷程[EB/OL].(2008-01-14)[2011-02-01].http://www.blogjava.net/BlueDavy/archive/2008/01/14/175054.html.
[6]Oracle.Oracle Berkeley DB Java editionhigh availability-large configuration and scalability testing[EB/OL].[2011-03-25].http://www.oracle.com/technetwork/database/berkeleydb/bdb-je-highavailabilitywhitepaper--129298.pdf.