網易雲信線上萬人連麥技術大揭祕

語言: CN / TW / HK

首圖.jpg

技術系列課回顧 | 網易雲信線上萬人連麥技術大揭祕

本文根據網易雲信資深音視訊服務端開發工程師陳策在《MCtalk Live#5:網易雲信線上萬人連麥技術大揭祕》線上直播分享整理。

導讀

大家好,我是來自網易雲信的陳策。連麥作為一個強互動場景,單房間內的高併發一直是個比較複雜的問題。這次給大家分享網易雲信在萬人連麥這個場景上的探索和實踐。

比較典型的萬人連麥需求場景有視訊會議研討會、低延遲直播、線上教育大班課、類 Club House(多人語聊房)等。對於萬人連麥的需求場景市面上普遍的解決方案是“RTC+CDN”的方式,即限制上麥主播人數在小規模(50人左右)進行 RTC 互動,然後轉推到 CDN,大規模的觀眾再通過 CDN 直播拉流的方式實現。這種解決方案在業務上限制了上麥人數,並且觀眾和主播之間有較大的聲畫延遲,無法滿足雲信的業務要求。例如,在遊戲語音場景中,會有大量的使用者開公麥,需要做到所有人都可以上麥,並且上麥人數不限制。那麼,網易雲信是如何解決這個問題的呢,本文將和大家分享我們在這個問題上的探索。

信令的技術難點

信令併發、弱網和高可用問題

我們在這個問題的探討分為幾個方面:信令、音訊技術、視訊技術以及伺服器間的網路傳輸,先來看看信令的實現。

RTC 是使用長連線進行雙向通知的。假設某個語聊房主播有一萬人,那麼只要其中某一個主播上/下麥或者加入/離開房間,都會觸發對其它 9999 人的信令通知。這種隨機的使用者行為會讓伺服器瞬時壓力非常大。

傳統的中心化單點伺服器顯然是支撐不了萬人房間這麼大併發的,必須使用分散式架構來分散壓力。假如一個萬人房間分佈在多臺伺服器上,那麼伺服器之間還要實時同步 Nx(N-1) 的使用者狀態和釋出訂閱關係,同時為了實現高可用,還需要支援某臺伺服器崩潰重啟後的資料同步。

另一方面,媒體伺服器一般會做成分散式網狀架構來降低點對點的延遲。但如果信令伺服器也保持每一個節點都平等的網狀架構,那麼每一個節點都要維護全量的級聯關係。這其中錯綜複雜的訊息同步性問題將會極難維護。

網易雲信分散式樹狀架構

為了實現高併發和高可用,結合信令都是在房間內部傳遞,房間之間不會有信令互動這一業務特點,我們將信令伺服器設計成分散式樹狀架構,每個房間是一顆獨立的樹,如下圖:

  • 根節點:房間管理伺服器,管理和儲存所有的使用者狀態和訂閱關係。
  • 子節點:作為邊緣伺服器,負責使用者就近接入。

這種樹狀架構可以有效分散各節點的廣播壓力。根節點會盡量根據就近使用者的原則進行分配,避免其與子節點之間鏈路過長,同時子節點儘量只充當訊息 proxy,不參與業務,把業務集中到根節點上,從而避免信令的同步亂序等問題。

根節點使用快取加資料庫來保證業務資料儲存的效能和可靠性。子節點由於不涉及使用者業務狀態,在崩潰重啟後,只需要客戶端信令的長連線重連,不用進行類似重新加入房間的操作,做到對使用者無感知。在遇到子節點宕機的情況下,則會依靠客戶端的超時機制,重新請求排程。通過這一系列手段,實現服務的高可用。

信令弱網問題

在RTC架構中,由於信令非常多且互動複雜,一般採用信令和媒體通道分離的策略。但這會引入一個問題,就是兩者的抗弱網能力不一致。媒體一般使用Udp傳輸,很容易做到在30%丟包下依然能流暢觀看。但信令一般使用Tcp傳輸,30%丟包下信令就基本不可用了。

為了解決這個問題,我們使用Quic作為信令加速通道,來保證信令媒體的弱網對抗能力一致性。同時在Quic連不通時(可能存在使用者網路對某些Udp埠不友好),也能退避到Websocket,以此來保證信令在弱網下的高可用。

音訊的技術難點

混音和選路的缺陷

在多人連麥場景中,最複雜的就是多個使用者同時說話場景下的音訊併發問題。

假設萬人房間中每個主播都上麥,由於語音的特性,每個主播理論上都要訂閱其它所有人(視訊可以按需訂閱,但音訊理論上應該全訂閱)。如果每個客戶端都訂閱 N-1(9999) 路流,不僅僅是流量的浪費,客戶端也支援不了如此多的下行,而且在現實場景中,只要超過 3 個人同時說話,其他人基本上就聽不清楚內容了。

解決這個問題的方法一般有音訊選路和服務端混音兩種。但在萬人房間的場景下這兩種解決方案都有所缺陷:

  • 音訊選路是在 N 路音訊中選擇音量最大的幾路進行下發(一般 2~3 路)。這個方案確實能夠解決上述問題,但它有一個前置條件:與客戶端直連的邊緣伺服器上必須彙集全量的音訊流,這樣才能選路。所以,即使是 48 核的伺服器,也難以支援萬路併發。
  • 服務端混音是解碼 N 路混成1路,或者選路之後再解碼3路混成1路。前者的問題主要是MCU 伺服器很難頂住這麼大的轉碼壓力,而且耗時過長。後者還是會有上述音訊選路的缺陷。其實MCU最大的缺點是單點問題,崩潰後會影響全量的使用者,很容易成為系統瓶頸。

網易雲信的分散式選路

為了解決音訊的上述問題,我們採用了在伺服器級聯之前預選路的方案。假設一個萬人房間平均分佈在 20 臺邊緣伺服器上,每臺伺服器有 500 路上行流,如果不使用級聯預選路,那麼每臺伺服器互相級聯後,都需要拉全量的 10000 路流才能供下行選路使用。

當我們使用級聯預選路方案後(預設 3路),每臺伺服器只需要拉  3x(20-1) 路流就可以,之後再從本機的 500 路流加上級聯的 3x(20-1) 路流中進行二次選路,選出最終音量最大的3路流下發給客戶端。通過這種方式,實現音訊的全訂閱。假設在 M 臺伺服器上傳輸 N 路音訊流,伺服器傳輸資料量的數量級就從 N^2 下降到 M^2。

視訊的技術難點

Simulcast/Svc 和位元速率壓制在大房間的侷限

由於客戶端效能限制,一般能同時解碼渲染的視訊流路數不會太多,可以通過“被訂閱才發流”這種方式來規避上述媒體併發問題。

萬人房間的視訊技術難點主要在於 QoS,RTC 中服務端的 QoS 手段主要有兩個:

  • 利用 Simulcast/Svc 切流
  • 通過 RTCP 壓制傳送端編碼位元速率

Simulcast 和 Svc 的本質是將使用者的下行頻寬分層在分發對應的流,但在萬人房間中,使用者頻寬往往分佈很散,機械的分層並不能讓大多數使用者都有最好的體驗。RTCP 位元速率壓制是根據接收端頻寬反饋給傳送端的編碼器,編出最適合的位元速率,其最適用的場景是 1v1,在萬人房間中會很難決策。

網易雲信 QoS 策略

為了讓儘可能多的使用者都獲得匹配其網路的視訊流,我們制定瞭如下的 QoS 策略:首先我們會根據下行頻寬將使用者從高到低分為4個層級,傳送端同時使用 Simulcast+Svc 編碼,例如720p/30fps,720p/15fps,720p/8fps,180p/30fps,伺服器根據使用者層級為其分配對應的資料流。

這種方法的優點是能夠實現每一個使用者都能匹配對應其頻寬的視訊流,但有一個顯而易見的缺點,就是分配不夠平均。比如一個萬人房間中,大部分使用者的頻寬都命中 720p/15fps 這一層,其它少量使用者分散在另外三層上,那麼實際上這個房間大多數使用者的視訊體驗都不是最佳。

為了解決這個問題,還需要在分層編碼的基礎上再結合位元速率壓制:首先將使用者的頻寬按照從高到低排序,取 topN% 使用者的最低頻寬反饋給傳送端,指導最高層級 (720p/30fps) 的編碼位元速率,以此讓 topN% 的使用者都能命中體驗最好的資料流。N 可以使用者設定,也可以根據房間內使用者的下行頻寬情況動態變化。

下圖以 Top60% 舉例:

還有一種場景是當用戶上行頻寬不足時,假設只有 1.2M,根本無法實現 Simulcast+Svc。這種情況下,我們會讓客戶端只編碼一路 720p 的單流,然後在房間中引入一個 MCU,將單流轉發給它,MCU 在轉碼時再使用 Simulcast+Svc,並回推給 SFU,以此來匹配我們的下行 QoS 策略。

伺服器之間網路傳輸的技術難點

跨運營商和跨國傳輸

實際開發的過程中,我們還遇到了一些伺服器之間網路傳輸問題,這裡也和大家分享一下。

比如為了減少最後一公里距離,我們會使用一些單線機房作為邊緣節點,不同運營商的單線機房如果直接級聯,他們的網路傳輸很明顯是不可控的。想要從架構層面解決這個問題,就必須在級聯網路中再引入一個三線/BGP 機房作為中轉,而這又要考慮中轉伺服器的節點位置分配和單點崩潰問題,這樣無疑大大增加了排程的複雜性。

另一種情況是跨國場景下的機器級聯,伺服器之間的公網路由不一定是最優,抖動也可能非常大,中間一公里的網路完全不可控。

WE-CAN

為了解決類似問題,我們將伺服器之間的傳輸模組抽象出來,引入了自己的公網基建,大規模分散式實時傳輸網:WE-CAN(Communications Acceleration Network)。在全球主要地區都部署節點,節點之間不斷探測網路質量並上報,中心決策模組收到上報後綜合運營商,實時網路質量,頻寬成本等資訊後計算任意兩個節點之間的最短路徑並生成路由表,再下發給各個節點作為下一跳的路由參考。WE-CAN 跟業務無關,完全是傳輸層解決方案。通過這種方式,媒體級聯只需要在包頭打上目標地址,再投遞給 WE-CAN,完全不需要考慮業務之外的傳輸問題。

總結

以上技術方案就是本次分享的全部內容,通過雲信的萬人連麥技術,將服務升級為無狀態,不需要限制房間最大人數和同時上麥人數,並且支援水平彈性擴容,輕鬆應對突發流量,秒級匹配使用者網路。

當然任何系統的搭建都不是一蹴而就的,其中每一個點,我們都是踩坑無數。網易雲信也將繼續打磨音視訊技術,給行業帶來更好的服務。

作者介紹

陳策,網易雲信資深音視訊服務端開發工程師,負責雲信全球 RTC 網路的搭建和擔任核心開發,在媒體資料傳輸和 RTC 全棧架構設計方面有豐富的經驗。