IM技術(shù)分享:萬(wàn)人群聊消息投遞方案的思考和實(shí)踐

本文由融云技術(shù)團(tuán)隊(duì)原創(chuàng)分享,原題“技術(shù)實(shí)踐丨萬(wàn)人群聊的消息分發(fā)控速方案”,為使文章更好理解,內(nèi)容有修訂。
1、引言
傳統(tǒng)意義上的IM群聊,通常都是像微信這樣的500人群,或者QQ的2000人群(QQ有3000人群,但那是單獨(dú)收費(fèi)的,也就意味著它并非無(wú)門(mén)檻標(biāo)配,能用上的人并不多)。
自從國(guó)外某號(hào)稱“世界上最安全的IM”搞出萬(wàn)人群聊之后,萬(wàn)人群迅速被國(guó)內(nèi)的使用者們接受。伴隨著移動(dòng)互聯(lián)網(wǎng)的發(fā)展,即時(shí)通訊服務(wù)被廣泛應(yīng)用于各個(gè)行業(yè)(以經(jīng)不再局限于傳統(tǒng)IM社交應(yīng)用領(lǐng)域),隨著業(yè)務(wù)快速發(fā)展,傳統(tǒng)百人、千人上限的群聊已經(jīng)無(wú)法滿足很多業(yè)務(wù)場(chǎng)景需求,所以萬(wàn)人甚至十萬(wàn)人的超大群也算是相伴而生、順應(yīng)潮流。?

▲ “紙飛機(jī)”的萬(wàn)人群(開(kāi)發(fā)人員顫抖中...)
IM群聊一直是IM應(yīng)用中比較有難度的熱點(diǎn)技術(shù)之一,通常意義的群聊,無(wú)非就是500人群、1000人群、2000人群這樣,技術(shù)實(shí)現(xiàn)上比單聊要復(fù)雜不少。然而對(duì)于萬(wàn)人群聊(甚至十萬(wàn)人群聊)來(lái)說(shuō),相比百人、千人群聊,技術(shù)實(shí)現(xiàn)上那幾乎是另一個(gè)技術(shù)維度的事情,難度要高很多。
本文根據(jù)融云技術(shù)團(tuán)隊(duì)的實(shí)踐經(jīng)驗(yàn),總結(jié)了萬(wàn)人群聊消息投遞方案的一些思考和實(shí)踐,希望能給你帶來(lái)啟發(fā)。
學(xué)習(xí)交流:
- 即時(shí)通訊/推送技術(shù)開(kāi)發(fā)交流5群:215477170?[推薦]
- 移動(dòng)端IM開(kāi)發(fā)入門(mén)文章:《新手入門(mén)一篇就夠:從零開(kāi)發(fā)移動(dòng)端IM》
- 開(kāi)源IM框架源碼:https://github.com/JackJiang2011/MobileIMSDK
(本文同步發(fā)布于:http://www.52im.net/thread-3687-1-1.html)
2、相關(guān)文章
萬(wàn)人群聊有關(guān)的技術(shù)文章還可讀一讀以下這篇:
《網(wǎng)易云信技術(shù)分享:IM中的萬(wàn)人群聊技術(shù)方案實(shí)踐總結(jié)》
《企業(yè)微信的IM架構(gòu)設(shè)計(jì)揭秘:消息模型、萬(wàn)人群、已讀回執(zhí)、消息撤回等》
《阿里釘釘技術(shù)分享:企業(yè)級(jí)IM王者——釘釘在后端架構(gòu)上的過(guò)人之處》
融云技術(shù)團(tuán)隊(duì)分享的其它文章:
《融云技術(shù)分享:融云安卓端IM產(chǎn)品的網(wǎng)絡(luò)鏈路保活技術(shù)實(shí)踐》
《融云技術(shù)分享:全面揭秘億級(jí)IM消息的可靠投遞機(jī)制》
《融云技術(shù)分享:基于WebRTC的實(shí)時(shí)音視頻首幀顯示時(shí)間優(yōu)化實(shí)踐》
《IM消息ID技術(shù)專題(三):解密融云IM產(chǎn)品的聊天消息ID生成策略》
3、超大群面臨的技術(shù)挑戰(zhàn)
與百人群、千人群相比,萬(wàn)人、甚至十萬(wàn)人超大群,大幅提升了群的觸達(dá)人數(shù),對(duì)于很多業(yè)務(wù)場(chǎng)景來(lái)說(shuō),好處不言而喻。
然而單群成員如此之大,給 IM 系統(tǒng)的流量沖擊非常巨大,技術(shù)難度可想而之。我們先來(lái)分析一下超大群的技術(shù)挑戰(zhàn)。
以一個(gè)萬(wàn)人群的模型為例:
1)如果群中有人發(fā)了消息,那么這條消息需要按照 1:9999 的比例進(jìn)行分發(fā)投遞,如果我們按照常規(guī)消息的處理流程,那么消息處理服務(wù)壓力巨大;
2)消息量大的情況下,服務(wù)端向客戶端直推消息的處理速度將會(huì)成為系統(tǒng)瓶頸,而一旦用戶的消息下發(fā)隊(duì)列造成了擠壓,會(huì)影響到正常的消息分發(fā),也會(huì)導(dǎo)致服務(wù)緩存使用量激增;
3)在微服務(wù)架構(gòu)中,服務(wù)以及存儲(chǔ)(DB,緩存)之間的 QPS 和網(wǎng)絡(luò)流量也會(huì)急劇增高;
4)以群為單位的消息緩存,內(nèi)存和存儲(chǔ)開(kāi)銷較大(消息體的存儲(chǔ)被放大了萬(wàn)倍)。
基于這些技術(shù)挑戰(zhàn),要想真正達(dá)成超大群的技術(shù)目標(biāo),勢(shì)必要做特定的技術(shù)優(yōu)化來(lái)應(yīng)對(duì)。
4、一般群聊的消息投遞模型
先來(lái)看看普通群聊的消息投遞模型。
我們的普通群聊消息投遞模型如下圖所示:

如上圖所示,當(dāng)用戶在普通群里發(fā)了一條消息后,投遞路徑是:
1)消息先到群組服務(wù);
2)然后通過(guò)群組服務(wù)緩存的群關(guān)系,鎖定這條消息最終需要分發(fā)的目標(biāo)用戶;
3)再根據(jù)一定的策略分發(fā)到消息服務(wù)上;
4)消息服務(wù)再根據(jù)用戶的在線狀態(tài)和消息狀態(tài)來(lái)判斷這條消息是直推、通知拉取還是轉(zhuǎn) Push,最終投遞給目標(biāo)用戶。
普通群聊的消息投遞,正像您期待的那樣,基本上大家的實(shí)現(xiàn)手段都大差不差。然而對(duì)于萬(wàn)人群來(lái)說(shuō),這顯然還不夠。
下面來(lái)看看我們針對(duì)萬(wàn)人群聊消息投遞的技術(shù)優(yōu)化手段。
5、萬(wàn)人群聊消息投遞優(yōu)化手段1:控速
針對(duì)萬(wàn)人群的消息投遞,我們的一個(gè)主要手段就是控速。

如上圖所示。
首先:我們會(huì)根據(jù)服務(wù)器的核數(shù)來(lái)建立多個(gè)群消息分發(fā)隊(duì)列,這些隊(duì)列我們?cè)O(shè)置了不同的休眠時(shí)間以及不同的消費(fèi)線程數(shù)。
通俗來(lái)講,可以將隊(duì)列這樣劃分為快、中、慢等隊(duì)列。
其次:我們根據(jù)群成員數(shù)量的大小來(lái)將所有群映射到相應(yīng)的隊(duì)列中。
規(guī)則是:
1)小群映射到快隊(duì)列中;
2)大群映射到相應(yīng)的慢隊(duì)列中。
然后:小群由于人數(shù)少,對(duì)服務(wù)的影響很小,所以服務(wù)利用快隊(duì)列快速的將群消息分發(fā)出去,而大群群消息則利用慢隊(duì)列的相對(duì)高延時(shí)來(lái)起到控速的作用。
6、萬(wàn)人群聊消息投遞優(yōu)化手段2:合并
在本文第3節(jié)中提到的萬(wàn)人群聊所面臨的技術(shù)挑戰(zhàn),最主要的挑戰(zhàn)其實(shí)就是消息進(jìn)行擴(kuò)散分發(fā)投遞后,消息被克隆出N條,消息流量瞬間被放大。
舉個(gè)例子:當(dāng)一條群消息發(fā)送到 IM 服務(wù)器后,需要從群組服務(wù)投遞給消息服務(wù),如果每一個(gè)群成員都投遞一次,并且投遞的群消息內(nèi)容是一致的話,那肯定會(huì)造成相應(yīng)的資源浪費(fèi)和服務(wù)壓力。
那么針對(duì)這種情況,我們的解決方案就是進(jìn)行消息合并投遞。
原理就是:服務(wù)落點(diǎn)計(jì)算中我們使用的是一致性哈希,群成員落點(diǎn)相對(duì)固定,所以落點(diǎn)一致的群成員我們可以合并成一次請(qǐng)求進(jìn)行投遞,這樣就大幅提高了投遞效率同時(shí)減少了服務(wù)的壓力。
下圖是云信團(tuán)隊(duì)分享的萬(wàn)人群消息合并投遞邏輯:

▲ 上圖引用自《IM中的萬(wàn)人群聊技術(shù)方案實(shí)踐總結(jié)》
如上圖所示,云信團(tuán)隊(duì)的萬(wàn)人群消息合并投遞方案是:按Link分組路由消息,同一Link上的全部群成員只需要路由一條消息即可。
7、十萬(wàn)、百萬(wàn)級(jí)的超大群處理方案
在實(shí)際群聊業(yè)務(wù)中,還有一種業(yè)務(wù)場(chǎng)景是超大規(guī)模群,這種群的群人數(shù)達(dá)到了數(shù)十萬(wàn)甚至上百萬(wàn)。
這種群如果按照上述的投投遞方案,勢(shì)必仍會(huì)造成消息節(jié)點(diǎn)的巨大壓力。
比如我們有一個(gè)十萬(wàn)人的群,消息節(jié)點(diǎn)五臺(tái),消息服務(wù)處理消息的上限是一秒鐘 4000 條,那每臺(tái)消息節(jié)點(diǎn)大約會(huì)分到 2 萬(wàn)條群消息,這已大大超出了消息節(jié)點(diǎn)的處理能力。
所以為了避免上述問(wèn)題,我們會(huì)將群成員上線超過(guò)3000的群識(shí)別為萬(wàn)人群、超級(jí)群,這種級(jí)別的群可以根據(jù)服務(wù)器數(shù)量和服務(wù)器配置相應(yīng)做調(diào)整針對(duì)這種超級(jí)群會(huì)用特殊的隊(duì)列來(lái)處理群消息的投遞。
這個(gè)特殊的隊(duì)列1秒鐘往后端消息服務(wù)投遞的消息數(shù)是消息服務(wù)處理上限的一半(留相應(yīng)的能力處理其他消息),如果單臺(tái)消息服務(wù)處理的 QPS 上限是 4000,那群組服務(wù)一秒往單臺(tái)消息服務(wù)最多投遞 2000 條。
8、寫(xiě)在最后
未來(lái),我們也會(huì)針對(duì)群消息進(jìn)行引用投遞,對(duì)于大群里發(fā)的消息體比較大的消息,我們給群成員只分發(fā)和緩存消息的索引,比如 MessageID。等群成員真正拉取群消息時(shí)再?gòu)膶⑾⒔M裝好給客戶端分發(fā)下去。這樣做會(huì)節(jié)省分發(fā)的流量以及存儲(chǔ)的空間。
隨著互聯(lián)網(wǎng)的發(fā)展,群組業(yè)務(wù)的模型和壓力也在不停地?cái)U(kuò)展,后續(xù)可能還會(huì)遇到更多的挑戰(zhàn),當(dāng)然也會(huì)不斷迭代出更優(yōu)的處理方式來(lái)應(yīng)對(duì)。
附錄:更多IM群聊技術(shù)文章
《快速裂變:見(jiàn)證微信強(qiáng)大后臺(tái)架構(gòu)從0到1的演進(jìn)歷程(一)》
《如何保證IM實(shí)時(shí)消息的“時(shí)序性”與“一致性”?》
《IM單聊和群聊中的在線狀態(tài)同步應(yīng)該用“推”還是“拉”?》
《IM群聊消息如此復(fù)雜,如何保證不丟不重?》
《微信后臺(tái)團(tuán)隊(duì):微信后臺(tái)異步消息隊(duì)列的優(yōu)化升級(jí)實(shí)踐分享》
《移動(dòng)端IM中大規(guī)模群消息的推送如何保證效率、實(shí)時(shí)性?》
《現(xiàn)代IM系統(tǒng)中聊天消息的同步和存儲(chǔ)方案探討》
《關(guān)于IM即時(shí)通訊群聊消息的亂序問(wèn)題討論》
《IM群聊消息的已讀回執(zhí)功能該怎么實(shí)現(xiàn)?》
《IM群聊消息究竟是存1份(即擴(kuò)散讀)還是存多份(即擴(kuò)散寫(xiě))?》
《一套高可用、易伸縮、高并發(fā)的IM群聊、單聊架構(gòu)方案設(shè)計(jì)實(shí)踐》
《[技術(shù)腦洞] 如果把14億中國(guó)人拉到一個(gè)微信群里技術(shù)上能實(shí)現(xiàn)嗎?》
《IM群聊機(jī)制,除了循環(huán)去發(fā)消息還有什么方式?如何優(yōu)化?》
《網(wǎng)易云信技術(shù)分享:IM中的萬(wàn)人群聊技術(shù)方案實(shí)踐總結(jié)》
《阿里釘釘技術(shù)分享:企業(yè)級(jí)IM王者——釘釘在后端架構(gòu)上的過(guò)人之處》
《IM群聊消息的已讀未讀功能在存儲(chǔ)空間方面的實(shí)現(xiàn)思路探討》
《直播系統(tǒng)聊天技術(shù)(一):百萬(wàn)在線的美拍直播彈幕系統(tǒng)的實(shí)時(shí)推送技術(shù)實(shí)踐之路》
《直播系統(tǒng)聊天技術(shù)(二):阿里電商IM消息平臺(tái),在群聊、直播場(chǎng)景下的技術(shù)實(shí)踐》
《直播系統(tǒng)聊天技術(shù)(三):微信直播聊天室單房間1500萬(wàn)在線的消息架構(gòu)演進(jìn)之路》
《直播系統(tǒng)聊天技術(shù)(四):百度直播的海量用戶實(shí)時(shí)消息系統(tǒng)架構(gòu)演進(jìn)實(shí)踐》
《企業(yè)微信的IM架構(gòu)設(shè)計(jì)揭秘:消息模型、萬(wàn)人群、已讀回執(zhí)、消息撤回等》
《融云IM技術(shù)分享:萬(wàn)人群聊消息投遞方案的思考和實(shí)踐》
>>?更多同類文章 ……
本文已同步發(fā)布于“即時(shí)通訊技術(shù)圈”公眾號(hào)。
同步發(fā)布鏈接是:http://www.52im.net/thread-3687-1-1.html