干貨:如何打造一個直播平台


上幾篇介紹了如何實現一個百萬級別的語音聊天室,本篇將介紹直播平台的設計。開始分享這個項目其實有點猶豫,因為我所參與的直播平台跟業界常用的方案不太一樣。但是仔細想想,架構設計本來就是在各種條件約束下的因地制宜,沒有絕對的正確和錯誤,合適才是關鍵。

我們是國內做直播相對比較早的團隊,也缺乏一些行業通用方案的參考,因此很多地方是自己通過踩坑摸索出來的。因為最開始我們產品只支持語音聊天,后來隨着直播業務(娛樂直播、游戲直播)的普及,才開始支持視頻直播,所以最朴素的想法就是,直接把語音服務的架構拿過來用。

 

上篇介紹了語音聊天室的完整架構,我們的設計就從這里開始。視頻服務可以用這種架構嗎?答案是肯定的。把上圖中的語音數據替換成視頻數據就可以了,唯一的不同是語音聊天室多個用戶可以同時說話,但是直播平台就只能有一個主播。

 

但是,隨着業務不斷增長,問題開始出現:一個SET內的房間數量到達了瓶頸。為什么呢?這要從語音服務器的實現說起。

 

如圖所示,每個語音服務器為每個房間維護6個語音通道(采用循環隊列實現),其中5個通道分別緩存5個用戶的語音數據,第6個是混音通道。沒錯,是5個用戶,聊天室的設計就是最多只支持5個用戶同時說話,因為同時說話的人再多就會聽不清楚。那其他人想說話怎么辦?一般的做法是聊天室的搶麥或者用戶多長時間不說話就自動放棄通道,或者像LOL這種游戲團隊設計就只有5個人。混音通道實際上就是把5個通道的數據根據時間順序放到一起(當然還有一些其他處理),聽眾收到的是混音通道的數據。

視頻服務器因為每個房間只有一個主播,因此只需要維護一個視頻數據通道,實現上與語音服務器類似。按理說,視頻服務器應該更簡單才對,但是卻有別的問題。

之前說過,語音服務器是按照SET來部署的,一個SET包含多個語音服務器,房間分布在一個SET內的機器上。因此通常一個房間會分布到多台語音服務器,這樣主要是為了用戶的就近接入。那SET內的房間數受什么制約呢?

之前沒有介紹的一個細節是,下圖所示,如果一個房間分布在多台語音服務器,這些語音服務器上都需要維護這個房間的6個語音通道(為什么不是只維護混音通道,大家自己思考),因此房間數的制約主要在於單台服務器的內存大小。

 

因為語音數據是很小的,一個包大概300多字節,6個語音通道占用的內存大概幾M,一台4G內存的機器就可以承載上千個房間。按照之前的計算一個SET 10台機器可以承載20萬的用戶,上千個房間幾乎是不可能的,因此對於語音服務,內存的瓶頸是不存在的。

但是對於視頻服務就不一樣了,視頻數據可是很大的,一幀的數據有時候可以達到幾M, 1個數據通道都可能占用幾十甚至上百M的內存。因此單服務器可承載的房間數可能只有一百個,也就是說單SET的房間數最多只能有一百個,這里就是瓶頸所在。

大家注意了,這個瓶頸是無法通過平行擴展增加機器來解決的,因為每台機器都受到這個限制(當然可以給每台機器加內存來解決,但是這種做法一方面增加了成本,另一方面增加了故障的概率)。這是一個系統架構導致的問題,解決方法可能很多,例如摒棄分SET的架構,或者把SET機器數減少等等。可以說,這個問題把我們從最開始閉門造車的野路子拉回了業界的通用標准。

 

做過直播的同學應該對上面的圖都很熟悉,它是一個典型的直播平台的架構圖。這個圖跟我們最開始的架構有一個最本質的區別是,我們采用了別人的CDN。為什么要加“別人”?因為我們之前實際上是在嘗試做自己的CDN來實現數據的分發。但是這條路走下來是個無底洞,我們沒有別人的資源豐富和專業。因此,上面的架構中,我們只負責生產數據,我們維護主播上傳的視頻數據,並把視頻資源信息上報給回源服務器。用戶打開直播時,先去CDN請求數據,如果CDN沒有數據,就會到回源服務器查找資源地址,並向資源所在的視頻服務器請求數據返回用戶。下次用戶打開視頻的時候,CDN就直接從自己維護的數據通道中獲取視頻了。

本篇主要介紹了視頻服務架構演進的過程,描述了從最開始照搬語音服務的架構,到面臨架構瓶頸時,轉而采用目前業界通用的架構的思路歷程。架構設計跟項目所處的時代背景和階段密切相關,每個階段都有其局限性,不能因為技術發展而完全否定原來的設計思路,現在所謂的業界標准也是從一次次的踩坑中走出來的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM