直播系統(tǒng)聊天技術(shù)(四):百度直播的海量用戶實時消息系統(tǒng)架構(gòu)演進(jìn)實踐
Posted on 2021-04-27 15:17 Jack Jiang 閱讀(209) 評論(0) 編輯 收藏本文原題“百度直播消息服務(wù)架構(gòu)實踐”,由百度APP消息中臺團(tuán)隊原創(chuàng)分享于“百度Geek說”公眾號,為了讓文章內(nèi)容更通俗易懂,本次已做排版優(yōu)化和內(nèi)容重新劃分,原文鏈接在文末。
1、引言
一套完整的直播系統(tǒng)核心功能有兩個:
- 1)實時音視頻的推拉流;
- 2)直播間消息流的收發(fā)(包括聊天消息、彈幕、指令等)。
本文主要分享的是百度直播的消息系統(tǒng)的架構(gòu)設(shè)計實踐和演進(jìn)過程。
實際上:直播間內(nèi)用戶的聊天互動,雖然形式上是常見的IM聊天消息流,但直播消息流不僅僅是用戶聊天。
除用戶聊天外:直播間內(nèi)常見的用戶送禮物、進(jìn)場、點贊、去購買、主播推薦商品、申請連麥等互動行為的實時提醒,也是通過消息流下發(fā)的。
此外:直播間關(guān)閉、直播流切換等特殊場景,也依賴消息流的實時下發(fā)。
所以,直播系統(tǒng)內(nèi)的消息流可以認(rèn)為是直播間內(nèi)主播與用戶間實時互動和直播間實時控制的基礎(chǔ)能力,也是系統(tǒng)支撐。如果說實時音視頻推拉流是直播系統(tǒng)的靈魂,那消息流可以說是直播系統(tǒng)的骨架,它的重要性不言而喻。
那么,如何構(gòu)建直播的消息系統(tǒng),又有哪些挑戰(zhàn)需要解決,借著本文我們一起來梳理一下。
學(xué)習(xí)交流:
- 即時通訊/推送技術(shù)開發(fā)交流5群:215477170 [推薦]
- 移動端IM開發(fā)入門文章:《新手入門一篇就夠:從零開發(fā)移動端IM》
- 開源IM框架源碼:https://github.com/JackJiang2011/MobileIMSDK
(本文同步發(fā)布于:http://www.52im.net/thread-3515-1-1.html)
2、系列文章
本文是系列文章中的第4篇:
《直播系統(tǒng)聊天技術(shù)(一):百萬在線的美拍直播彈幕系統(tǒng)的實時推送技術(shù)實踐之路》
《直播系統(tǒng)聊天技術(shù)(二):阿里電商IM消息平臺,在群聊、直播場景下的技術(shù)實踐》
《直播系統(tǒng)聊天技術(shù)(三):微信直播聊天室單房間1500萬在線的消息架構(gòu)演進(jìn)之路》
《直播系統(tǒng)聊天技術(shù)(四):百度直播的海量用戶實時消息系統(tǒng)架構(gòu)演進(jìn)實踐》(* 本文)
3、與普通IM群聊的區(qū)別
直播間內(nèi)的聊天消息,經(jīng)常被類比于普通的IM群聊功能。
群聊是大家比較熟悉的即時通訊(IM)場景,直播間內(nèi)聊天和群聊,二者有相似性,但也有本質(zhì)的區(qū)別。
對比二者的特點,直播消息與IM群聊主要有以下區(qū)別:
1)參與人數(shù)不同:IM群聊的參與人數(shù)上千人就是很大的群了。但對于高熱度的大型直播場景,例如國慶、閱兵、春晚等,單直播間累計用戶是百萬甚至千萬量級的集合,同時在線人數(shù)可達(dá)數(shù)百萬人。
2)組織關(guān)系不同:IM用戶進(jìn)群退群,是相對低頻的操作,用戶集合相對固定,用戶進(jìn)出的變更頻度不會特別高。而用戶進(jìn)出直播間,是非常頻繁的,高熱度直播的單直播間每秒面臨上萬用戶的進(jìn)出變更。
3)持續(xù)時間不同:IM群聊建立后,聊天持續(xù)時間可能比較長,幾天到數(shù)月都有。而直播間大部分持續(xù)不超過幾個小時。
4、核心技術(shù)挑戰(zhàn)
根據(jù)上節(jié)中,直播消息和IM通聊的類比分析,針對直播中的消息系統(tǒng),我們可以提煉出兩個核心技術(shù)挑戰(zhàn)。
挑戰(zhàn)一:直播間內(nèi)用戶的維護(hù)
- 1)單直播間每秒上萬用戶的進(jìn)出變更(實際進(jìn)入直播間峰值不超過2萬QPS,退出也不超過2萬QPS);
- 2)單直播間同時數(shù)百萬用戶在線;
- 3)單直播間累計用戶達(dá)千萬量級。
支持在線百萬、累積千萬兩個集合,每秒4萬QPS更新,有一定壓力,但有支持高讀寫性能的存儲應(yīng)該可以解決,例如redis。
挑戰(zhàn)二:百萬在線用戶的消息下發(fā)
面對百萬在線用戶,上下行都有大量的消息,從直播用戶端視角分析:
- 1)消息的實時性:如果消息服務(wù)端做簡單消峰處理,峰值消息的堆積,會造成整體消息延時增大,且延時可能產(chǎn)生很大的累積效應(yīng),消息與直播視頻流在時間線上產(chǎn)生很大的偏差,影響用戶觀看直播時互動的實時性;
- 2)端體驗和性能:端展示各類用戶聊天和系統(tǒng)消息,一般一屏不超過10-20條。如果每秒有超過20條的消息下發(fā),端上展示的消息基本會持續(xù)刷屏。再考慮到有禮物消息的特效等,大量的消息,對端的處理和展示,帶來持續(xù)高負(fù)荷。所以,對于一個長時間觀看直播的用戶端來說,如果出現(xiàn)持續(xù)的大量消息,端的消息消費會有顯著的性能壓力,且過多消息會有累積效應(yīng)。
由于技術(shù)挑戰(zhàn)一不難解決,以下內(nèi)容主要討論技術(shù)挑戰(zhàn)二。
5、技術(shù)設(shè)計目標(biāo)
綜合考慮上節(jié)的技術(shù)挑戰(zhàn)和直播業(yè)務(wù)場景,我們對于消息系統(tǒng)的需求目標(biāo)有比較明顯的指標(biāo)定義。
技術(shù)設(shè)計目標(biāo)定義大致如下:
- 1)實時性方面:端和端的消息要達(dá)到秒級;
- 2)性能方面:消息服務(wù)能支持同一直播間內(nèi)百萬以上用戶同時在線下發(fā);
- 3)峰值處理:對于峰值時的過多消息,丟棄是合理適當(dāng)?shù)奶幚矸绞剑?/li>
- 4)基于合理的端用戶體驗,單直播間內(nèi)每秒消息數(shù)假設(shè)不超過N條。
現(xiàn)在:問題的核心是,如何做到把不超過N條的消息,在S秒內(nèi),下發(fā)到直播間內(nèi)的百萬用戶(假設(shè) N<=20,S<=2)。
6、從普通IM群聊的技術(shù)實現(xiàn)上找靈感
6.1 普通IM群聊消息收發(fā)分析
IM群聊數(shù)據(jù)流及壓力點:

如上圖所示,首先具體分析一下普通群聊的消息收發(fā)流程:
- 1)對于群group-1,分配一個群公共消息信箱group-mbox-1;
- 2)群group-1內(nèi)的用戶user-1,由手機端APP-1上發(fā)出消息msg-1;
- 3)服務(wù)端接收到消息msg-1,檢查user-1是否有權(quán)限,如有權(quán)限,將msg-1存儲到群信箱group-mbox-1,生成相應(yīng)msgID-1;
- 4)服務(wù)端查詢group-1對應(yīng)的用戶列表groupUserList-1;
- 5)基于groupUserList-1拆分出所有獨立群用戶:user-1、user-2 ... user-n;
- 6)對于每一個用戶user-i來說,需要查詢用戶user-i的所在設(shè)備device-i-1、device-i-2、device-i-m(因為一個賬號可能登錄多個設(shè)備);
- 7)對于每個設(shè)備device-i-j來說,長連接通道都會建立一個獨立的長連接connect-j以服務(wù)于該設(shè)備;但由于connect-j是由端上APP-1連接到長連接服務(wù)的,具有動態(tài)性,所以,查詢device-i-j與connect-j的對應(yīng)關(guān)系時,需要依賴一個路由服務(wù)route來完成查詢;
- 8)在查得connect-j后,可以通過connect-j下發(fā)msg-1的通知groupmsg-notify-1;
- 9)如果用戶user-i正在使用device-i-j的手機端APP-1,用戶user-i就可以立即從長連接connect-j上收到msg-1的通知groupmsg-notify-1;
- 10)在接收到groupmsg-notify-1后,手機端APP-1中的消息SDK根據(jù)端本地歷史消息記錄的最后一條消息latestMsg對應(yīng)的消息ID即latestMsgID,來向服務(wù)端發(fā)起拉消息請求fetchMsg,拉取group-1中從latestMsgID+1到最新的所有消息;
- 11)服務(wù)端收到拉消息請求fetchMsg后,從group-mbox-1中取出latestMsgID+1到最新的所有消息,返回給端;如果消息過多,可能需要端分頁拉取;
- 12)端APP-1拉取到group-1中從latestMsgID+1到最新的所有消息,可以做展示;在用戶在會話中閱讀后,需要設(shè)置所有新消息的已讀狀態(tài)或者會話已讀狀態(tài)。
6.2 普通IM群聊主要壓力
如果完全重用普通群聊消息的下發(fā)通知到端拉取的全過程,對于user-1發(fā)的一條消息msg-1,如果需要支持一個實時百萬量級的群消息,大概有以下幾個每秒百萬量級的挑戰(zhàn)。
首先:秒級拆分出用戶列表groupUserList-1,需要秒級讀出百萬的用戶列表數(shù)據(jù),對于存儲和服務(wù)是第一個百萬級挑戰(zhàn)。
第二:對于拆分出群中的所有獨立用戶user-i,需要秒級查詢出百萬量級的device-i-j,對于存儲和服務(wù)是第二個百萬級挑戰(zhàn)。
第三:對于所有device-i-j,通過動態(tài)路由服務(wù)route,需要秒級查詢出百萬量級的connect-j,對于存儲和服務(wù)是第三個百萬級挑戰(zhàn)。
第四:對于通過長連接connect-j下發(fā)時,需要支持秒級下發(fā)百萬量級的群消息通知groupmsg-notify-1到對應(yīng)的connect-j上,對于長連接服務(wù)是個百萬級的挑戰(zhàn)。
第五:對于收到消息通知的所有端APP-1,需要支持百萬QPS端從服務(wù)端拉取消息請求fetchMsg,對于消息信箱服務(wù),這是也是一個百萬量級的挑戰(zhàn);考慮到實際各端latestMsgID可能不同,可能的優(yōu)化方式會更復(fù)雜一些,帶來的性能影響會更大。
第六:如果在絕大多數(shù)用戶是在線聊天的場景,設(shè)置已讀狀態(tài)也會有百萬量級QPS對服務(wù)端的壓力。
顯然:完全重用群聊的消息流程,對消息服務(wù)和長連接服務(wù)帶來的壓力是巨大的。
6.3 普通IM群聊優(yōu)化方案
IM群聊數(shù)據(jù)流優(yōu)化后的壓力點:

如上圖所示,現(xiàn)在我們來分析以上每個百萬量級的挑戰(zhàn),是否有優(yōu)化的空間:
- 1)對于①拆分用戶列表和②查詢用戶對應(yīng)設(shè)備,如果存儲上將二者合并集中起來,也就是優(yōu)化直播間內(nèi)用戶列表的存儲,擴展設(shè)備信息,可以減少一次user->device的百萬QPS查詢,可以優(yōu)化;
- 2)對于④下行通知和⑤端拉取fetchMsg的可靠消息拉取模式,考慮到直播消息允許部分折損丟棄,可以只做單向消息下發(fā),而不做拉取,對于大部分連接保持在線的用戶,也是可以接受的。所以可以優(yōu)化,只保留下行通知(包含消息體),而舍棄端拉取;
- 3)對于⑥消息設(shè)置已讀,直播場景下可以考慮簡化舍棄。
如上優(yōu)化后,減少了②⑤⑥三個百萬量級壓力請求,但還有①拆分用戶列表③動態(tài)路由查詢④長連接下發(fā),這三個百萬量級步驟需要處理。
對于①拆分用戶列表:支持百萬量級用戶列表查詢,比較常規(guī)的思路是支持基于群groupID的批量查詢,例如一次可以查出100個用戶,1萬QPS查詢就可以支持到百萬;基于群groupID把用戶數(shù)據(jù)的存儲,分散到多個主從實例和分片上,控制好打散粒度不出現(xiàn)熱點,基本能做到,只是存儲資源可能消耗較多。
對于③動態(tài)路由查詢:表面上看,面臨的問題與①類似,但卻有些不同。因為群的用戶列表,是基于群groupID做key,建立一個表或多個打散的表;而device-i-j的查詢是完全分散的,也是需要批量查詢能力,但是完全分散的設(shè)備信息查詢,不能只針對特定key做優(yōu)化,需要動態(tài)路由服務(wù)支持整體上達(dá)到百萬QPS的查詢性能。
對于④長連接服務(wù)下發(fā):由于長連接服務(wù)不依賴外部的存儲服務(wù),如果整體要支持百萬量級的下發(fā)能力,若長連接單實例能支持1萬的下發(fā)能力,整體上100個實例就能支持到百萬量級下發(fā)。
基于以上分析:支持百萬量級的消息下發(fā),初見曙光。似乎只要優(yōu)化好用戶列表、動態(tài)路由的存儲/查詢和長連接的容量擴容,但所有的前提是需要消耗大量存儲和機器資源。
考慮到直播業(yè)務(wù)的實際情況,現(xiàn)實不容樂觀:
- 1)一方面,平時沒有熱點直播時,可能單場直播并發(fā)在線用戶數(shù)峰值不超過1萬人,甚至不到1000;在業(yè)務(wù)初期,整體直播在線用戶峰值可能也不超過10萬。這就意味著,為了支持百萬量級的峰值,資源整體上有幾十倍的冗余;
- 2)另一方面,如果突然來了一場熱度非常高的直播,可能需要支持的不只是100萬量級消息下發(fā),可能是500萬以上的量級(例如國慶閱兵、春晚等)。這樣的話,每次大型直播得提前預(yù)估可能的在線用戶峰值,如果超過當(dāng)前設(shè)計容量,需要對①用戶列表③動態(tài)路由查詢④長連接服務(wù),分別擴容和壓測;或者在可接受的情況下,做服務(wù)降級或拒絕服務(wù)。
而實際上:在線用戶峰值量級很難估計準(zhǔn)確,這樣會造成實際資源利用率很低,擴縮容的操作頻繁,運維成本高。是否選擇這個方案,也是很令人糾結(jié)。
6.4 普通群聊多群組方案
也有人提過拆分多個群組的方案。
例如:如果一個群組最多支持1萬用戶,開100個群就可以支持一百萬用戶;再建立一個虛擬群,將這100個群關(guān)聯(lián)起來,似乎可行。
但如果仔細(xì)分析,會發(fā)現(xiàn)以上提到的幾個問題:“①拆分用戶列表、③動態(tài)路由查詢、④長連接下發(fā)”,高壓力依然存在,還是不可避免。
除此之外,多群組還會引入其他問題:
- 1)問題一:多群組消息不同步。如果兩個用戶在一起看直播,而所屬群不同,看到的消息會完全不同;
- 2)問題二:直播場景用戶是動態(tài)進(jìn)出的,也就是說群組成員非常不穩(wěn)定,在線用戶峰值波動也比較大。如果是根據(jù)在線人數(shù)增長,動態(tài)新開群組,可能第一個群用戶已經(jīng)很多了,第二個群剛開始用戶比較少;或者,在峰值期間開了比較多的群,隨著熱度降低用戶離開,用戶變得分散,一些群的用戶可能較稀少,聊天互動較少,這時需要縮容合并群。如何平衡多個群的用戶,達(dá)到好的業(yè)務(wù)效果,也是比較難做的。
基于以上分析,我們并沒有選擇多群組方案。
7、基于組播mcast方案的消息架構(gòu)實踐
經(jīng)過上節(jié)中類比普通IM群聊消息的架構(gòu)設(shè)計,本節(jié)將介紹我們支持實時高并發(fā)百萬量級同時在線用戶的直播消息架構(gòu)——組播mcast方案的提出及演化。
7.1 跳出原有框架思考
是否要采用上節(jié)基于IM群聊的優(yōu)化方案,還是可以另辟蹊徑?
先暫時拋開群收發(fā)消息流程:對于消息下發(fā)來說,如果一定要說一個步驟是必不可少的,那一定是長連接下發(fā)這步了。沒有通過長連接下發(fā),消息就無法最終到達(dá)用戶。
當(dāng)然有人說輪詢拉取也可以替代長連接下發(fā),來獲取消息,但顯然輪詢拉取的性能壓力和實時性與長連接下發(fā)相比差很多,故不在討論范圍。
如果能簡化為:給長連接服務(wù)下發(fā)消息時指定一個類似的groupID,長連接服務(wù)能直接拆分到所有群組用戶相關(guān)的長連接connect-j,就可以省略掉用戶列表拆分和動態(tài)路由查詢的百萬量級查詢。
這樣的話:消息下發(fā)的壓力將主要由長連接服務(wù)來承受,服務(wù)端也不需要對多個系統(tǒng)擴容,直播消息的優(yōu)化可能會大為簡化。
根據(jù)這個思路:相當(dāng)于在長連接服務(wù)中,對連接connect也建立群組的概念。基于連接組的設(shè)想,我們設(shè)計了一套長連接的組播mcast機制。
7.2 長連接組播mcast基本概念
基本概念總結(jié)如下:
- 1)每個長連接組播mcast有全局唯一的標(biāo)識mcastID;
- 2)長連接組播mcast支持創(chuàng)建、刪除、修改、查詢等管理操作;
- 3)長連接組播mcast是若干長連接在線用戶的連接connect的集合;
- 4)一個用戶user-i在設(shè)備device-i-j上,對于特定應(yīng)用APP-k來說,建立唯一的一個長連接connect-j-k(此處暫時不區(qū)別登錄用戶和非登錄用戶);
- 5)長連接組播mcast與組內(nèi)長連接connect-j-k的關(guān)系維護(hù),不需要額外的獨立存儲,是維護(hù)在每個長連接服務(wù)的實例上。
7.3 長連接組播mcast的路由概念
組播mcast-m的路由route-m,是一個長連接服務(wù)實例的集合LcsList,記錄了所有加入mcast-m的長連接connect-i所在長連接服務(wù)實例lcs-j。
7.4 長連接組播mcast路由的記錄維護(hù)
加入組播mcast的邏輯流程:
- 1)客戶端調(diào)用消息sdk加入mcast-m;
- 2)消息sdk通過長連接,發(fā)出上行請求mcastJoin(mcast-m);
- 3)業(yè)務(wù)層收到來自長連接實例lcs-i上的連接connect-i的mcastJoin請求,校驗mcast-m的合法性;
- 4)業(yè)務(wù)層請求路由層建立基于組播mcast-m的組播路由mcastRoute-m,將長連接實例lcs-i加入組播路由mcastRoute-m中;
- 5)業(yè)務(wù)層請求長連接服務(wù)層,請求mcastJoin所在長連接實例lcs-i,將請求所在連接connect-i加入到mcastConnectList-m中。
離開組播mcast,與加入組播mcast基本類似,由客戶端調(diào)用消息sdk離開mcast-m,發(fā)出上行請求mcastLeave(mcast-m),長連接服務(wù)端更新路由和mcastConnectList-m信息。
7.5 組播mcast消息推送
組播mcast數(shù)據(jù)流及壓力點:

基于組播mcast的長連接消息推送過程,是一個 1:M * 1:N 的擴散放大過程。
具體過程描述如下:
- 1)一條消息msg-1推送,目的地是ID為mcast-m組播;
- 2)后端業(yè)務(wù)模塊根據(jù)目的mcast-m,做一致性hash選擇出mcast路由分發(fā)模塊實例mcastRouter- i,發(fā)送msg-1到mcastRouter-i;
- 3)mcast分發(fā)路由模塊實例mcastRouter-i,根據(jù)mcast-m的組播路由mcastRoute-m,查找所對應(yīng)的接入實例路由記錄列表mcastLcsList-m,拆分出mcast-m所有的長連接接入實例lcs-1..lcs-M,分別并發(fā)發(fā)送msg-1到長連接實例上;
- 4)一個長連接服務(wù)實例lcs-j,收到消息msg-1推送后,根據(jù)組播mcast-m查找組播連接列表mcastConnectList-m,查出mcast-m內(nèi)所有的連接connect-m-1..connect-m-N,并發(fā)推送msg-1到消息客戶端sdk-m-1..sdk-m-N;
- 5)消息客戶端sdk-m-o收到msg-1后,遞交給上層業(yè)務(wù)(例如直播sdk)。
7.6 組播mcast機制的性能評估
現(xiàn)在分析一下以上的組播mcast機制的性能壓力:
- 1)組播mcast的路由維護(hù),主要壓力在于mcastJoin和mcastLeave,而Join的量級峰值請求很難超過2萬qps;訪問壓力比百萬低兩個數(shù)量級;
- 2)組播mcast的消息推送流程,在一級路由mcastRoute拆分到長連接實例時,一般在幾十到百量級,成本很低;
- 3)組播mcast在長連接單實例內(nèi)的消息推送,是單進(jìn)程內(nèi)的多連接并發(fā)發(fā)送,經(jīng)優(yōu)化后線上實測,在單實例保持25W長連接的情況下,單實例壓測可達(dá)8Wqps的mcast穩(wěn)定下發(fā),保守按5Wqps容量評估;多個長連接實例間,是完全的并發(fā),可以較容易的水平擴容。
綜上可知:對于100Wqps的下發(fā),20個長連接實例就可以完全負(fù)荷(20*5W=100W),且有一定裕量。如果500Wqps的下發(fā),也不超過100實例;1000W的下發(fā),如果以8W單實例較大的負(fù)荷承載,125實例就可以支持。

看上去,基于以上組播mcast機制,我們建立了一套高效的支持百萬量級QPS的長連接下發(fā)機制,當(dāng)前長連接服務(wù)的容量就可以支持,基本不用擴容。但是否能完全滿足直播業(yè)務(wù)場景需求,還需要進(jìn)一步討論。
7.7 消息峰值問題
對于每秒1條消息,擴散到100W用戶,甚至500W用戶,以上組播mcast機制似乎都能應(yīng)對。
但直播間內(nèi)消息的實際情況是:熱門的直播每秒用戶上行聊天消息會有很多,除聊天消息外,直播間還有人數(shù)、進(jìn)場、點贊、分享等定期和不定期發(fā)送的很多種類系統(tǒng)消息。
如果假設(shè)每秒峰值有100條各類消息:100W*100=1億,簡單按單實例5Wqps算,需要2000個實例才能支持,雖然比老的群聊系統(tǒng)應(yīng)該好很多,但系統(tǒng)還是遇到大量資源冗余或應(yīng)對峰值需要大量擴容的老問題。是否能有更好的解決方式?
這里我們考慮常見的一個優(yōu)化思路,是通過批量聚合的模式來提高系統(tǒng)性能。
如果將這100條消息每秒聚合打包一次來統(tǒng)一下發(fā),QPS還是100W,長連接系統(tǒng)的下發(fā)QPS不變,但每秒下發(fā)消息量級可以達(dá)到1億,這個聚合方案實測是可行的。
聚合模式,我們付出的成本是消息時延的上升,1秒的聚合平均時延增加500ms,用戶體驗損失不算大,但系統(tǒng)下發(fā)消息量級可以提升百倍,綜合評估成本收益來看是合理的。考慮到直播的實際場景,大多數(shù)場景下秒級的聚合和時延是可以接受的。
7.8 消息帶寬問題
如上節(jié)所分析的,聚合延時下發(fā),長連接單實例QPS問題解決了,隨之而來的是,長連接單實例下發(fā)的帶寬壓力問題。
例如:長連接單實例需要下發(fā)10000長連接時,每秒100消息,消息平均2K字節(jié),實際帶寬為2K*100*10000*8=15625Mbps,這已經(jīng)超過單物理機的萬兆網(wǎng)卡的帶寬容量。
另一方面:從全局帶寬來看,也高達(dá)1.5Tbps,帶寬資源對于機房出口也會帶來壓力,這樣的帶寬成本過高,需要削減帶寬使用或有更好的替代方案。
面對下發(fā)數(shù)據(jù)量帶寬消耗過大的問題,在不改動業(yè)務(wù)數(shù)據(jù)的前提下,我們采用了數(shù)據(jù)壓縮的解決方案。
而壓縮是CPU密集型的操作,由于直播業(yè)務(wù)的實時性,不能簡單考慮壓縮比,在綜合平衡壓縮比、壓縮時延和壓縮CPU消耗后,調(diào)優(yōu)壓縮庫后實測的平均壓縮比達(dá)到6.7 : 1,數(shù)據(jù)量壓縮到原來的15%左右,這樣15625Mbps*15%=2344Mbps=2.29Gbps。單機萬兆網(wǎng)卡的帶寬容量,最多承載4.27萬的長連接下發(fā),雖然沒有達(dá)到5萬,基本也可以接受。
從全局帶寬來看,峰值也削減到不超過230Gbps,收益很明顯。

7.9 客戶端性能問題
進(jìn)一步考慮,直播場景下,不僅是有較高的峰值消息量級,而是在直播過程中有持續(xù)的高消息量級壓力。這不僅對于服務(wù)端是壓力,對于客戶端來說也是個挑戰(zhàn)。
持續(xù)的高消息量級:
- 1)一方面客戶端在接收、展示等方面有明顯的壓力;
- 2)另一方面直播界面上過多過快的消息刷新,對于用戶體驗也是有害無益的。
所以:在綜合平衡用戶體驗和客戶端性能的基礎(chǔ)上,消息服務(wù)端增加了結(jié)合消息優(yōu)先級的分級頻控限速機制,單用戶客戶端并不需要承受每秒100條的壓力,削減每秒下發(fā)消息后,長連接單實例每秒下發(fā)5-8萬長連接,CPU和帶寬都是可以穩(wěn)定支持的。
7.10 實時消息問題
我們提供了基于消息優(yōu)先級的實時下發(fā)機制:
- 1)對于高優(yōu)消息可以立即觸發(fā)聚合下發(fā),不會增加聚合延時;
- 2)而對于普通中低優(yōu)消息,還是做延時聚合下發(fā)。
7.11 用戶在線問題
組播mcast機制的出發(fā)點,在百萬量級高并發(fā)在線的場景下,保障在線用戶的消息到達(dá),允許不在線用戶接收消息的部分折損,付出合理的技術(shù)復(fù)雜度和成本,取得服務(wù)質(zhì)量和性能平衡。
而針對在線用戶的消息到達(dá),還有個關(guān)鍵問題是如何保障用戶的長連接在線。
為了提升長連接服務(wù)的接入穩(wěn)定性和可達(dá)性,我們在以下幾個方面做了優(yōu)化。
1)訪問點:
長連接服務(wù)在國內(nèi)三大運營商的華北華東華南區(qū)域均部署了接入點入口。針對有部分國外用戶的直播場景,還增加了香港機房的獨立接入點入口。
2)HTTPDNS:
針對部分用戶的DNS劫持問題和解析錯誤問題,消息SDK接入了HTTPDNS服務(wù)并優(yōu)化本地緩存,形成多級域名解析保障體系,提升了域名解析的可靠性,減少了DNS劫持和錯誤率(見《百度APP移動端網(wǎng)絡(luò)深度優(yōu)化實踐分享(一):DNS優(yōu)化篇》)。
3)心跳優(yōu)化:
長連接的心跳是保活探活的重要手段,針對直播場景實時性高的特點,為了盡快發(fā)現(xiàn)長連接斷鏈,在組播mcastJoin后,長連接心跳也調(diào)整為間隔更短、服務(wù)端動態(tài)可控的智能心跳。
這樣在及時發(fā)現(xiàn)連接異常后,消息SDK可以快速主動重新建連。
4)斷鏈恢復(fù):
在直播間用戶已加入組播mcast的情況下,如果長連接斷鏈,長連接服務(wù)端會主動或被動的觸發(fā)清除組播mcast成員。
而長連接重建連恢復(fù)時,直播業(yè)務(wù)層也需要監(jiān)聽連接恢復(fù)信號,重新加入組播mcast,以恢復(fù)組播mcast的消息通路。
7.12 小結(jié)一下
綜上所述,組播mcast機制:
- 1)有效的解決了百萬量級同時在線用戶的消息實時下發(fā)問題;
- 2)對于短時斷鏈和消息過多,允許部分消息的丟棄;
- 3)滿足了直播場景消息的設(shè)計目標(biāo)。
組播mcast機制特點是:
- 1)消息服務(wù)和路由層壓力較輕,整體壓力只由長連接層承載,易于水平擴容;
- 2)基于延時聚合下發(fā),輔以壓縮限速,可以很好的解決下行QPS與帶寬的性能問題;
- 3)系統(tǒng)整體下行的QPS和帶寬是完全可控的。100W在線用戶的下行最大QPS是100W,500W在線用戶的下行最大QPS是500W。單實例的下發(fā)能力5-8萬QPS是穩(wěn)定的。因此,可以很容易判斷整體的系統(tǒng)容量,特殊場景是否需要擴容;
- 4)mcast機制雖然是針對直播場景提出的,但本身設(shè)計具有通用性,可以應(yīng)用于其他需要實時在線大量用戶分組的消息推送場景。
8、基于組播mcast方案消息架構(gòu)的進(jìn)一步拓展
在組播mcast機制解決了百萬量級的在線用戶實時消息下發(fā)后,直播消息的場景不斷擴大,不斷有直播創(chuàng)新業(yè)務(wù)提出新的消息需求。
相應(yīng)的,組播mcast的服務(wù)機制也需要與時俱進(jìn),不斷在深度和廣度上拓展優(yōu)化。以下重點介紹一下歷史消息和禮物消息。
8.1 直播間歷史消息的支持
對于剛進(jìn)入直播間的用戶來說,需要看到一些最近的聊天記錄,以增強聊天互動氛圍并幫助了解直播的進(jìn)展;對歷史聊天記錄感興趣額用戶,還可以追溯更多的消息歷史。這就產(chǎn)生了聊天歷史的需求。
為了支持這類歷史消息的需求,拓展方案是對于每個組播mcast申請開通一個組播公共消息信箱mcast-mbox服務(wù)。
邏輯是這樣的:
- 1)對于用戶消息和其他有持久化需要的消息,全部寫入這個消息信箱;
- 2)用戶可以指定組播mcastID,按時間區(qū)間和要拉取得消息條數(shù),來獲取組播mcast的歷史消息。
下面補充說明一下消息信息的概念和應(yīng)用。
什么是消息信箱服務(wù)的概念?
- 1)消息信箱內(nèi)的一條消息msg,有唯一的消息標(biāo)識符msgID;
- 2)一條消息msg,還包括有發(fā)送方信息、接收方信息、消息類型、消息內(nèi)容等字段,此處可以暫時忽略;
- 3)每條消息可以設(shè)置過期時間,消息過期后不能訪問到;
- 4)每條消息可以設(shè)置已讀狀態(tài);
- 5)一個消息信箱mbox,有唯一的信箱標(biāo)識符mboxID;
- 6)一個消息信箱mbox是一個容器,存儲有序的消息列表msgList;消息列表msgList按msgID排序的;
- 7)消息信箱服務(wù),對指定信箱mbox支持單條消息或批量消息的寫入;
- 8)消息信箱服務(wù),對指定信箱mbox支持基于msgID的單條消息或批量消息的查找;
- 9)消息信箱服務(wù),對指定信息mbox支持從msgID-begin到msgID-end的范圍查找。
實際上,最常用的就是基于msgid范圍的消息拉取。這里的消息信箱服務(wù)是時間線timeline模型,有興趣的同學(xué)可以進(jìn)一步參考時間線timeline模型的相關(guān)信息(見《現(xiàn)代IM系統(tǒng)中聊天消息的同步和存儲方案探討》一文中的“4、Timeline模型”一節(jié))。
8.2 直播間禮物消息的支持
禮物消息:

禮物消息場景分析:
- 1)用戶送禮給主播,主播側(cè)需要盡快、可靠地收到禮物消息通知,才能及時的給予用戶反饋;
- 2)送出禮物的用戶,本地就可及時展示禮物效果,無消息通知強訴求;
- 3)直播間內(nèi)其他用戶,需要收到禮物消息,以展示禮物效果,提升直播間互動氛圍,激發(fā)其他用戶送禮;
- 4)禮物消息涉及用戶訂單和購買行為,需要由服務(wù)端確認(rèn)發(fā)出;
- 5)禮物消息優(yōu)先級明顯高于其他聊天消息、系統(tǒng)消息。
基于以上分析,直播消息提出以下技術(shù)拓展方案:
- 1)增加一個獨立的可靠消息組播mcast通道(如圖4中組播mcast-2),專供高優(yōu)可靠消息的收發(fā);與其他普通消息、系統(tǒng)消息在數(shù)據(jù)流層面隔離,減少相互干擾;
- 2)對于普通用戶側(cè)的端消息SDK,禮物消息組播mcast通道雖然是新增獨立通道,消息收發(fā)邏輯與普通消息組播mcast通道保持一致;
- 3)對于主播側(cè),端消息SDK對于禮物消息組播mcast通道,需要支持推拉結(jié)合模式,以保障禮物消息的全部到達(dá);即使有短暫的掉線,也需要取到全部禮物消息;
- 4)對于主播側(cè),在極端情況下,如果長連接建連有異常,消息SDK可以通過短連接接口輪詢,來拉取禮物組播mcast信箱消息來兜底。
基于以上獨立的可靠消息組播mcast通道方案,在未剔除一些異常場景的情況下,如主播下線未關(guān)播、數(shù)據(jù)偶發(fā)打點丟失等,禮物消息的觸達(dá)率已達(dá)到99.9%以上。
8.3 直播消息其他方面的發(fā)展
在百度直播的發(fā)展歷程中,直播消息服務(wù)還面臨著許多其他基礎(chǔ)性問題和創(chuàng)新業(yè)務(wù)帶來的其他挑戰(zhàn)。
現(xiàn)在這些問題都有了較好的解決方案,以下列舉一些,供大家學(xué)習(xí)參考:
- 1)如何支持多種客戶端場景,安卓、iOS、H5、小程序、PC;
- 2)如何支持同一場直播的消息在百度APP和好看、全民、貼吧等矩陣APP的打通;
- 3)如何支持非登錄用戶:IM一般是支持登錄用戶,而直播場景也需要支持非登錄用戶;
- 4)長連接服務(wù)如果出了嚴(yán)重問題,是否有端獲取消息的降級通道;
- 5)直播消息審核的機審人審如何做,如何支持先發(fā)后審和先審后發(fā);
- 6)如何支持跨多個直播間的消息;
- 7)直播消息服務(wù)是如何支持創(chuàng)新業(yè)務(wù)的,如答題直播、直播帶貨、直播連麥等。
限于篇幅,以上問題在此不再做具體討論,有興趣同學(xué)歡迎探討。
9、回顧和展望
自百度直播上線以來幾年間,直播消息服務(wù)迎難而上,一路披荊斬棘為百度直播保駕護(hù)航,為百度直播提供了堅實的技術(shù)支撐和保障。
未來,在支持直播創(chuàng)新業(yè)務(wù)、更細(xì)粒度的消息分級服務(wù)、直播消息基礎(chǔ)服務(wù)的穩(wěn)定性和性能等方面,直播消息服務(wù)會繼續(xù)努力,夯實基礎(chǔ),持續(xù)創(chuàng)新,以支持直播業(yè)務(wù)更好更快的發(fā)展。
附錄:更多相關(guān)文章
[1] IM群聊方面的文章:
《快速裂變:見證微信強大后臺架構(gòu)從0到1的演進(jìn)歷程(一)》
《IM單聊和群聊中的在線狀態(tài)同步應(yīng)該用“推”還是“拉”?》
《微信后臺團(tuán)隊:微信后臺異步消息隊列的優(yōu)化升級實踐分享》
《移動端IM中大規(guī)模群消息的推送如何保證效率、實時性?》
《現(xiàn)代IM系統(tǒng)中聊天消息的同步和存儲方案探討》
《IM群聊消息的已讀回執(zhí)功能該怎么實現(xiàn)?》
《IM群聊消息究竟是存1份(即擴散讀)還是存多份(即擴散寫)?》
《一套高可用、易伸縮、高并發(fā)的IM群聊、單聊架構(gòu)方案設(shè)計實踐》
《[技術(shù)腦洞] 如果把14億中國人拉到一個微信群里技術(shù)上能實現(xiàn)嗎?》
《IM群聊機制,除了循環(huán)去發(fā)消息還有什么方式?如何優(yōu)化?》
《網(wǎng)易云信技術(shù)分享:IM中的萬人群聊技術(shù)方案實踐總結(jié)》
《阿里釘釘技術(shù)分享:企業(yè)級IM王者——釘釘在后端架構(gòu)上的過人之處》
《IM群聊消息的已讀未讀功能在存儲空間方面的實現(xiàn)思路探討》
>> 更多同類文章 ……
[2] 更多直播技術(shù)的文章:
《移動端實時音視頻直播技術(shù)詳解(四):編碼和封裝》
《移動端實時音視頻直播技術(shù)詳解(五):推流和傳輸》
《移動端實時音視頻直播技術(shù)詳解(六):延遲優(yōu)化》
《理論聯(lián)系實際:實現(xiàn)一個簡單地基于html]5的實時視頻直播》
《實時視頻直播客戶端技術(shù)盤點:Native、html]5、WebRTC、微信小程序》
《Android直播入門實踐:動手搭建一套簡單的直播系統(tǒng)》
《淘寶直播技術(shù)干貨:高清、低延時的實時視頻直播技術(shù)解密》
《技術(shù)干貨:實時視頻直播首屏耗時400ms內(nèi)的優(yōu)化實踐》
《新浪微博技術(shù)分享:微博實時直播答題的百萬高并發(fā)架構(gòu)實踐》
《實時音頻的混音在視頻直播中的技術(shù)原理和實踐總結(jié)》
《七牛云技術(shù)分享:使用QUIC協(xié)議實現(xiàn)實時視頻直播0卡頓!》
《近期大熱的實時直播答題系統(tǒng)的實現(xiàn)思路與技術(shù)難點分享》
《網(wǎng)易云信實時視頻直播在TCP數(shù)據(jù)傳輸層的一些優(yōu)化思路》
《首次披露:快手是如何做到百萬觀眾同場看直播仍能秒開且不卡頓的?》
《淺談實時音視頻直播中直接影響用戶體驗的幾項關(guān)鍵技術(shù)指標(biāo)》
《技術(shù)揭秘:支持百萬級粉絲互動的Facebook實時視頻直播》
《移動端實時視頻直播技術(shù)實踐:如何做到實時秒開、流暢不卡》
《實現(xiàn)延遲低于500毫秒的1080P實時音視頻直播的實踐分享》
《海量實時消息的視頻直播系統(tǒng)架構(gòu)演進(jìn)之路(視頻+PPT)[附件下載]》
《YY直播在移動弱網(wǎng)環(huán)境下的深度優(yōu)化實踐分享(視頻+PPT)[附件下載]》
《從0到1:萬人在線的實時音視頻直播技術(shù)實踐分享(視頻+PPT) [附件下載]》
《在線音視頻直播室服務(wù)端架構(gòu)最佳實踐(視頻+PPT) [附件下載]》
>> 更多同類文章 ……
本文已同步發(fā)布于“即時通訊技術(shù)圈”公眾號。
▲ 本文在公眾號上的鏈接是:點此進(jìn)入。同步發(fā)布鏈接是:http://www.52im.net/thread-3515-1-1.html,原文鏈接:點此進(jìn)入
作者:Jack Jiang (點擊作者姓名進(jìn)入Github)
出處:http://www.52im.net/space-uid-1.html
交流:歡迎加入即時通訊開發(fā)交流群 215891622
討論:http://www.52im.net/
Jack Jiang同時是【原創(chuàng)Java
Swing外觀工程BeautyEye】和【輕量級移動端即時通訊框架MobileIMSDK】的作者,可前往下載交流。
本博文
歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明出處(也可前往 我的52im.net 找到我)。