以190億美元的價(jià)格出售給Facebook,交易談判過(guò)程中更受到了拉里·佩奇的勸阻,WhatsApp確實(shí)取得了一場(chǎng)輝煌的勝利。然而不可忽視的是,該公司用以服務(wù)4.5億活躍用戶(hù)的工程團(tuán)隊(duì)只有區(qū)區(qū)32人。近日HighScalability創(chuàng)始人Tod Hoff撰文分析了這一天價(jià)收購(gòu)的原因和WhatsApp的高可靠架構(gòu),雖然并不完整,但還是有許多值得學(xué)習(xí)的地方。
以下為譯文:
從WhatsApp軟件架構(gòu)師Rick Reed在3月份即將發(fā)表的演講介紹中(That's 'Billion' with a 'B': Scaling to the next level at WhatsApp),我們可以得知WhatsApp當(dāng)下的一些輪廓:
現(xiàn)在,WhatsApp有數(shù)百個(gè)節(jié)點(diǎn)、數(shù)千個(gè)核心及數(shù)百TB的內(nèi)存,我們的目標(biāo)是服務(wù)全世界數(shù)十億用戶(hù)。在WhatsApp,我們使用了Erlang/基于FreeBSD服務(wù)器基礎(chǔ)設(shè)施,為了應(yīng)對(duì)消息的增長(zhǎng)需求,我們必須克服一個(gè)又一個(gè)挑戰(zhàn),可以說(shuō)在系統(tǒng)容量(大于8000核心)和速度(每秒Erlang消息超7000萬(wàn))上的極限挑戰(zhàn)從未停歇!
鑒于這個(gè)演講在3月份才發(fā)布,這里我們不妨聚焦Rick Reed兩年前的分享—— WhatsApp如何應(yīng)對(duì)數(shù)百萬(wàn)的同時(shí)鏈接數(shù)。
在Yahoo!供職時(shí),Rick Reed曾負(fù)責(zé)用C++建立高性能的消息總線(xiàn),因此他對(duì)高擴(kuò)展性架構(gòu)并不陌生。WhatsApp創(chuàng)始人中還包括了一個(gè)擁有大量擴(kuò)展經(jīng)驗(yàn)的Yahoo!工程師,不難得知,WhatsApp有現(xiàn)在的成就與兩個(gè)創(chuàng)始人的超凡技術(shù)是分不開(kāi)的。而企圖成為全世界50億手機(jī)服務(wù)商的遠(yuǎn)大目標(biāo),他們也必須將技術(shù)推向極限!
190億美元的交易的背后
做為一個(gè)程序員,如果你問(wèn)WhatsApp是否值那么多,我的答案必然是否定的!因?yàn)楫a(chǎn)品真正價(jià)值不在于那些死板的代碼,而在如何讓用戶(hù)喜歡并且使用。
著眼這個(gè)應(yīng)用的特點(diǎn),我們知道WhatsApp是一個(gè)世界級(jí)的 零噱頭(零廣告,零創(chuàng)意,零游戲)產(chǎn)品,在SMS收費(fèi)時(shí)代提供了一個(gè)免費(fèi)的信息交互平臺(tái)。當(dāng)下,這個(gè)應(yīng)用已被數(shù)量巨大的美國(guó)人使用,因此一旦有用戶(hù)加入,即會(huì)在上面發(fā)現(xiàn)大量的親朋好友。在手機(jī)如此普及年代,WhatsApp絕對(duì)稱(chēng)得上填補(bǔ)了美國(guó)社交網(wǎng)絡(luò)上的空白。鑒于其跨平臺(tái)特性,所以每個(gè)人都可以使用它;值得關(guān)注的是,它還可以傳遞各種格式信息,比如共享地理位置、發(fā)送語(yǔ)音及視頻等。WhatsApp有著非常出色的國(guó)際化,使用手機(jī)號(hào)碼作為驗(yàn)證信息、聯(lián)系人列表作為社交圖,因此你不需要郵箱驗(yàn)證、用戶(hù)名及密碼,更不需要提供信用卡等號(hào)碼信息——“it just works”。
雖然WhatsApp有著如此的誘人特性,但是它仍然不值190億美元,而且對(duì)于互聯(lián)網(wǎng)巨頭來(lái)說(shuō),這樣的特性模仿起來(lái)也并不復(fù)雜。
WhatsApp之所以能賣(mài)190億美元可能有多個(gè)原因: 第1, 如Google CEO Larry Page所說(shuō);第2, WhatsApp已經(jīng)威脅到Facebook;第3,F(xiàn)acebook正在褪色,需要補(bǔ)充大量新鮮血液;第4, WhatsApp是你的電話(huà)簿;第5,WhatsApp可以收集到大量的元數(shù)據(jù)(雖然他們并未保存)。
準(zhǔn)確的說(shuō),190億美元收購(gòu)WhatsApp是為了它的 4.5億用戶(hù),為了它的日百萬(wàn)用戶(hù)增加,為了它可能會(huì)有10億用戶(hù)的潛能——Facebook需要WhatsApp成為下一個(gè)10億用戶(hù)應(yīng)用,當(dāng)然只能成為它的一部分。同時(shí),40美元一個(gè)用戶(hù)的價(jià)格也并不離譜,特別是以股票充當(dāng)大部分金額。Facebook曾今使用 30美元每用戶(hù)的價(jià)格收購(gòu)了Instagram,而 Twitter的每個(gè)用戶(hù)更值110美元。
Benedict Evans 做了一個(gè)非常棒的預(yù)測(cè),移動(dòng)是一個(gè)萬(wàn)億級(jí)的市場(chǎng)。WhatsApp通過(guò)每天發(fā)送180億SMS消息(整個(gè)SMS系統(tǒng)每天發(fā)送的消息也只有200億條)攪亂了整個(gè)SMS市場(chǎng),而這個(gè)市場(chǎng)有著超過(guò)1億美元的稅收。在智能手機(jī)采用越發(fā)普及的年代,WhasApp有著比Facebook更清晰的盈利思路。然而,在承諾了零廣告和零干涉后,F(xiàn)acebook又會(huì)從何處得益?
在 移動(dòng)應(yīng)用業(yè)務(wù)開(kāi)發(fā)上有著許多有趣的用例, WhatsApp則經(jīng)常被項(xiàng)目團(tuán)隊(duì)用來(lái)建立會(huì)話(huà)組,風(fēng)投們也樂(lè)于將它作為交易流程中的對(duì)話(huà)工具。
Instagram被Kuwait用來(lái)出售綿羊。
WeChat,WhatsApp的一個(gè)競(jìng)爭(zhēng)者,在1月份推出了一個(gè)叫車(chē)服務(wù);值得關(guān)注的是,僅僅一個(gè)月,這個(gè)應(yīng)用上的 打車(chē)成交量就達(dá)到了2100萬(wàn)。
商業(yè)活動(dòng)看起來(lái)確實(shí)很適合WhatsApp,但是它的用途顯然還有更多——西班牙警察使用它來(lái)抓捕罪犯,意大利人們使用它來(lái)組織籃球比賽。
鑒于每個(gè)人都有手機(jī)而且消息應(yīng)用已變得更加強(qiáng)大、自由及便宜,商業(yè)及其它類(lèi)型應(yīng)用程序已逐步向移動(dòng)端過(guò)渡。許多功能已不再只能用桌面或Web應(yīng)用程序?qū)崿F(xiàn),消息應(yīng)用已初露鋒芒。
其中,許多應(yīng)用已經(jīng)對(duì)Facebook和Google產(chǎn)生威脅,桌面和網(wǎng)絡(luò)皆將成為過(guò)去, 消息+移動(dòng)將讓整個(gè)系統(tǒng)愈加偏離這些巨頭的王國(guó),那么在這股移動(dòng)的大潮中Facebook又該何去何從?
隨著移動(dòng)化的更加深入,F(xiàn)acebook的地位已愈發(fā)岌岌可危,用戶(hù)的流逝顯然已不可避免。桌面Web是Facebook后端所有特性的入口,它非常的肥胖、復(fù)雜及陳舊,當(dāng)下已經(jīng)很少有人會(huì)喜歡Facebook的UI。
在Facebook確定了“Mobile first”這個(gè)移動(dòng)方案后,更深度的打磨被執(zhí)行——不僅建立不同用途的應(yīng)用,同時(shí)也提供了多個(gè)具有類(lèi)似功能和相互競(jìng)爭(zhēng)的應(yīng)用,這些應(yīng)用有時(shí)甚至不會(huì)共享相同的后臺(tái)基礎(chǔ)設(shè)施,比如:Messenger和WhatsApp,Instagram和Facebook圖片應(yīng)用。Paper也是Facebook一個(gè)限制功能候補(bǔ)入口,但是它表現(xiàn)得非常好。
在Mobile World Congress上,F(xiàn)acebook CEO Mark Zuckerberg發(fā)表了自己的看法, 他認(rèn)為收購(gòu)WhatsApp與Internet.org的愿景緊密相連:
這個(gè)思想就是建立一組基礎(chǔ)互聯(lián)網(wǎng)的免費(fèi)服務(wù)——“互聯(lián)網(wǎng)的911”,這可能是類(lèi)似Facebook這樣的社交網(wǎng)絡(luò)服務(wù)、消息服務(wù)以及搜索服務(wù)等。將這些服務(wù)提供給那些支付得起卻沒(méi)有支付意識(shí)的用戶(hù),引誘其上癮,讓他們知道自己的重要性,從而更愿意使用更多的收費(fèi)服務(wù)。
這是個(gè)長(zhǎng)久的目標(biāo),這個(gè)舞臺(tái)里有足夠多的利益去追逐,然而即時(shí)回報(bào)率卻非常的低, Facebook正在這條道路上前行著
拋開(kāi)這次交易不談,WhatsApp究竟是如何用32個(gè)工程師來(lái)支撐4.5億的活躍用戶(hù),下面一起探索……
服務(wù)4.5億用戶(hù)的高可靠架構(gòu)
信息源
需要注意的是, WhatsApp的整體架構(gòu)并未公開(kāi),這里僅僅是從不同信息源中獲取不同的片段。Rick Reed的講座主要分享了使用Erlang實(shí)現(xiàn)單服務(wù)器200萬(wàn)連接數(shù),雖然很有價(jià)值,但是并不是整個(gè)應(yīng)用架構(gòu)。
- Rick Reed: 擴(kuò)展到數(shù)百萬(wàn)并發(fā)連接數(shù)(2012, PPT)
- Rick Reed: Erlang Factory(訪(fǎng)談)
- Eugene Fooksman: WhatsApp的Erlang使用(訪(fǎng)談)
- DLD14: 關(guān)于WhatsApp(Jan Koum和David Rowan)
- Yowsup以前是WhatsApp的一個(gè)開(kāi)源API,但是由于 棄用了DMCA當(dāng)下已不可用,但是同樣可以說(shuō)明WhatsApp的一些內(nèi)部工作機(jī)制。
- 相關(guān)文章中列出的一些信息。
一、 統(tǒng)計(jì)
這些統(tǒng)計(jì)是當(dāng)下系統(tǒng)的一些數(shù)據(jù),更多針對(duì)數(shù)據(jù)存儲(chǔ)、消息、meta-clustering以及新加入的BEAM/OTP補(bǔ)丁。
- 4.5億的活躍用戶(hù),并且是史上最快達(dá)到這個(gè)數(shù)字的公司
- 32個(gè)工程師,平均每人支撐1400萬(wàn)活躍用戶(hù)
- 每天收發(fā)跨7個(gè)平臺(tái)的500億消息
- 平均每天注冊(cè)用戶(hù)過(guò)百萬(wàn)
- 0廣告開(kāi)銷(xiāo)
- 800萬(wàn)投資
- 數(shù)百個(gè)節(jié)點(diǎn)
- 8000+核心
- 數(shù)百TB內(nèi)存
- 每秒Erlang消息超過(guò)7000萬(wàn)
- 在2011年,WhatsApp單服務(wù)器取得 100萬(wàn)個(gè)tcp會(huì)話(huà),同時(shí)還有內(nèi)存和CPU剩余。在2012年, tcp會(huì)話(huà)發(fā)展到了200萬(wàn)。2013年WhatsApp 發(fā)表tweet聲明,70億消息入站,110億消息出戰(zhàn),即每天處理180億消息,偉大的2013!
二、 平臺(tái)
后端
- Erlang
- FreeBSD
- Yaws、lighttpd
- PHP
- BEAM定制補(bǔ)丁(BEAM類(lèi)似于Java的JVM,但適用于Erlang)
- 定制XMPP
前端
- 7個(gè)客戶(hù)端平臺(tái):iPhone、Android、Blackberry、Nokia Symbian 360、Nokia S40、Windows Phone和一個(gè)未知的
- SQLite
三、 硬件
標(biāo)準(zhǔn)的面向用戶(hù)服務(wù)器:
- Dual Westmere Hex-core(24個(gè)邏輯CPU)
- 100 GB RAM、SSD
- Dual NIC(公共面向用戶(hù)的網(wǎng)絡(luò)、私有的后端 /分布)
四、 產(chǎn)品
- 聚焦消息傳遞。連接來(lái)自世界各地的用戶(hù),忽視他們的地理位置,無(wú)需支付高額費(fèi)用,創(chuàng)始人Jan Koum還經(jīng)常提起1992年在世界各地與家里人聯(lián)系是多么的難。
- 隱私。由Jan Koum制定,消息不會(huì)在服務(wù)器上儲(chǔ)存,聊天記錄也不會(huì)儲(chǔ)存,目的就是不去了解用戶(hù)隱私。不會(huì)保存用戶(hù)姓名及性別,聊天記錄只存儲(chǔ)在電話(huà)上。
五、通用
1. WhatsApp服務(wù)器基本上完全使用Erlang實(shí)現(xiàn)
- 做后端消息路由的服務(wù)器系統(tǒng)使用Erlang實(shí)現(xiàn)
- 值得炫耀的是,如此龐大數(shù)量的活躍用戶(hù)只使用非常少的服務(wù)器來(lái)管理,團(tuán)隊(duì)一致認(rèn)為這很大程度上歸功于Erlang。
- 值得注意的是,F(xiàn)acebook Chat就是在2009年使用Erlang開(kāi)發(fā),他們棄用Erlang的原因是難以招聘到優(yōu)秀的程序員。
2. WhatsApp服務(wù)器最早從Ejabberd開(kāi)始
- Ejabberd是個(gè)非常出名的開(kāi)源Jabber服務(wù)器,使用Erlang實(shí)現(xiàn)。
- 最初選用它的原因是開(kāi)放、廣受開(kāi)發(fā)者關(guān)注、易于開(kāi)始以及Erlang在大型通信系統(tǒng)上的長(zhǎng)期口碑。
- 接下來(lái)的許多年一直從事Ejabberd的重寫(xiě)和修改,包括從XMPP轉(zhuǎn)換到內(nèi)部開(kāi)發(fā)協(xié)議、調(diào)整代碼庫(kù)以及重設(shè)計(jì)一些核心組件,對(duì)Erlang VM做了大量的修改以獲得高性能。
3. 為了應(yīng)對(duì)每天500億消息,工作重心被放到可靠系統(tǒng)的打造上,貨幣化對(duì)于我們來(lái)說(shuō)還是件遙遠(yuǎn)的事情。
4. 系統(tǒng)的健康狀況主要看隊(duì)列的長(zhǎng)度,每個(gè)節(jié)點(diǎn)上消息隊(duì)列的長(zhǎng)度都會(huì)被一直監(jiān)控,超過(guò)預(yù)先設(shè)置的臨界值則會(huì)發(fā)出提醒,多個(gè)警報(bào)發(fā)生則標(biāo)志著系統(tǒng)進(jìn)入了下一個(gè)瓶頸。
5. 通過(guò)上傳圖片、音頻、視頻到一個(gè)HTTP服務(wù)器上來(lái)發(fā)送多媒體消息,然后將鏈接與Base64編碼的縮略圖一起添加到內(nèi)容(如果可用)。
6. 有些代碼基本上每天都在變化,通常情況下是一天幾次;當(dāng)然,峰值期間必須避開(kāi)的。Erlang非常適用于將修改或者是新功能添加到產(chǎn)品,熱加載意味著無(wú)需重新啟動(dòng)就可以實(shí)現(xiàn)修改,錯(cuò)誤可以很快的得到解決,同樣通過(guò)熱加載,系統(tǒng)變得更加松耦合,這可以讓更新快速的發(fā)布。
7. WhatsApp使用了什么樣的協(xié)議?WhatsApp服務(wù)器池使用了SSL Socket,在客戶(hù)端重新連接對(duì)消息進(jìn)行檢索之前,所有消息都會(huì)在服務(wù)器上排隊(duì)。消息的成功檢索會(huì)發(fā)回給WhatsApp服務(wù)器,它將會(huì)被重新轉(zhuǎn)發(fā)給原始發(fā)送者;一旦客戶(hù)端成功接收這條消息,它就會(huì)在服務(wù)器存儲(chǔ)中擦除。
8. WhatsApp注冊(cè)程序的內(nèi)部工作機(jī)制是什么樣的?WhasApp依賴(lài)電話(huà)IMEI號(hào)碼來(lái)建立用戶(hù)名/密碼,這點(diǎn)在最近已經(jīng)修改。WhatsApp現(xiàn)在會(huì)讓?xiě)?yīng)用發(fā)送一個(gè)包含5位數(shù)Pin的一般請(qǐng)求,然后給這個(gè)電話(huà)號(hào)碼發(fā)送一個(gè)SMS,這意味著WhatsApp客戶(hù)端不再受限于某臺(tái)手機(jī)。基于Pin的號(hào)碼,應(yīng)用會(huì)從WhatsApp請(qǐng)求一個(gè)唯一的鍵,這個(gè)鍵將作為未來(lái)的使用密碼,這同樣意味著在新的設(shè)備上注冊(cè)后會(huì)無(wú)效原有設(shè)備上的鍵。
9. 在Android上使用了Google的推送服務(wù)。
10. 在Android上有更多的客戶(hù)。與Android打交道更讓大家愉快,開(kāi)發(fā)者能夠快速的基于一個(gè)特性構(gòu)建原型,并以最短的時(shí)間推出,如果存在問(wèn)題的話(huà)也可以快速修復(fù),iOS則不行。
六、單服務(wù)器上200萬(wàn)連接數(shù)的探索
1. 雖然用戶(hù)增長(zhǎng)是喜聞樂(lè)見(jiàn)的,但是它同樣意味著你得投入更多錢(qián)去購(gòu)買(mǎi)硬件;同時(shí),機(jī)器數(shù)量的增加也大幅增加了管理和運(yùn)維復(fù)雜性。
2. 需要為流量的起伏做規(guī)劃,例子就是西班牙的足球比賽和墨西哥的地震。這些現(xiàn)實(shí)世界中發(fā)生的大事件造成了非常高的流量峰值,因此需要有足夠的剩余容量來(lái)應(yīng)對(duì)流量高峰+突發(fā)事件,比如一場(chǎng)近期的足球比賽產(chǎn)生了當(dāng)天35%的出站消息。
3. 初始的服務(wù)器負(fù)載是每個(gè)服務(wù)器20萬(wàn)并發(fā)連接。
- 預(yù)期將會(huì)添加大量的服務(wù)器來(lái)維持用戶(hù)增加。
- 服務(wù)器會(huì)因?yàn)樨?fù)載的爆發(fā)而宕機(jī),網(wǎng)絡(luò)及其它的故障也會(huì)發(fā)生。這時(shí)候需要做一些組件的解耦,這樣一來(lái)可以添加容量以應(yīng)對(duì)峰值。
- 目標(biāo)是單服務(wù)器支撐百萬(wàn)連接數(shù),這個(gè)目標(biāo)在只有20萬(wàn)連接數(shù)時(shí)已經(jīng)制定。動(dòng)態(tài)的容量規(guī)劃以應(yīng)對(duì)世界級(jí)事件、硬件故障及其它類(lèi)型的小故障,系統(tǒng)需要足夠的彈性去應(yīng)對(duì)高使用率和故障。
七、用來(lái)增強(qiáng)可擴(kuò)展性的工具和技術(shù)
1. 編寫(xiě)系統(tǒng)活動(dòng)報(bào)告工具(wsar):
- 記錄整個(gè)系統(tǒng)狀態(tài),包括OS狀態(tài)、硬件狀態(tài)、BEAM狀態(tài)。這是為了便于從其他系統(tǒng)獲取狀態(tài)信息,如虛擬內(nèi)存。跟蹤記錄CPU利用率、系統(tǒng)整體利用率、用戶(hù)時(shí)間、系統(tǒng)時(shí)間、中斷時(shí)間、上下文切換、系統(tǒng)調(diào)用、traps、數(shù)據(jù)包發(fā)送和接收、所有進(jìn)程隊(duì)列中總消息數(shù)、繁忙的端口事件、通信速率、字節(jié)輸入/輸出、調(diào)度狀態(tài),垃圾回收狀態(tài)等。
- 最初一分鐘運(yùn)行一次,當(dāng)系統(tǒng)運(yùn)行變得困難時(shí),時(shí)間段將降為1秒鐘一次,因?yàn)橐环昼姛o(wú)法運(yùn)行的情況很少發(fā)生。了解所有系統(tǒng)運(yùn)行情況需要非常細(xì)粒度的統(tǒng)計(jì)數(shù)據(jù)。
2. CPU(pmcstat)中的硬件性能計(jì)數(shù)器:
通過(guò)查看CPU時(shí)間占用百分比,可以了解正在執(zhí)行的模擬器(emulator)周期時(shí)間。假如是16%,說(shuō)明只有16%的時(shí)間執(zhí)行模擬代碼,所以即使你能消除所有Erlang代碼的執(zhí)行時(shí)間,也只能節(jié)省總運(yùn)行時(shí)間16%,這意味著你應(yīng)該將重點(diǎn)放在其他方面以提高系統(tǒng)的效率。
3. dtrace、 內(nèi)核鎖計(jì)數(shù)、fprof
- Dtrace是主要用于調(diào)試,而不是提高性能。
- 在FreeBSD上給BEAM打補(bǔ)丁加入CPU時(shí)間戳。
- 寫(xiě)腳本創(chuàng)建所有進(jìn)程的聚合視圖,查看哪些程序一直在占用系統(tǒng)資源。
- 最大的勝利是給模擬器啟用鎖計(jì)數(shù)。
4. 一些問(wèn)題:
- 早期發(fā)現(xiàn)很多時(shí)間花在了垃圾回收程序上,這個(gè)問(wèn)題已經(jīng)被解決了。
- 發(fā)現(xiàn)一些網(wǎng)絡(luò)堆棧的問(wèn)題,后來(lái)堆棧被調(diào)走了。
- 大多數(shù)問(wèn)題是關(guān)于模擬器的鎖沖突,主要體現(xiàn)在鎖計(jì)數(shù)的輸出上。
5. 度量
- 綜合的工作負(fù)載,這意味著從你自己的測(cè)試腳本中生成流量,這對(duì)極限規(guī)模下面向用戶(hù)系統(tǒng)調(diào)優(yōu)沒(méi)有價(jià)值。
- 對(duì)于用戶(hù)表這樣簡(jiǎn)單的接口效果不錯(cuò),生成接入然后盡可能快地讀取。
- 假如在一臺(tái)服務(wù)器只支持100萬(wàn)連接,那么整個(gè)系統(tǒng)將需要30臺(tái)這樣的主機(jī)去打開(kāi)足夠的IP端口,生成足夠多的連接;然而,這么多的開(kāi)銷(xiāo)僅僅可以測(cè)試一臺(tái)服務(wù)器。對(duì)于測(cè)試200萬(wàn)個(gè)連接的服務(wù)器需要用到60個(gè)主機(jī),生成這樣的規(guī)模真的很難。
- 很難生成生產(chǎn)環(huán)境下的那種流量。在正常的工作量下還可以估算,但在現(xiàn)實(shí)中看到的那些網(wǎng)絡(luò)事件、世界事件,這主要因?yàn)槎嗥脚_(tái)上客戶(hù)端的不同用戶(hù)行為,而且不同國(guó)家之間也有差異。
- Tee’d 工作負(fù)載
- 采用正常生產(chǎn)環(huán)境流量,然后把它放到一個(gè)單獨(dú)的系統(tǒng)中。
- 這對(duì)系統(tǒng)非常有用,因?yàn)楫a(chǎn)生的副作用會(huì)受到限制。不想看到網(wǎng)絡(luò)擁堵,或者對(duì)用戶(hù)造成影響。
- Erlang支持熱加載,所以可以在完整生產(chǎn)負(fù)荷下產(chǎn)生想法、編譯,在程序運(yùn)行時(shí)加載變化,而且能即時(shí)看到變化的好壞。
- 添加旋鈕動(dòng)態(tài)調(diào)節(jié)生產(chǎn)加載,觀察它對(duì)性能的影響。觀察特征輸出,比如CPU使用率、VM 使用率、監(jiān)聽(tīng)隊(duì)列溢出并調(diào)節(jié)旋鈕,看看系統(tǒng)會(huì)有怎樣的反應(yīng)。
- 真正的生產(chǎn)負(fù)載
- 最終測(cè)試。輸入工作和輸出工作都要測(cè)試。
- 多次將服務(wù)器放入DNS中,使其得到正常情況兩倍或三倍的流量。TTL事務(wù)會(huì)產(chǎn)生問(wèn)題,因?yàn)榭蛻?hù)端不會(huì)遵守DNS TTL,而且這里還會(huì)有延遲,因此無(wú)法快速做出反應(yīng)以獲得更多可以被處理的流量。
- IPFW. 將一臺(tái)服務(wù)器的流量轉(zhuǎn)移給另一臺(tái),這樣可以使主機(jī)的連接數(shù)達(dá)到理想的水平。內(nèi)核如果因?yàn)橛袀€(gè)Bug就奔潰是不行的。
6. 結(jié)果
- 開(kāi)始時(shí)每個(gè)服務(wù)器有20萬(wàn)個(gè)并發(fā)連接。
- 第一個(gè)瓶頸出現(xiàn)每臺(tái)服務(wù)器42.5萬(wàn)個(gè)連接的時(shí)候。系統(tǒng)遇到了很多沖突,工作停止了。安裝調(diào)度器檢測(cè)有多少有用的任務(wù)被停止、睡眠,或回轉(zhuǎn)了。在加載時(shí),它開(kāi)始遇到睡眠鎖,整個(gè)系統(tǒng)只用35-45%的CPU利用率,但調(diào)度程序的CPU利用率卻達(dá)到了95%。
- 第一輪修復(fù)使連接數(shù)超過(guò)100萬(wàn)個(gè)。
- VM利用率為76%,CPU利用率為73%,BEAM模擬器利用率為45%,與用戶(hù)百分比很吻合,這是件好事,因?yàn)槟M器得和用戶(hù)一樣。
- 通常CPU利用率并不是好的評(píng)估方法,因?yàn)榭赡苡捎谡{(diào)度程序使用CPU導(dǎo)致系統(tǒng)看起來(lái)很忙。
- 一個(gè)月以后解決了瓶頸,每個(gè)服務(wù)器連接數(shù)達(dá)到200萬(wàn)個(gè)。
- BEAM利用率為80%,與FreeBSD開(kāi)始分頁(yè)的情況接近。CPU利用率大致相同,有兩倍的連接數(shù)。調(diào)度程序遇到了沖突,但運(yùn)行得很好。
- 看來(lái)測(cè)試可以暫停了,這時(shí)開(kāi)始分析Erlang代碼。
- 最初每個(gè)連接有兩個(gè)Erlang進(jìn)程,消減為一個(gè)。
- 用計(jì)時(shí)器完成一些工作。
- 在每個(gè)服務(wù)器有280萬(wàn)連接時(shí)達(dá)到頂峰
- 571k pkts/sec, >200k dist msgs/sec
- 做一些內(nèi)存優(yōu)化,VM加載下降到70%。
- 嘗試過(guò)將連接數(shù)增加到300萬(wàn),但沒(méi)有成功。
- 當(dāng)系統(tǒng)遇到故障時(shí),查看長(zhǎng)消息隊(duì)列(單個(gè)消息隊(duì)列或消息隊(duì)列總和)。
- 將每個(gè)進(jìn)程的消息隊(duì)列統(tǒng)計(jì)添加到BEAM設(shè)備上。包括發(fā)送/接收了多少條消息以及發(fā)送/接收的速度。
- 每10秒取樣一次,可以看到一個(gè)進(jìn)程有60萬(wàn)條消息,每15秒延遲出列4萬(wàn)條消息。預(yù)計(jì)完全出列時(shí)間是41秒。
7. 一些發(fā)現(xiàn):
- Erlang + BEAM + 它們的補(bǔ)丁——可以具有接近線(xiàn)性的SMP可擴(kuò)展性。在24路服務(wù)器上運(yùn)行系統(tǒng),CPU利用率達(dá)到85%,持續(xù)運(yùn)行負(fù)載——它可以像這樣運(yùn)行一整天。
- Erlang程序模型的證明。
- 服務(wù)器使用的時(shí)間越長(zhǎng),其積累長(zhǎng)時(shí)間運(yùn)行連接就越多,但不是每個(gè)連接都很忙碌,其中大多數(shù)是閑置的,所以服務(wù)器使用時(shí)間越長(zhǎng)能夠處理的連接數(shù)也就越多。
- 沖突是最大的問(wèn)題。
- Erlang代碼中的一些修復(fù)可以減少BEAM的沖突問(wèn)題。
- 向BEAM添加一些補(bǔ)丁。
- 分區(qū)負(fù)載工作不需要頻繁跨處理器運(yùn)行。
- Time-of-day鎖。每次從一個(gè)端口發(fā)送消息都會(huì)針對(duì)所有調(diào)度程序產(chǎn)生一個(gè)Time-of-day鎖,這意味著所有的CPU都會(huì)遇到同一個(gè)鎖。
- 優(yōu)化計(jì)數(shù)器的使用,移除bif計(jì)數(shù)器
- 發(fā)現(xiàn)IO時(shí)間表算術(shù)增長(zhǎng)。創(chuàng)建VM抖動(dòng)使哈希表在不同的時(shí)間點(diǎn)重新分配,改進(jìn)使用幾何分配表。
- 通過(guò)你已經(jīng)打開(kāi)的端口添加寫(xiě)入文件,以減少端口沖突。
- Mseg分配是所有分配器沖突的交點(diǎn),因此創(chuàng)建好每一個(gè)調(diào)度程序。
- 獲得一個(gè)連接時(shí)會(huì)有很多端口事務(wù),設(shè)置選項(xiàng)降低昂貴的端口交互。
- 當(dāng)消息隊(duì)列積壓太多的話(huà),垃圾回收會(huì)破壞系統(tǒng)穩(wěn)定性。所以暫停 GC,直到隊(duì)列收縮。
- 避免一些不必要的麻煩。
- 從FreeBSD 9移植一個(gè)TSE計(jì)時(shí)器到FreeBSD 8。讀取計(jì)時(shí)器開(kāi)銷(xiāo)更小,快速時(shí)間,比讀取芯片還要便宜。
- 從FreeBSD 9移植igp網(wǎng)絡(luò)驅(qū)動(dòng)程序,因?yàn)槎鄠€(gè)隊(duì)列會(huì)因?yàn)镹IC鎖定出問(wèn)題。
- 增加文件和套接字的數(shù)目。
- Pmcstat顯示很多時(shí)間被用來(lái)在網(wǎng)絡(luò)堆棧中查找PCB,所以擴(kuò)大哈希表讓查詢(xún)更快些。
- BEAM補(bǔ)丁
- 之前提到過(guò)的設(shè)備補(bǔ)丁。植入設(shè)備調(diào)度程序用來(lái)獲取使用信息、信息隊(duì)列統(tǒng)計(jì)信息、sleep數(shù)、發(fā)送率、消息數(shù)等。可以在Erlang代碼中使用procinfo(任務(wù)管理)實(shí)現(xiàn),但有100萬(wàn)的連接時(shí),這一過(guò)程會(huì)變得非常慢。
- 統(tǒng)計(jì)數(shù)據(jù)收集非常高效,所以它們可以在生產(chǎn)中運(yùn)行。
- 統(tǒng)計(jì)數(shù)據(jù)保持3個(gè)不同衰變間隔:1秒、10秒和100秒。允許隨時(shí)觀測(cè)發(fā)生的問(wèn)題。
- 讓鎖計(jì)數(shù)為更大的異步線(xiàn)程計(jì)數(shù)工作。
- 為調(diào)試鎖計(jì)數(shù)器添加調(diào)試選項(xiàng)。
- 調(diào)試
- 設(shè)置低調(diào)度程序的喚醒值,因?yàn)檎{(diào)度程序一旦進(jìn)入睡眠就再也無(wú)法喚醒。
- mseg分配器優(yōu)于malloc。
- 每個(gè)調(diào)度程序每個(gè)實(shí)例都有個(gè)分配器。
- 配置大的carrier,而且還會(huì)越來(lái)越大。導(dǎo)致FreeBSD使用超級(jí)頁(yè),降低 TLB thrash比率,并為相同的CPU提高了吞吐量。
- 以實(shí)時(shí)優(yōu)先級(jí)運(yùn)行BEAM,這樣其他的東西比如cron作業(yè)就不會(huì)打斷調(diào)度程序。防止小故障導(dǎo)致重要用戶(hù)通信的阻塞。
- 打補(bǔ)丁下調(diào)spin數(shù),從而使調(diào)度程序不會(huì)spin。
- Mnesia
- 相比erlang:now,更喜歡os:timestamp。
- 不使用事務(wù),用遠(yuǎn)程的備份,并行復(fù)制每個(gè)表以提高吞吐量。
- 事實(shí)上還對(duì)許多地方進(jìn)行了修改。
八、經(jīng)驗(yàn)總結(jié)
1. 優(yōu)化是件非常艱辛的事情,也只有工程師去做。Rick在回顧大量的修改后(使每個(gè)服務(wù)器連接數(shù)達(dá)到200),更覺(jué)得頭皮發(fā)麻。大量的工作包括編寫(xiě)工具、運(yùn)行測(cè)試、增加補(bǔ)丁、把讓人眼花繚亂的方法添加到堆棧的每一層、調(diào)試系統(tǒng)、尋找蛛絲馬跡,每一個(gè)細(xì)節(jié)都不能放過(guò),你需要努力讓一切都在掌握之中。只有這樣才能消除瓶頸,提高性能以及最大程度地實(shí)現(xiàn)可擴(kuò)展性。
2. 獲取你需要的數(shù)據(jù);編寫(xiě)工具;為工具添加補(bǔ)丁;添加調(diào)控旋鈕。擴(kuò)展系統(tǒng)獲取更多數(shù)據(jù)是Ken不懈的追求,為了獲取他們需要的數(shù)據(jù),需要不停地編寫(xiě)工具、腳本來(lái)管理和優(yōu)化系統(tǒng)。為了數(shù)據(jù),不惜一切代價(jià)。
3. 度量;消除瓶頸;測(cè)試;不斷重復(fù)這樣的過(guò)程。枯燥無(wú)聊,但你需要這樣做。
4. Erlang很給力!Erlang繼續(xù)證明其作為一個(gè)多用途、可靠、高性能平臺(tái)的優(yōu)良品質(zhì)。雖然Erlang也需要大量的調(diào)整和修補(bǔ),這些工作難免會(huì)讓人對(duì)Erlang產(chǎn)生質(zhì)疑。
5. 破解病毒式代碼,獲得利潤(rùn)。“病毒式”現(xiàn)在是優(yōu)良品質(zhì)的代名詞,就像WhatsApp那樣,只要你真得做到了,那意味著你得到了很多很多錢(qián)。
6. 價(jià)值和員工數(shù)現(xiàn)在已經(jīng)沒(méi)有直接聯(lián)系了。如今,員工的數(shù)量并不能說(shuō)明什么。先進(jìn)的世界級(jí)電信基礎(chǔ)設(shè)施使WhatsApp這樣的應(yīng)用程序成為可能。如果WhatsApp還需要做網(wǎng)絡(luò)或手機(jī)等設(shè)備,那可能根本就不會(huì)有WhatsApp這樣的公司存在。功能強(qiáng)大、價(jià)格廉價(jià)的硬件和開(kāi)源的軟件也無(wú)疑使WhatsApp的成功事半功倍。換句話(huà)說(shuō)WhatsApp的成功在于它在正確的地點(diǎn)、時(shí)間為正確的用戶(hù)提供了正確的產(chǎn)品。
7. 能夠重視用戶(hù)想法是很了不起的。WhatsApp 將自身定位成一個(gè)簡(jiǎn)單的消息傳遞應(yīng)用,而不是游戲網(wǎng)絡(luò)、廣告網(wǎng)絡(luò)或者已經(jīng)面臨消亡的照片網(wǎng)絡(luò),這一點(diǎn)很重要。這樣的定位使他們沒(méi)有在應(yīng)用中添加廣告,他們努力保持應(yīng)用簡(jiǎn)單的同時(shí)添加新功能,傻瓜型操作方式使WhatsApp適用于每一個(gè)用戶(hù)。
8. 考慮到簡(jiǎn)單性,有一些限制是允許的。你的身份被綁定到電話(huà)號(hào)碼,所以如果你更改了電話(huà)號(hào)碼你的身份就失效了。這和一般的應(yīng)用程序確實(shí)有點(diǎn)不太一樣,但卻使整個(gè)系統(tǒng)在設(shè)計(jì)上變得更加簡(jiǎn)單了。
9. 年齡上的歧視。2009年,因?yàn)槟挲g歧視,WhatsApp創(chuàng)始人Brian Acton在Twitter和Facebook連一份工作都找不到,那就讓它們后悔去吧。
10. 先從簡(jiǎn)單的開(kāi)始然后再深度定制。聊天剛推出時(shí),服務(wù)器端基于jabberd,現(xiàn)在它已經(jīng)被完全重寫(xiě),但那個(gè)確實(shí)是Erlang方向上的第一步。Erlang初次使用時(shí)就體現(xiàn)出的可擴(kuò)展性、可靠性和可操作性,這使得到了越來(lái)越廣泛的應(yīng)用。
11. 保持低的服務(wù)器數(shù)量。努力讓服務(wù)器盡可能的少,同時(shí)為短暫高峰期預(yù)留足夠的上升空間。分析并優(yōu)化直到達(dá)到收益遞減點(diǎn),然后再部署更多的硬件。
12. 有目的地增加冗余服務(wù)器。這可以確保在公司放假時(shí)也能為用戶(hù)提供不間斷的服務(wù),員工可以享受假期而不用花時(shí)間修復(fù)過(guò)載問(wèn)題。
13. 賺錢(qián)時(shí)也要考慮公司的成長(zhǎng)。WhatsApp免費(fèi)時(shí)成長(zhǎng)是最快的,早期每天都有1萬(wàn)次的下載量。然后轉(zhuǎn)向付費(fèi)時(shí),下載量下降至每天1000次。在年底增加了圖片消息后,他們就把按下載次數(shù)付費(fèi)改成了按年收費(fèi)。
14. 靈感總來(lái)自最意想不到的地方。忘記Skype用戶(hù)名和密碼的經(jīng)歷無(wú)疑給WhatsApp帶來(lái)了靈感。