如何設(shè)計一個支撐億級流量的消息隊列

大家可能對億級流量沒有什么概念侵贵,我首先以10億級流量來進(jìn)行一下設(shè)備需求的評估:
每天需要承載10億+請求流量數(shù)據(jù),一天24小時蝇率,對于平臺來說拥坛,晚上12點到凌晨8點這8個小時幾乎沒多少數(shù)據(jù)涌入的。這里我們使用「二八法則」來進(jìn)行預(yù)估读处,也就是80%的數(shù)據(jù)(8億)會在剩余的16個小時涌入糊治,且8億中的80%的數(shù)據(jù)(約6.4億)會在這16個小時的20%時間 (約3小時)涌入。
通過上面的場景分析,可以得出如下:

QPS計算公式 = 640000000 ÷ (3 * 60 * 60) = 6萬

也就是說高峰期集群需要抗住每秒6萬的并發(fā)請求罚舱。

首先從網(wǎng)絡(luò)設(shè)備來看井辜,目前比較普及的是千兆網(wǎng)卡绎谦,首先我們以千兆網(wǎng)卡來進(jìn)行設(shè)備臺數(shù)的估算:

假設(shè)每條數(shù)據(jù)平均按20kb(生產(chǎn)端有數(shù)據(jù)匯總)來算,高峰期的時候粥脚,1000M網(wǎng)卡不可能打滿帶寬窃肠,我們按80%來算,所以每臺機(jī)器能處理的請求數(shù)是

1000*1024kb%0.8/20kb =4W

再考慮到高可靠性問題阿逃,每臺機(jī)器至少需要3個副本铭拧,所以每臺機(jī)器能處理的請求大約是1W左右。

隊列如何設(shè)計恃锉?

從上面的估算我們得出,一臺機(jī)器是搞不定10億請求的呕臂,所以我們需要多臺機(jī)器來解決問題破托。在大學(xué)課本上我們學(xué)過,隊列具備先進(jìn)先出的特性歧蒋,從數(shù)據(jù)結(jié)構(gòu)上來說土砂,需要一個頭尾指針,如果是多機(jī)部署谜洽,那么我們這個頭尾指針就不能記錄到一臺機(jī)器上萝映,所以我們需要一個記錄頭尾指針的地方。

用隊列解決問題阐虚,其實是用生產(chǎn)者消費模式來解決問題序臂,生產(chǎn)者不停往隊列生產(chǎn)數(shù)據(jù),消費者不停進(jìn)行數(shù)據(jù)消費实束。所以兩者需要緊密配合奥秆,不然有一方速度跟不上都會導(dǎo)致10億的目標(biāo)無法實現(xiàn)。

假設(shè)生產(chǎn)者消費的過程中生產(chǎn)的速度很快咸灿,消費的速度很慢构订,如果不限制生產(chǎn)者的生產(chǎn)速度那么可能會出現(xiàn)內(nèi)存的OOM,因為內(nèi)存是有限制的避矢,但是如果為了避免限制生產(chǎn)者的生產(chǎn)悼瘾,因為如果限制了就無法達(dá)到10億的目標(biāo),所以我們要解決這個問題就不可能用內(nèi)存去存儲數(shù)據(jù)审胸,要么把數(shù)據(jù)存儲在磁盤上亥宿,或者數(shù)據(jù)庫。

總體如何設(shè)計歹嘹?

從以上分析我們可以知道箩绍,總體上我們采用分布式的架構(gòu),為了存儲隊列的頭尾指針尺上,我們設(shè)計一個類似于元數(shù)據(jù)的東西材蛛,就是要分布式存儲隊列的頭尾指針來記錄隊列的生產(chǎn)和消費情況圆到,同時我們需要一個服務(wù)節(jié)點來進(jìn)行分布式協(xié)調(diào),我們需要這個服務(wù)節(jié)點來接受生產(chǎn)者生產(chǎn)的數(shù)據(jù)卑吭,同時將數(shù)據(jù)傳遞到消費者手里芽淡,同時這個服務(wù)節(jié)點需要將數(shù)據(jù)進(jìn)行分布式存儲,要么存儲到磁盤豆赏,或者是數(shù)據(jù)庫挣菲。

通過以上的分析這個架構(gòu)基本成型,但是我們還需要在細(xì)節(jié)上去考慮一些東西掷邦,不然還是無法實現(xiàn)目標(biāo)白胀。

首先,我們要考慮消費者如何去服務(wù)節(jié)點獲取數(shù)據(jù)抚岗,一般獲取數(shù)據(jù)方式的有兩種或杠,要么是推(push),要么是拉(pull)宣蔚,那么我們應(yīng)該怎么選擇呢向抢?如果采用推模式,那么這個服務(wù)器節(jié)點必須記錄狀態(tài)胚委,不然無法保證數(shù)據(jù)的順序性和連續(xù)性消費挟鸠,我們知道一旦服務(wù)器有了狀態(tài)是很災(zāi)難的事情,首先服務(wù)器處理起來相當(dāng)復(fù)雜亩冬,其次服務(wù)器需要記錄大量狀態(tài)并進(jìn)行狀態(tài)管理導(dǎo)致資源擴(kuò)張的問題艘希,因為我們不知道我們的客戶即消費者的規(guī)模,而導(dǎo)致服務(wù)器承擔(dān)管理相當(dāng)多的資源鉴未,可能是無限的枢冤,同時推模式因為有了狀態(tài)導(dǎo)致服務(wù)節(jié)點無法做到橫向擴(kuò)展。所以我們只能選擇拉模式铜秆,將狀態(tài)和復(fù)雜性留著客戶端淹真,這樣才能做到服務(wù)端達(dá)到無限水平擴(kuò)展。

其次连茧,我們要考慮數(shù)據(jù)如何存儲的問題核蘸,如果存儲在磁盤上,由于非SSD的磁盤對隨機(jī)讀不友好啸驯,所以我們需要考慮數(shù)據(jù)如何寫入到磁盤的問題客扎,考慮到性能方法肯定是順序?qū)懯切阅茏詈玫模侨绻菍懭氲酱疟P上罚斗,我們考慮到海量數(shù)據(jù)的檢索問題徙鱼,所以需要對文件進(jìn)行分塊存儲和進(jìn)行索引問題。如果是存儲到數(shù)據(jù)庫,我們可以利用數(shù)據(jù)庫的天生的分庫和自帶的索引功能來避免復(fù)雜的設(shè)計袱吆。

如何做到高性能和高可用厌衙?

在高性能方面,可以參考我之前寫的Netty簡介和Dubbo的線程模型兩篇文章绞绒,總體上來說就是借助于IO多路復(fù)用模式同時綜合使用線程池和隊列等技術(shù)來充分壓榨服務(wù)的CPU和IO來為我們所用婶希,總體原則是不能浪費服務(wù)器資源,同時也不能讓服務(wù)器閑置蓬衡。

在高可用方面喻杈,我們需要考慮考慮服務(wù)節(jié)點和存儲數(shù)據(jù)的多副本機(jī)制,然而既然存在多副本狰晚,我們就需要處理多副本的同步問題筒饰,如果不想折騰可以直接使用Zookeeper,zk使用zab協(xié)議保證多副本的同步問題家肯,對于分布式同步協(xié)議可以參考我之前寫的分布式協(xié)議簡介龄砰,很多分布式數(shù)據(jù)為了不依賴于zk,自己實現(xiàn)了Paxos或者Raft實現(xiàn)了副本同步問題讨衣。

由于在存儲方面我們設(shè)計了多分區(qū)存儲,那么可以利用多分區(qū)的特性來加速生產(chǎn)者的生產(chǎn)和消費者的消費式镐,在生產(chǎn)端我們可以讓多個生產(chǎn)者同時將數(shù)據(jù)生產(chǎn)到不同的分區(qū)反镇,消費端讓消費者消費不同的分區(qū),這樣就可以大大提高生產(chǎn)和消費的速度娘汞,對于消費端還要考慮橫向擴(kuò)展問題歹茶,就是如果有消費者上下線要考慮怎么做重平衡問題,保證消費端的均衡消費你弦。

at least once和exactly once

at least once是對一個隊列產(chǎn)品的基本要求惊豺,如果滿足不了這個要求一般都不是一個合格的隊列產(chǎn)品,at least once一般要求客戶端能處理重復(fù)消費的問題禽作,即保證無狀態(tài)尸昧。exactly once是最難的,要實現(xiàn)這點旷偿,我們需要保證消息僅僅被投遞一次烹俗,那么我們需要在服務(wù)端不能丟消息,也不能重復(fù)投遞消息萍程,為到達(dá)這點我們可以參考關(guān)系數(shù)據(jù)庫的redo和undo日志的實現(xiàn)來進(jìn)行設(shè)計幢妄,同時需要在業(yè)務(wù)上確定消息的唯一性,我們需要給消息加入唯一標(biāo)識茫负,而保證消息不被重復(fù)投遞蕉鸳,這個跟數(shù)據(jù)庫的主鍵很像。

其他方面

一個隊列的開發(fā)我們可以使用任何語言忍法,如果使用java的話潮尝,我們還可以做其他優(yōu)化榕吼,比如為了避免jvm的垃圾回收機(jī)制導(dǎo)致內(nèi)存頻繁的回收,我們可以使用堆外內(nèi)存設(shè)計內(nèi)存池來加快內(nèi)存的分配和重復(fù)利用衍锚,同時可以利用零拷貝技術(shù)避免內(nèi)存數(shù)據(jù)在用戶態(tài)和內(nèi)核態(tài)重復(fù)的進(jìn)行拷貝來提高性能友题。我們也可以使用自定義協(xié)議或者壓縮技術(shù)來實現(xiàn)數(shù)據(jù)的高效傳輸?shù)取?/p>

總結(jié)

設(shè)計一個高性能和高可用的隊列產(chǎn)品是一個比較有難度和有技術(shù)的活,我們可以利用分布式存儲技術(shù)戴质,分布式協(xié)調(diào)協(xié)議度宦,以及IO多路復(fù)用技術(shù)等來為我們所用,但是從細(xì)節(jié)方面來說告匠,要實現(xiàn)一個生產(chǎn)上可用的合格隊列產(chǎn)品戈抄,需要付出相當(dāng)?shù)呐Σ拍軐崿F(xiàn)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末后专,一起剝皮案震驚了整個濱河市划鸽,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌戚哎,老刑警劉巖裸诽,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異型凳,居然都是意外死亡丈冬,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進(jìn)店門甘畅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來埂蕊,“玉大人,你說我怎么就攤上這事疏唾⌒钛酰” “怎么了?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵槐脏,是天一觀的道長喉童。 經(jīng)常有香客問我,道長准给,這世上最難降的妖魔是什么泄朴? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮露氮,結(jié)果婚禮上祖灰,老公的妹妹穿的比我還像新娘。我一直安慰自己畔规,他們只是感情好局扶,可當(dāng)我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般三妈。 火紅的嫁衣襯著肌膚如雪畜埋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天畴蒲,我揣著相機(jī)與錄音悠鞍,去河邊找鬼。 笑死模燥,一個胖子當(dāng)著我的面吹牛咖祭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蔫骂,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼么翰,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了辽旋?” 一聲冷哼從身側(cè)響起浩嫌,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎补胚,沒想到半個月后码耐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡溶其,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年伐坏,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片握联。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖每瞒,靈堂內(nèi)的尸體忽然破棺而出金闽,到底是詐尸還是另有隱情,我是刑警寧澤剿骨,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布代芜,位于F島的核電站,受9級特大地震影響浓利,放射性物質(zhì)發(fā)生泄漏挤庇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一贷掖、第九天 我趴在偏房一處隱蔽的房頂上張望嫡秕。 院中可真熱鬧,春花似錦苹威、人聲如沸昆咽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽掷酗。三九已至调违,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間泻轰,已是汗流浹背技肩。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留浮声,地道東北人虚婿。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像阿蝶,于是被迫代替她去往敵國和親雳锋。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,834評論 2 345

推薦閱讀更多精彩內(nèi)容