在云計(jì)算發(fā)展飛速的時(shí)代,傳統(tǒng)通訊正在與互聯(lián)網(wǎng)、IT等各大領(lǐng)域融合發(fā)展,無論是IM、視頻、VoIP、還是呼叫中心,企業(yè)都需要根據(jù)自身業(yè)務(wù)形態(tài)開發(fā)和部署屬于自己的通訊平臺(tái)。那么,在用戶群體不斷壯大之時(shí),云平臺(tái)如何該支持百萬千萬或者上億的在線用戶?日前, 容聯(lián)云通訊CTO(首席技術(shù)官)許志強(qiáng)為程序員們帶來了一場(chǎng)主題為“云通訊PaaS平臺(tái)的挑戰(zhàn)和應(yīng)對(duì)之道”的在線培訓(xùn)。
一個(gè)云平臺(tái)怎么支持百萬千萬或者上億的在線用戶?許志強(qiáng)認(rèn)為這里有幾個(gè)關(guān)鍵點(diǎn):
1、操作系統(tǒng)調(diào)優(yōu)
第一步是操作系統(tǒng)的調(diào)優(yōu),因?yàn)椴僮飨到y(tǒng)的缺省設(shè)置并不是適合這種大規(guī)模的系統(tǒng)訪問的,包括打開文件數(shù)、TCP接收發(fā)送緩沖等,你需要根據(jù)你的業(yè)務(wù)請(qǐng)將操作系統(tǒng)各項(xiàng)的參數(shù)設(shè)置進(jìn)行一個(gè)調(diào)優(yōu)。
2、采用異步接口
第二步,因?yàn)楝F(xiàn)在大多數(shù)的網(wǎng)絡(luò)協(xié)議都是基于TCPIP協(xié)議的,客戶端在很多情況下是非活躍的,那么要單臺(tái)機(jī)器處理幾十萬或者上百萬以上的連接需要采用異步的接口。在Linux上使用的是epoll,在windows上就是I/O Completion Port. 十年前,我們會(huì)討論一臺(tái)Web服務(wù)器怎么支撐一萬個(gè)用戶(著名的C10K問題),現(xiàn)在這個(gè)問題已經(jīng)隨著操作系統(tǒng)的完善已經(jīng)非常輕易的解決了,關(guān)鍵是怎么使用操作系統(tǒng)提供的這些接口?,F(xiàn)在如果采用長連接,目前的技術(shù)水平達(dá)到幾十萬甚至上百萬(依賴實(shí)際的吞吐量)的長連接單臺(tái)服務(wù)器是沒有任何問題的。
3、內(nèi)存數(shù)據(jù)庫緩存、減少數(shù)據(jù)庫操作
第三點(diǎn),我們知道數(shù)據(jù)庫的操作是比較重的,像內(nèi)存數(shù)據(jù)有可能用(Memcache、Redis)或者各種內(nèi)存數(shù)據(jù)庫緩存一些數(shù)據(jù),減少數(shù)據(jù)庫的操作,衡量哪些數(shù)據(jù)放內(nèi)存數(shù)據(jù)庫中的一個(gè)重要原則就是: 如果數(shù)據(jù)訪問比較頻繁,可以通過key訪問,業(yè)務(wù)邏輯上不需要強(qiáng)一致的數(shù)據(jù)適合放內(nèi)存數(shù)據(jù)庫。
4、內(nèi)部模塊交換采用長連接、Protocol Buffer等
系統(tǒng)內(nèi)部盡可能采用長連接,因?yàn)橄到y(tǒng)的每一次連接都是一個(gè)開銷,可能在低負(fù)載情況下沒有關(guān)系,每次請(qǐng)求一個(gè)連接,看上去也挺快,一秒鐘幾百個(gè)請(qǐng)求,一千多請(qǐng)求也行,但是一旦系統(tǒng)負(fù)荷增大,這部分開銷在整個(gè)系統(tǒng)開銷就會(huì)非常大了。另外在協(xié)議編碼的盡可能采用像Protocol Buffer的協(xié)議,這是谷歌開源的協(xié)議,具有很好的編解碼效率和傳輸流量優(yōu)化。
5、節(jié)點(diǎn)可并行擴(kuò)展、Cluster集群
設(shè)計(jì)的時(shí)候需要考慮各個(gè)模塊、節(jié)點(diǎn)是否可并行擴(kuò)展的?是不是增加一個(gè)模塊、節(jié)點(diǎn)就能夠提供服務(wù)擴(kuò)展系統(tǒng)容量?將每個(gè)節(jié)點(diǎn)盡可能做成無狀態(tài)的,只有做到這點(diǎn),系統(tǒng)才能可擴(kuò)展、才能做集群、才能采用Cluster集群來做負(fù)載均衡服務(wù)。
6、自動(dòng)部署新業(yè)務(wù)節(jié)點(diǎn)支持服務(wù)的自動(dòng)化擴(kuò)容
云服務(wù)的用戶可能突然業(yè)務(wù)量大增,系統(tǒng)能不能通過自動(dòng)部署解決彈性自動(dòng)擴(kuò)容?這是云通訊現(xiàn)在正在做的。我們跟運(yùn)營商的線路不是可以通過動(dòng)態(tài)增加的,那是物理接口沒有辦法增加的。但是針對(duì)IP端的設(shè)備我們是可以做自動(dòng)部署的,像阿里云、亞馬遜,可以提供API讓你自動(dòng)地創(chuàng)建虛擬的主機(jī),你可以提前做好相應(yīng)的磁盤映像, 當(dāng)檢測(cè)到某個(gè)類型的設(shè)備負(fù)責(zé)過高后,可以通過接口把這個(gè)服務(wù)部署起來。當(dāng)你業(yè)務(wù)節(jié)點(diǎn)快速增加的時(shí)候,你采用這種自動(dòng)部署的方案可以大幅減少人工干預(yù)維護(hù)的工作。
7.一次性Hash的負(fù)載分配方式
講到集群,就必須說的是集群中負(fù)載的分配方式。舉個(gè)例子,之前阿里云余額寶是從IOE架構(gòu)移到阿里云上,當(dāng)時(shí)存在一個(gè)很大的一個(gè)挑戰(zhàn),余額寶的請(qǐng)求量太大了,mysql數(shù)據(jù)庫性能不夠,怎么解決這個(gè)問題呢? 常見的方法就是根據(jù)賬號(hào)分?jǐn)?shù)據(jù)庫、分系統(tǒng)處理,按照賬號(hào)分配到對(duì)應(yīng)的數(shù)據(jù)庫和處理系統(tǒng), 這就是負(fù)載分配的方式。一般來說,大家一個(gè)很直觀的想法可能是根據(jù)這個(gè)帳號(hào)做一下hash計(jì)算。有三個(gè)節(jié)點(diǎn),就除三,余數(shù)在哪兒就去哪個(gè)節(jié)點(diǎn),這是慣用的思路。但是這里有一個(gè)問題,之前的三個(gè)節(jié)點(diǎn),后來可能變成四個(gè)節(jié)點(diǎn),五個(gè)節(jié)點(diǎn),一旦變成四個(gè)節(jié)點(diǎn),五個(gè)節(jié)點(diǎn)以后,原來的Hash的值就不對(duì)了,如果加了一個(gè)節(jié)點(diǎn)以后,后面所有的分配都會(huì)不對(duì),數(shù)據(jù)庫什么都要重新調(diào)整,整個(gè)負(fù)載會(huì)劇烈的進(jìn)行一個(gè)移動(dòng),對(duì)增加處理節(jié)點(diǎn)是不友好的。
下面是百度上的一個(gè)圖,這個(gè)是一次性Hash的負(fù)載分配方式:
假如這是一個(gè)環(huán),這個(gè)環(huán)是從0到2的32次方,我們保證Hash出來的值在這個(gè)區(qū)間內(nèi)隨機(jī)分布。在這個(gè)區(qū)間內(nèi),我們這里只有四個(gè)節(jié)點(diǎn),圖中藍(lán)色的節(jié)點(diǎn)是我們的服務(wù)節(jié)點(diǎn)。當(dāng)一個(gè)請(qǐng)求來了,或者一個(gè)帳號(hào)來了,這個(gè)請(qǐng)求是由誰來服務(wù)呢?我們把這個(gè)請(qǐng)求計(jì)算一個(gè)hash,hash值會(huì)落在這個(gè)環(huán)的其中一個(gè)點(diǎn)上,就是圖中的這個(gè)紫色的點(diǎn)。紫色的點(diǎn)實(shí)際上不是一個(gè)具體的服務(wù)點(diǎn),它會(huì)按方向找最近的點(diǎn),假如我們以順時(shí)針方向,他就找順時(shí)針最近的一個(gè)點(diǎn)。假如在第三和四節(jié)點(diǎn)之間,這兩個(gè)節(jié)點(diǎn)的負(fù)載增加了,我們就在這兩個(gè)節(jié)點(diǎn)中間加一個(gè)節(jié)點(diǎn),把他們中間的負(fù)載做一個(gè)分擔(dān),這樣其他的節(jié)點(diǎn)負(fù)責(zé)的這種負(fù)載請(qǐng)求不會(huì)波動(dòng)不會(huì)發(fā)生變化。只有落在我們分配的節(jié)點(diǎn)順時(shí)針之前的節(jié)點(diǎn)會(huì)有一些變化。所以這樣就非常容易把一個(gè)節(jié)點(diǎn)加到里面不影響整個(gè)系統(tǒng)的動(dòng)蕩。