owt概覽一

本文來自英特爾實時通信解決方案架構師 段先德在LiveVideoStackCon2019上海大會的分享,詳細介紹了英特爾在進行分佈式SFU/MCU媒體服務器的架構設計中秉持的一些設計原則以及關鍵問題的解決思路。

大家好,我是來自英特爾上海研發中心的段先德。從2014年開始主要做基於WebRTC的實時通信和統一通信解決方案。對於實時通訊來說WebRTC技術是一個革命性的存在。2014年4月英特爾發佈了Intel® Collaboration Suite for WebRTC,這是一款可免費使用的包含服務器側程序和客戶端SDK的完整解決方案。經過多年的迭代更新,當前最新發布的是4.2版本。

  1. Requirements and Design Principles

在這裏插入圖片描述

本次分享的內容主要分爲三個部分,首先介紹英特爾ICS for WebRTC項目中要解決的問題;其次介紹我們在解決這些問題的時候的指導思想和整體設計原則;最後介紹我們的解決方案目前的狀態以及當下和近期要做的一些事情。

1.1 Functional Requirements

在這裏插入圖片描述

我們項目團隊最初的出發點是希望能做一套夠達到一般功能性要求的基於互聯網的視頻會議解決方案。譬如可以支持WebRTC和SIP終端,實現接入到同一個會議中。SIP主要針對的是存量設備,重點是對WebRTC終端的支持。WebRTC接入相比於很多以前存量的企業視頻會議解決方案有很多的突破,從2011年以後Chrome在端多媒體系統,弱網對抗方面以及音視頻處理這方面一直在持續的改進。

英特爾很早就注意到在WebRTC時代,亟需一個統一的終端和服務器側的解決方案。我們需要把企業內外的一些移動終端、桌面應用、瀏覽器、傳統的SIP終端設備都支持起來,需要支持NAT穿越和屏幕共享,需要支持服務器側音視頻錄製,等等。這裏面很多功能性需求通過傳統SIP的解決方案做起來很不方便或者成本很高,但是在WebRTC時代,在基於互聯網應用的技術思路下,可以很便捷、很優雅地解決這些問題,於是我們在2014年做了ICS for WebRTC v1.0。之後在2016年和2017年之間直播類的應用大爆發使得有些客戶希望我們的解決方案裏面能夠支持直播類場景,把實時互動場景下的音視頻流通過RTMP/RTSP/HLS/Dash推送到現有的CDN網絡裏面去。基於這類需求,我們在功能性方面增加了互動Streaming的能力。

2018年到現在,直播的用戶體驗要求越來越高,客戶希望主播和粉絲或者觀衆之間的互動能夠非常平滑的切換,同時端到端的時延也能夠做得更好,也就是希望做到保證端到端的實時性的前提下,在單個呼叫裏支持海量的用戶連接。這就要求服務器側系統既要有非常大的“扇出”能力,要支持終端連接在“發佈者”和“訂閱者”之間非常平滑地進行切換。我們目前正在做的就是把目前的解決方案擴展到這種能夠支持大規模併發的“實時互動廣播”,初步目標是單個呼叫裏達到百萬以上的併發連接,而且端到端的時延能夠全球控制在300毫秒以內。關於端到端時延,我們在國內互聯網上做過一些小規模的測試,測試結果的時延是150毫秒以內。我們還希望這個解決方案能夠很方便封裝成類似於CDN的服務訪問接口或者形式,以便集成到客戶現有的直播解決方案中去。

我們當前的解決方案已經具備了非常靈活的服務器側媒體處理,服務器端可以做音視頻的混音混流,比如說當前的一個呼叫裏面有十幾個參與方,有的參與方希望訂閱呼叫中其他參與方發佈的原始流,有的參與方希望訂閱所有或部分參與方的mix流,有的參與方希望訂閱符合自己對codec、分辨率、幀率、碼率等定製化要求的轉發流,我們當前的解決方案已經可以很好地支持這些需求。

1.2 Nonfunctional Requirements

在這裏插入圖片描述

如果僅僅是爲了達到前面所講的各種功能性需求,隨便選擇一個現有的開源框架去改改,再自己從頭寫一些功能模塊拼湊一下,總可以整出一個PoC的版本或可以初步走向產品的東西。如果是要嚴肅地做一個打算把它放到生產環境去運營的產品級別的東西,真正考驗這個解決方案的生命力的其實是它在非功能性需求方面的取捨和功力。即使是選擇現有的開源框架去做產品,這個框架對非功能性方面的考量也是最重要的決定因素。

在非功能性方面主要關注的點有三個方面。

一是系統的可擴展性,它的服務部署規模可大可小,可以小到在一臺英特爾®️ 酷睿™️i7的PC上部署使用,大到一個集羣幾百臺甚至上千臺機器組成一個大的cluster上部署使用。另外呼叫的參與方式可以是兩三個人的討論會,或者十幾個人一般視頻會議,又或者是幾十人的在線課堂。部署時可以在當前的系統容量不足時在不中斷業務的前提下增加或者刪減當前部署的規模,達到很靈活的Scale in/Scale out。

二是容錯性,容錯能力大多描述都比較抽象,但是落實到系統在做設計的時候要考慮的東西就是非常具體的設計決策,在系統設計裏面我們會強調甚至固執的堅持每一個部件都可能會出錯,運行時都會發生crash,這就需要在流程設計或者一般邏輯裏面handle這些問題,在系統發生部分失效的時候,要能夠做到自動恢復或服務優雅降級。

三是分佈式部署,單臺機器上單實例的部署是不可能做容錯的,只有分佈式的部署才能夠做到。我們要求允許把任何部件部署在數據中心的多臺機器上面。我們現在進一步的要求是要能夠把任何部件部署在多個數據中心,進行跨數據中心的分佈式部署。

2.Unified Media Spread Model UMSM)

2.1 Modularization at Runtime

在這裏插入圖片描述

要滿足上述的各種功能性和非功能性需求,就需要在概念模型上對系統的各個部件進行足夠的抽象,將邏輯上獨立的部件封裝到運行時獨立的模塊裏面——即模塊化。不管是從單一職責的角度來說,還是從系統的可組合性來說,模塊化是自始至終不能打破的一個原則,是我們當前系統——也是很多複雜系統進行架構的第一原則。在我們的系統設計中,對於跟客戶端交互的部件來說,要把信令和媒體分開。對於媒體部分來說,媒體的接入部分和處理部分一定是分開的,直接和用戶打交道的部分和後臺內部的一些處理部件,不管是從單一職責角度來講還是從面向接口的健壯性要求來講都必須把它們分開。

我們的服務器側系統在運行時可以分成五大塊。

第一塊就是跟客戶端進行信令交互的部件,即圖中的WebRTC Portal和SIP Portal。他們跟WebRTC客戶端和SIP終端進行信令交互。值得注意的一點是WebRTC標準對信令交互的格式和通道沒有規定,我們採用的是一種承載在socket.io通道中的私有協議。

第二塊是跟客戶端進行音視頻媒體交互的部件,即圖中的WebRTC Agent、Streaming Agent、SIP Agent和Recording Agent。其中WebRTC Agent負責跟客戶端之間建立PeerConnection連接,SIP Agent跟SIP終端RTP流進行傳輸,Streaming Agent是針對RTSP/RTMP/HLS/Dash流,我們可以把IPCamera的RTSP流作爲輸入直接拉到系統裏面來,也可以把系統裏面任何一個輸入流/合成流/轉碼後的流作爲輸出推送到RTMP Server上去,Recording雖然是完全發生在服務器側的行爲,但實際上在概念層次上面是更接近於流的輸出。所以在概念模型裏我們也把Recording Agent當做媒體接出部件,以達到概念模型的一致性。

第三塊是媒體處理的部件,即圖中的Audio Agent和Video Agent。Audio Agent是進行音頻混音轉碼工作的部件,Video Agent是視頻的合屏和轉碼的部件,這些所有的部件都是單獨部署獨立進程在運行。

第四塊是呼叫控制的部件,即圖中的Conference Agent。我們的系統還是將多方實時音視頻通信作爲場景基礎,Conference Agent就是一通呼叫的總控制部件,它負責room中的參與者、流、訂閱關係的控制和管理。對於像遠程教育、遠程醫療、遠程協助之類的其他場景,我們主要是通過對Conference Agent來進行拓展和增強去支持。

第五塊就是一些支持部件。整個服務器系統在運行和單機運行時都是cluster形式,Cluster Manager就是一個簡單的cluster管理器。視頻會議場景中會有一些room的預配置和管理,room的配置數據存放在MongoDB中,管理員都是通過OAM UI通過RESTful API訪問Management API部件實現數據訪問並受理REST請求。另外各個部件之間的rpc是架設在RabbitMQ消息隊列上的。

2.2 Strong Isolation

在這裏插入圖片描述

第二個原則就是要做強隔離。在系統裏面堅持執行的原則就是要做強隔離,運行時一定是把看到的邏輯上面獨立部件,把它在物理上也做成完全獨立的運行時進程。比如像信令受理部件和信令執行部件就是分別獨立的進程。這樣做使得信令受理部件可以獨立於呼叫控制裏面的業務邏輯而存在。同理媒體接入部件和媒體處理部件也是分別獨立進程。這裏的進程就是OS語義上面進程,是我們服務器側系統構建的基本元素,是生命體的細胞,不同的部件之間進行通訊唯一的方式就是message passing(消息傳遞)。在概念模型裏面看的得到部件都是用單獨的Worker進程來處理一個獨立的Job。比方說一個Video Agent生成出來的Video Node,它的職責要麼是做一個視頻混流器,要麼是做一個視頻轉碼器,單獨運行,獨立工作。這樣做一方面是進行錯誤隔離一個部件中產生的異常不會傳染影響其他部件,一方面是各個運行時部件可以進行運行時單獨進行升級替換。

2.3 Hierarchy in Media Accessing/Processing

在這裏插入圖片描述

第三個原則就是層次化。具體體現在在媒體接入和媒體處理的一些部件的設計和實現上,這些部件在南北(縱)向上面有明確的層次劃分,自下而上分爲包交互層、幀交互層和內容操作層。以媒體接入部件爲例,我們服務器側系統需要跟各種外圍系統和終端進行媒體交互,有的媒體是通過RTP/SRTP包的形式輸入、輸出,有的媒體是直接以AVStream的行書輸出、輸出。當媒體進入到我們服務器側系統內部以後,我們希望有一個統一的格式讓它在所有的媒體相關部件之間自由流轉,所以我們就定義了統一的MediaFrame格式,所有輸入的媒體在媒體接入部件上被組裝成MediaFrame。處理MediaFrame的邏輯我們把它放在幀交互層,與客戶端進行RTP/SRTP交互的邏輯我們放在包交互層。另外,MediaFrame進入媒體處理部件後,如果涉及到raw格式的操作——譬如合屏、色彩調整、添加水印、替換背景等——我們就把相關邏輯放在內容操作層。

2.4 Media Pipeline in WebRTC Node

在這裏插入圖片描述

設計原則講起來太枯燥,舉兩個例子。

第一個是WebRTC Node中的Pipeline結構。在WebRTCNode上面有一個明確的一個界限,廣爲人知的一些開源的框架裏面有一些SFU框架是直接做RTP包的高級轉發,而在我們的解決方案裏於所有的外部媒體進入到系統裏面會先將它們整理成統一的媒體(幀集的封裝)之後在各個結點之間進行傳輸。除了使得層次分明便於系統橫向擴展以外,另外一大好處就是把RTP傳輸相關的事務都終結在媒體接入部件(節點)上,RTP傳輸中的丟包、亂序等問題的處理不會擴散到系統其它部件。

2.5 Media Pipeline in Video Node (Video Mixer)

在這裏插入圖片描述

第二個例子是視頻混流器內部的Pipeline結構。視頻混流的部件在Pipeline上面進出都是視頻幀,圖上紫顏色的模塊進出的都是視頻已編碼的幀,在視頻處理部件的內部可以是一些已編碼的幀,也可以是一些Scaler和Convertor。使得各個層次的處理器接口非常清楚,便於做成plugable。

2.6 Unified Media Spread Model (UMSM)
在這裏插入圖片描述

前面我們根據系統的功能性和非功能性需求,把系統拆成了一個個鬆散的部件。那麼,怎麼把這些部件捏合到一起成爲一個有機的系統呢?特別是針對各個媒體接入部件和媒體處理部件之間的媒體交互,我們需要定義一個統一的內部媒體交互模型——我們稱之爲UMSM。

音視頻媒體在系統內部流動,我們採用的是一個“發佈-訂閱”結構的流基本拓撲。如圖所示,系統有一個發佈者發佈一個流進入到系統裏,此時有兩個訂閱者,其中一個訂閱者希望訂閱發佈的原始流的直接轉發流,另外一個訂閱者希望訂閱房間裏面所有的原始流合成流合屏以後的mix流,流的發佈者和訂閱者的PeerConnection連接建立在不同的WebRTC Node上面,通過PeerConnection進入WebRTC Node的SRTP包流,經過解密,被整理封裝成MediaFrame(Audioframe/Videoframe),之後再在不同的部件之間進行傳遞,如果有訂閱者需要的是直接轉發流,就把它封裝好的音頻和視頻的幀直接擴散到訂閱者所連接的WebRTC Node上面來,如果有訂閱者需要合成的流(合屏和混音的流),那麼就把混流和混音以後的MediaFrame從AudioNode(Audio Mixer)和VideoNode(Video Mixer)擴散到訂閱者所連接的WebRTC Node上。

有了這樣一個足夠鬆散的系統內部流擴散結構,無論這些媒體接入部件和媒體處理部件是運行在同一臺機器上還是運行在一個數據中心內的不同機器上——甚至運行在位於不同數據中心的不同機器上,都有統一的、一致的流拓撲結構。

2.7 Media Spread Protocol

在這裏插入圖片描述

要實現這樣一個流擴散模型,重點要解決兩個方面的問題,一個是媒體節點間的傳輸,另一個是媒體節點的控制。

媒體節點間的傳輸是面向連接的,因爲擴散鏈路都可能持續比較長的時間,且一般服務器側部件的部署環境的網絡條件是可控的,有利於保障傳輸質量。另外每一個連接結點間的擴散鏈路的連接是雙向的,因爲有可能兩個媒體流的接入結點之間存在雙向的擴散,以及與媒體流相關的一些feedback信息需要被反向傳遞,我們希望它能夠複用在同一個擴散鏈路上面。另外我們需要它是可靠的,在以前跟合作伙伴做技術交流的時候他們對於要求流擴散鏈路必須是可靠的這一點有疑惑。實際上這是一個實時性和可靠性的取捨問題,我們選擇在這個環節保證可靠性,而把實時性推給底層去解決,因爲如果要在流擴散鏈路的所有環節處理信號損失,將給上層邏輯帶來巨大的複雜性。

2.8 MSP – Transport Control Primitives(WIP)

在這裏插入圖片描述

傳輸控制就是對於節點間擴散傳輸鏈路的控制,目前爲了方便在採用的是TCP,在同一數據中心內進行流擴散問題不大,在應用到跨數據中心的部署場景中時,特別是tts和delay比較大的情況下,實際可用的throughput會受比較大的影響,目前仍有一些改進的工作還在進行當中,我們也在調研SCTP和QUIC。

2.9 MSP – Underlying Transport Protocols(TCP vs.QUIC under weak network)

在這裏插入圖片描述

我們在節點間擴散時加一些網損的情況下用TCP和QUIC有做過一些對比測試。QUIC和TCP都是可靠傳輸,在有網損的時候都會產生一些重傳或者是冗餘,但是他們不同的擁塞控制策略會對端到端的媒體傳遞的質量產生不同的影響。我們的對比測試中,發送端是以恆定的碼率和幀率(24fps)向服務器側發送視頻流,服務器側在節點間分別採用TCP和QUIC進行節點間媒體流擴散,圖中截取的是相同的網損條件下接收端收到的實際幀率,在5%的丟包和30ms delay時, TCP的幀率就會抖動的非常厲害,在接收端體驗就會看到點不流暢,能明顯地看到它的卡頓。當加上10%的丟包時波動就跟家劇烈,有時甚至降低到0fps,接收端的用戶體驗就是非常明的卡頓。相比而言,在QUIC上面還能夠看到,接收端的幀率能夠更好地堅持在24fps上下,接收端的流暢度更好。總體來看,QUIC是在弱網環境下進行節點間流擴散的一個不錯的備選傳輸。

2.10 MSP – Media Control Primitives
在這裏插入圖片描述

媒體控制的操作對於媒體節點來說,一個publish就是往媒體結點上面發佈一路流,給它增加一個input,一個subscribe就是在它上面去增添一個output,linkup就是把一個input和output接續起來,cutoff就把一個input和一個output拆開。對於媒體處理的結點有一些內生的流,generate就是讓它產生一路流指定規格(codec、分辨率、幀率、碼率、關鍵幀間隔等),degenerate就是讓它取消正在生成中的一個流。

3.Cross DC Media Spread

3.1 Cross DC Media Spread:Relay Node (WIP)

在這裏插入圖片描述

做TCP和QUIC的對比調研目的就是解決跨數據中心通過Internet進行節點間媒體流擴散的實時性(本質是throughput)問題。由於在跨數據中心媒體擴散的時候需要在Internet上面做流擴散,Internet在傳輸質量上講沒有在數據中心裏的效果那麼滿意,需要找一些基於UDP改進的可靠傳輸協議去嘗試,我們調研過SCTP和QUIC,總體來看QUIC的表現是相當不錯的。

同時爲了減少同一條流在兩個數據中心的多個節點間傳輸,我們增加了一個Relay Agent(Node)的部件,使得同一條流在兩個數據中心之間只需要擴散一次。Relay Agent的另一個作用是進行流擴散的時候的路由控制,譬如一個集團公司的很多分支機房並不是BGP的,需要將流匯聚到指定的BGP機房才能更好地向其他地區數據中心擴散。

3.2 Access Node(Agent) Scheduling

在這裏插入圖片描述

在部署了多個接入節點以後,除了通過增加接入節點來擴充系統的scalability,我們還希望能夠利用接入節點的不同地理位置給靠近它的終端用戶做就近接入。以WebRTC Agent爲例,在部署WebRTC Agent的時候可以指定它的capacity(能力),capacity上面有兩個標籤,一個是isp,一個是region。用戶在進行通信連接請求的時候,它帶上isp和region的preference(喜好),系統在進行WebRTC Agent調度的時候會對所有可用的WebRTC Agent的capacity與用戶指定的preference進行匹配,找到最滿意的接入結點,最後達到就近接入的目的。

在符合preference的候選不止一個時,系統還提供基於work load和歷史使用記錄進行last-used、least-used、round-robin、random等調度策略,選取符合指定策略的接入節點。

3.3 CDN alike Service
在這裏插入圖片描述

解決了跨數據中心部署的媒體流擴散和調度問題後,我們的解決方案就可以提供更廣闊的實時多方音視頻通信服務。特別是有了Relay Agent的級聯能力後,我們服務器側系統就可以得到極大的提升,譬如假設單個媒體接入節點的扇出能力是1:1000的話,經過一級級聯後就能達到1:100萬,經過兩級級聯後就能達到1:10億,已經堪比一般CDN的扇出能力了。而CDN的就是本質是一個分佈式的cache系統,cache是實時應用的天敵。許多既要求海量扇出比,又要求實時性,並且要隨時平滑進行流拓撲切換的場景下,CDN就顯得無能爲力了,而我們的解決方案將覆蓋這些場景,特別是在5G和IoT的時代。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章