本文來自英特爾實時通信解決方案架構(gòu)師 段先德在LiveVideoStackCon2019上海大會的分享,詳細介紹了英特爾在進行分布式SFU/MCU媒體服務(wù)器的架構(gòu)設(shè)計中秉持的一些設(shè)計原則以及關(guān)鍵問題的解決思路。
大家好,我是來自英特爾上海研發(fā)中心的段先德。從2014年開始主要做基于WebRTC的實時通信和統(tǒng)一通信解決方案。對于實時通訊來說WebRTC技術(shù)是一個革命性的存在。2014年4月英特爾發(fā)布了Intel? Collaboration Suite for WebRTC,這是一款可免費使用的包含服務(wù)器側(cè)程序和客戶端SDK的完整解決方案。經(jīng)過多年的迭代更新,當(dāng)前最新發(fā)布的是4.2版本。
1.Requirements and Design Principles
本次分享的內(nèi)容主要分為三個部分,首先介紹英特爾ICS for WebRTC項目中要解決的問題;其次介紹我們在解決這些問題的時候的指導(dǎo)思想和整體設(shè)計原則;最后介紹我們的解決方案目前的狀態(tài)以及當(dāng)下和近期要做的一些事情。
1.1 Functional Requirements
我們項目團隊最初的出發(fā)點是希望能做一套夠達到一般功能性要求的基于互聯(lián)網(wǎng)的視頻會議解決方案。譬如可以支持WebRTC和SIP終端,實現(xiàn)接入到同一個會議中。SIP主要針對的是存量設(shè)備,重點是對WebRTC終端的支持。WebRTC接入相比于很多以前存量的企業(yè)視頻會議解決方案有很多的突破,從2011年以后Chrome在端多媒體系統(tǒng),弱網(wǎng)對抗方面以及音視頻處理這方面一直在持續(xù)的改進。
英特爾很早就注意到在WebRTC時代,亟需一個統(tǒng)一的終端和服務(wù)器側(cè)的解決方案。我們需要把企業(yè)內(nèi)外的一些移動終端、桌面應(yīng)用、瀏覽器、傳統(tǒng)的SIP終端設(shè)備都支持起來,需要支持NAT穿越和屏幕共享,需要支持服務(wù)器側(cè)音視頻錄制,等等。這里面很多功能性需求通過傳統(tǒng)SIP的解決方案做起來很不方便或者成本很高,但是在WebRTC時代,在基于互聯(lián)網(wǎng)應(yīng)用的技術(shù)思路下,可以很便捷、很優(yōu)雅地解決這些問題,于是我們在2014年做了ICS for WebRTC v1.0。之后在2016年和2017年之間直播類的應(yīng)用大爆發(fā)使得有些客戶希望我們的解決方案里面能夠支持直播類場景,把實時互動場景下的音視頻流通過RTMP/RTSP/HLS/Dash推送到現(xiàn)有的CDN網(wǎng)絡(luò)里面去。基于這類需求,我們在功能性方面增加了互動Streaming的能力。
2018年到現(xiàn)在,直播的用戶體驗要求越來越高,客戶希望主播和粉絲或者觀眾之間的互動能夠非常平滑的切換,同時端到端的時延也能夠做得更好,也就是希望做到保證端到端的實時性的前提下,在單個呼叫里支持海量的用戶連接。這就要求服務(wù)器側(cè)系統(tǒng)既要有非常大的“扇出”能力,要支持終端連接在“發(fā)布者”和“訂閱者”之間非常平滑地進行切換。我們目前正在做的就是把目前的解決方案擴展到這種能夠支持大規(guī)模并發(fā)的“實時互動廣播”,初步目標(biāo)是單個呼叫里達到百萬以上的并發(fā)連接,而且端到端的時延能夠全球控制在300毫秒以內(nèi)。關(guān)于端到端時延,我們在國內(nèi)互聯(lián)網(wǎng)上做過一些小規(guī)模的測試,測試結(jié)果的時延是150毫秒以內(nèi)。我們還希望這個解決方案能夠很方便封裝成類似于CDN的服務(wù)訪問接口或者形式,以便集成到客戶現(xiàn)有的直播解決方案中去。
我們當(dāng)前的解決方案已經(jīng)具備了非常靈活的服務(wù)器側(cè)媒體處理,服務(wù)器端可以做音視頻的混音混流,比如說當(dāng)前的一個呼叫里面有十幾個參與方,有的參與方希望訂閱呼叫中其他參與方發(fā)布的原始流,有的參與方希望訂閱所有或部分參與方的mix流,有的參與方希望訂閱符合自己對codec、分辨率、幀率、碼率等定制化要求的轉(zhuǎn)發(fā)流,我們當(dāng)前的解決方案已經(jīng)可以很好地支持這些需求。
1.2 Nonfunctional Requirements
如果僅僅是為了達到前面所講的各種功能性需求,隨便選擇一個現(xiàn)有的開源框架去改改,再自己從頭寫一些功能模塊拼湊一下,總可以整出一個PoC的版本或可以初步走向產(chǎn)品的東西。如果是要嚴肅地做一個打算把它放到生產(chǎn)環(huán)境去運營的產(chǎn)品級別的東西,真正考驗這個解決方案的生命力的其實是它在非功能性需求方面的取舍和功力。即使是選擇現(xiàn)有的開源框架去做產(chǎn)品,這個框架對非功能性方面的考量也是最重要的決定因素。
在非功能性方面主要關(guān)注的點有三個方面。
一是系統(tǒng)的可擴展性,它的服務(wù)部署規(guī)模可大可小,可以小到在一臺英特爾??酷睿??i7的PC上部署使用,大到一個集群幾百臺甚至上千臺機器組成一個大的cluster上部署使用。另外呼叫的參與方式可以是兩三個人的討論會,或者十幾個人一般視頻會議,又或者是幾十人的在線課堂。部署時可以在當(dāng)前的系統(tǒng)容量不足時在不中斷業(yè)務(wù)的前提下增加或者刪減當(dāng)前部署的規(guī)模,達到很靈活的Scale in/Scale out。
二是容錯性,容錯能力大多描述都比較抽象,但是落實到系統(tǒng)在做設(shè)計的時候要考慮的東西就是非常具體的設(shè)計決策,在系統(tǒng)設(shè)計里面我們會強調(diào)甚至固執(zhí)的堅持每一個部件都可能會出錯,運行時都會發(fā)生crash,這就需要在流程設(shè)計或者一般邏輯里面handle這些問題,在系統(tǒng)發(fā)生部分失效的時候,要能夠做到自動恢復(fù)或服務(wù)優(yōu)雅降級。
三是分布式部署,單臺機器上單實例的部署是不可能做容錯的,只有分布式的部署才能夠做到。我們要求允許把任何部件部署在數(shù)據(jù)中心的多臺機器上面。我們現(xiàn)在進一步的要求是要能夠把任何部件部署在多個數(shù)據(jù)中心,進行跨數(shù)據(jù)中心的分布式部署。
2.Unified Media Spread Model UMSM)
2.1 Modularization at Runtime
要滿足上述的各種功能性和非功能性需求,就需要在概念模型上對系統(tǒng)的各個部件進行足夠的抽象,將邏輯上獨立的部件封裝到運行時獨立的模塊里面——即模塊化。不管是從單一職責(zé)的角度來說,還是從系統(tǒng)的可組合性來說,模塊化是自始至終不能打破的一個原則,是我們當(dāng)前系統(tǒng)——也是很多復(fù)雜系統(tǒng)進行架構(gòu)的第一原則。在我們的系統(tǒng)設(shè)計中,對于跟客戶端交互的部件來說,要把信令和媒體分開。對于媒體部分來說,媒體的接入部分和處理部分一定是分開的,直接和用戶打交道的部分和后臺內(nèi)部的一些處理部件,不管是從單一職責(zé)角度來講還是從面向接口的健壯性要求來講都必須把它們分開。
我們的服務(wù)器側(cè)系統(tǒng)在運行時可以分成五大塊。
第一塊就是跟客戶端進行信令交互的部件,即圖中的WebRTC Portal和SIP Portal。他們跟WebRTC客戶端和SIP終端進行信令交互。值得注意的一點是WebRTC標(biāo)準(zhǔn)對信令交互的格式和通道沒有規(guī)定,我們采用的是一種承載在socket.io通道中的私有協(xié)議。
第二塊是跟客戶端進行音視頻媒體交互的部件,即圖中的WebRTC Agent、Streaming Agent、SIP Agent和Recording Agent。其中WebRTC Agent負責(zé)跟客戶端之間建立PeerConnection連接,SIP Agent跟SIP終端RTP流進行傳輸,Streaming Agent是針對RTSP/RTMP/HLS/Dash流,我們可以把IPCamera的RTSP流作為輸入直接拉到系統(tǒng)里面來,也可以把系統(tǒng)里面任何一個輸入流/合成流/轉(zhuǎn)碼后的流作為輸出推送到RTMP Server上去,Recording雖然是完全發(fā)生在服務(wù)器側(cè)的行為,但實際上在概念層次上面是更接近于流的輸出。所以在概念模型里我們也把Recording Agent當(dāng)做媒體接出部件,以達到概念模型的一致性。
第三塊是媒體處理的部件,即圖中的Audio Agent和Video Agent。Audio Agent是進行音頻混音轉(zhuǎn)碼工作的部件,Video Agent是視頻的合屏和轉(zhuǎn)碼的部件,這些所有的部件都是單獨部署獨立進程在運行。
第四塊是呼叫控制的部件,即圖中的Conference Agent。我們的系統(tǒng)還是將多方實時音視頻通信作為場景基礎(chǔ),Conference Agent就是一通呼叫的總控制部件,它負責(zé)room中的參與者、流、訂閱關(guān)系的控制和管理。對于像遠程教育、遠程醫(yī)療、遠程協(xié)助之類的其他場景,我們主要是通過對Conference Agent來進行拓展和增強去支持。
第五塊就是一些支持部件。整個服務(wù)器系統(tǒng)在運行和單機運行時都是cluster形式,Cluster Manager就是一個簡單的cluster管理器。視頻會議場景中會有一些room的預(yù)配置和管理,room的配置數(shù)據(jù)存放在MongoDB中,管理員都是通過OAM UI通過RESTful API訪問Management API部件實現(xiàn)數(shù)據(jù)訪問并受理REST請求。另外各個部件之間的rpc是架設(shè)在RabbitMQ消息隊列上的。
2.2 Strong Isolation
第二個原則就是要做強隔離。在系統(tǒng)里面堅持執(zhí)行的原則就是要做強隔離,運行時一定是把看到的邏輯上面獨立部件,把它在物理上也做成完全獨立的運行時進程。比如像信令受理部件和信令執(zhí)行部件就是分別獨立的進程。這樣做使得信令受理部件可以獨立于呼叫控制里面的業(yè)務(wù)邏輯而存在。同理媒體接入部件和媒體處理部件也是分別獨立進程。這里的進程就是OS語義上面進程,是我們服務(wù)器側(cè)系統(tǒng)構(gòu)建的基本元素,是生命體的細胞,不同的部件之間進行通訊唯一的方式就是message passing(消息傳遞)。在概念模型里面看的得到部件都是用單獨的Worker進程來處理一個獨立的Job。比方說一個Video Agent生成出來的Video Node,它的職責(zé)要么是做一個視頻混流器,要么是做一個視頻轉(zhuǎn)碼器,單獨運行,獨立工作。這樣做一方面是進行錯誤隔離一個部件中產(chǎn)生的異常不會傳染影響其他部件,一方面是各個運行時部件可以進行運行時單獨進行升級替換。
2.3 Hierarchy in Media Accessing/Processing
第三個原則就是層次化。具體體現(xiàn)在在媒體接入和媒體處理的一些部件的設(shè)計和實現(xiàn)上,這些部件在南北(縱)向上面有明確的層次劃分,自下而上分為包交互層、幀交互層和內(nèi)容操作層。以媒體接入部件為例,我們服務(wù)器側(cè)系統(tǒng)需要跟各種外圍系統(tǒng)和終端進行媒體交互,有的媒體是通過RTP/SRTP包的形式輸入、輸出,有的媒體是直接以AVStream的行書輸出、輸出。當(dāng)媒體進入到我們服務(wù)器側(cè)系統(tǒng)內(nèi)部以后,我們希望有一個統(tǒng)一的格式讓它在所有的媒體相關(guān)部件之間自由流轉(zhuǎn),所以我們就定義了統(tǒng)一的MediaFrame格式,所有輸入的媒體在媒體接入部件上被組裝成MediaFrame。處理MediaFrame的邏輯我們把它放在幀交互層,與客戶端進行RTP/SRTP交互的邏輯我們放在包交互層。另外,MediaFrame進入媒體處理部件后,如果涉及到raw格式的操作——譬如合屏、色彩調(diào)整、添加水印、替換背景等——我們就把相關(guān)邏輯放在內(nèi)容操作層。
2.4 Media Pipeline in WebRTC Node
設(shè)計原則講起來太枯燥,舉兩個例子。
第一個是WebRTC Node中的Pipeline結(jié)構(gòu)。在WebRTCNode上面有一個明確的一個界限,廣為人知的一些開源的框架里面有一些SFU框架是直接做RTP包的高級轉(zhuǎn)發(fā),而在我們的解決方案里于所有的外部媒體進入到系統(tǒng)里面會先將它們整理成統(tǒng)一的媒體(幀集的封裝)之后在各個結(jié)點之間進行傳輸。除了使得層次分明便于系統(tǒng)橫向擴展以外,另外一大好處就是把RTP傳輸相關(guān)的事務(wù)都終結(jié)在媒體接入部件(節(jié)點)上,RTP傳輸中的丟包、亂序等問題的處理不會擴散到系統(tǒng)其它部件。
2.5 Media Pipeline in Video Node (Video Mixer)
第二個例子是視頻混流器內(nèi)部的Pipeline結(jié)構(gòu)。視頻混流的部件在Pipeline上面進出都是視頻幀,圖上紫顏色的模塊進出的都是視頻已編碼的幀,在視頻處理部件的內(nèi)部可以是一些已編碼的幀,也可以是一些Scaler和Convertor。使得各個層次的處理器接口非常清楚,便于做成plugable。
2.6 Unified Media Spread Model (UMSM)
前面我們根據(jù)系統(tǒng)的功能性和非功能性需求,把系統(tǒng)拆成了一個個松散的部件。那么,怎么把這些部件捏合到一起成為一個有機的系統(tǒng)呢?特別是針對各個媒體接入部件和媒體處理部件之間的媒體交互,我們需要定義一個統(tǒng)一的內(nèi)部媒體交互模型——我們稱之為UMSM。
音視頻媒體在系統(tǒng)內(nèi)部流動,我們采用的是一個“發(fā)布-訂閱”結(jié)構(gòu)的流基本拓撲。如圖所示,系統(tǒng)有一個發(fā)布者發(fā)布一個流進入到系統(tǒng)里,此時有兩個訂閱者,其中一個訂閱者希望訂閱發(fā)布的原始流的直接轉(zhuǎn)發(fā)流,另外一個訂閱者希望訂閱房間里面所有的原始流合成流合屏以后的mix流,流的發(fā)布者和訂閱者的PeerConnection連接建立在不同的WebRTC Node上面,通過PeerConnection進入WebRTC Node的SRTP包流,經(jīng)過解密,被整理封裝成MediaFrame(Audioframe/Videoframe),之后再在不同的部件之間進行傳遞,如果有訂閱者需要的是直接轉(zhuǎn)發(fā)流,就把它封裝好的音頻和視頻的幀直接擴散到訂閱者所連接的WebRTC Node上面來,如果有訂閱者需要合成的流(合屏和混音的流),那么就把混流和混音以后的MediaFrame從AudioNode(Audio Mixer)和VideoNode(Video Mixer)擴散到訂閱者所連接的WebRTC Node上。
有了這樣一個足夠松散的系統(tǒng)內(nèi)部流擴散結(jié)構(gòu),無論這些媒體接入部件和媒體處理部件是運行在同一臺機器上還是運行在一個數(shù)據(jù)中心內(nèi)的不同機器上——甚至運行在位于不同數(shù)據(jù)中心的不同機器上,都有統(tǒng)一的、一致的流拓撲結(jié)構(gòu)。
2.7 Media Spread Protocol
要實現(xiàn)這樣一個流擴散模型,重點要解決兩個方面的問題,一個是媒體節(jié)點間的傳輸,另一個是媒體節(jié)點的控制。
媒體節(jié)點間的傳輸是面向連接的,因為擴散鏈路都可能持續(xù)比較長的時間,且一般服務(wù)器側(cè)部件的部署環(huán)境的網(wǎng)絡(luò)條件是可控的,有利于保障傳輸質(zhì)量。另外每一個連接結(jié)點間的擴散鏈路的連接是雙向的,因為有可能兩個媒體流的接入結(jié)點之間存在雙向的擴散,以及與媒體流相關(guān)的一些feedback信息需要被反向傳遞,我們希望它能夠復(fù)用在同一個擴散鏈路上面。另外我們需要它是可靠的,在以前跟合作伙伴做技術(shù)交流的時候他們對于要求流擴散鏈路必須是可靠的這一點有疑惑。實際上這是一個實時性和可靠性的取舍問題,我們選擇在這個環(huán)節(jié)保證可靠性,而把實時性推給底層去解決,因為如果要在流擴散鏈路的所有環(huán)節(jié)處理信號損失,將給上層邏輯帶來巨大的復(fù)雜性。
2.8 MSP - Transport Control Primitives(WIP)
傳輸控制就是對于節(jié)點間擴散傳輸鏈路的控制,目前為了方便在采用的是TCP,在同一數(shù)據(jù)中心內(nèi)進行流擴散問題不大,在應(yīng)用到跨數(shù)據(jù)中心的部署場景中時,特別是tts和delay比較大的情況下,實際可用的throughput會受比較大的影響,目前仍有一些改進的工作還在進行當(dāng)中,我們也在調(diào)研SCTP和QUIC。
2.9 MSP - Underlying Transport Protocols(TCP vs.QUIC under weak network)
我們在節(jié)點間擴散時加一些網(wǎng)損的情況下用TCP和QUIC有做過一些對比測試。QUIC和TCP都是可靠傳輸,在有網(wǎng)損的時候都會產(chǎn)生一些重傳或者是冗余,但是他們不同的擁塞控制策略會對端到端的媒體傳遞的質(zhì)量產(chǎn)生不同的影響。我們的對比測試中,發(fā)送端是以恒定的碼率和幀率(24fps)向服務(wù)器側(cè)發(fā)送視頻流,服務(wù)器側(cè)在節(jié)點間分別采用TCP和QUIC進行節(jié)點間媒體流擴散,圖中截取的是相同的網(wǎng)損條件下接收端收到的實際幀率,在5%的丟包和30ms delay時, TCP的幀率就會抖動的非常厲害,在接收端體驗就會看到點不流暢,能明顯地看到它的卡頓。當(dāng)加上10%的丟包時波動就跟家劇烈,有時甚至降低到0fps,接收端的用戶體驗就是非常明的卡頓。相比而言,在QUIC上面還能夠看到,接收端的幀率能夠更好地堅持在24fps上下,接收端的流暢度更好。總體來看,QUIC是在弱網(wǎng)環(huán)境下進行節(jié)點間流擴散的一個不錯的備選傳輸。
2.10 MSP - Media Control Primitives
媒體控制的操作對于媒體節(jié)點來說,一個publish就是往媒體結(jié)點上面發(fā)布一路流,給它增加一個input,一個subscribe就是在它上面去增添一個output,linkup就是把一個input和output接續(xù)起來,cutoff就把一個input和一個output拆開。對于媒體處理的結(jié)點有一些內(nèi)生的流,generate就是讓它產(chǎn)生一路流指定規(guī)格(codec、分辨率、幀率、碼率、關(guān)鍵幀間隔等),degenerate就是讓它取消正在生成中的一個流。
3.1 Cross DC Media Spread:Relay Node (WIP)
做TCP和QUIC的對比調(diào)研目的就是解決跨數(shù)據(jù)中心通過Internet進行節(jié)點間媒體流擴散的實時性(本質(zhì)是throughput)問題。由于在跨數(shù)據(jù)中心媒體擴散的時候需要在Internet上面做流擴散,Internet在傳輸質(zhì)量上講沒有在數(shù)據(jù)中心里的效果那么滿意,需要找一些基于UDP改進的可靠傳輸協(xié)議去嘗試,我們調(diào)研過SCTP和QUIC,總體來看QUIC的表現(xiàn)是相當(dāng)不錯的。
同時為了減少同一條流在兩個數(shù)據(jù)中心的多個節(jié)點間傳輸,我們增加了一個Relay Agent(Node)的部件,使得同一條流在兩個數(shù)據(jù)中心之間只需要擴散一次。Relay Agent的另一個作用是進行流擴散的時候的路由控制,譬如一個集團公司的很多分支機房并不是BGP的,需要將流匯聚到指定的BGP機房才能更好地向其他地區(qū)數(shù)據(jù)中心擴散。
3.2 Access Node(Agent) Scheduling
在部署了多個接入節(jié)點以后,除了通過增加接入節(jié)點來擴充系統(tǒng)的scalability,我們還希望能夠利用接入節(jié)點的不同地理位置給靠近它的終端用戶做就近接入。以WebRTC Agent為例,在部署WebRTC Agent的時候可以指定它的capacity(能力),capacity上面有兩個標(biāo)簽,一個是isp,一個是region。用戶在進行通信連接請求的時候,它帶上isp和region的preference(喜好),系統(tǒng)在進行WebRTC Agent調(diào)度的時候會對所有可用的WebRTC Agent的capacity與用戶指定的preference進行匹配,找到最滿意的接入結(jié)點,最后達到就近接入的目的。
在符合preference的候選不止一個時,系統(tǒng)還提供基于work load和歷史使用記錄進行l(wèi)ast-used、least-used、round-robin、random等調(diào)度策略,選取符合指定策略的接入節(jié)點。
3.3 CDN alike Service
解決了跨數(shù)據(jù)中心部署的媒體流擴散和調(diào)度問題后,我們的解決方案就可以提供更廣闊的實時多方音視頻通信服務(wù)。特別是有了Relay Agent的級聯(lián)能力后,我們服務(wù)器側(cè)系統(tǒng)就可以得到極大的提升,譬如假設(shè)單個媒體接入節(jié)點的扇出能力是1:1000的話,經(jīng)過一級級聯(lián)后就能達到1:100萬,經(jīng)過兩級級聯(lián)后就能達到1:10億,已經(jīng)堪比一般CDN的扇出能力了。而CDN的就是本質(zhì)是一個分布式的cache系統(tǒng),cache是實時應(yīng)用的天敵。許多既要求海量扇出比,又要求實時性,并且要隨時平滑進行流拓撲切換的場景下,CDN就顯得無能為力了,而我們的解決方案將覆蓋這些場景,特別是在5G和IoT的時代。
-
英特爾
+關(guān)注
關(guān)注
61文章
9960瀏覽量
171743 -
服務(wù)器
+關(guān)注
關(guān)注
12文章
9149瀏覽量
85405
原文標(biāo)題:如何構(gòu)建分布式SFU/MCU媒體服務(wù)器?
文章出處:【微信號:livevideostack,微信公眾號:LiveVideoStack】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論