個人資料
文章分類
正文

WhatsApp 的通話中繼基礎設施

(2024-05-22 12:29:25) 下一個

Source: https://atscaleconference.com/calling-relay-infrastructure-at-whatsapp-scale/?

WhatsApp 曆史和規模
自2015年推出 WhatsApp 的通話功能以來,它的通話中繼基礎架構一直負責在用戶之間高可靠、低延遲地傳輸語音和視頻數據。從一對一語音通話開始,接著是視頻通話,再到群組通話,WhatsApp 的使用量隨著時間呈指數級增長。該應用現在已成為世界上最大的通話產品之一,每天傳輸超過10億次通話。由於規模如此驚人,我們遇到了很少有通話產品會遇到的獨特問題。我們不斷發展中繼架構,以跟上不斷增長的規模和容量需求。


WhatsApp 原則
WhatsApp 建立在隱私、簡單和可靠性這些核心原則之上。
為確保不可被破壞的隱私,WhatsApp 早期就決定對所有通信(包括語音和視頻通話)強製執行端到端加密。這意味著中繼服務器無法訪問流經其中的媒體內容,因此中繼無法對媒體進行升級/降級、轉碼或任何其他修改
為確保簡單性,我們專注於通過聚焦並完善最重要的功能為用戶提供無幹擾體驗。從用戶界麵到服務器架構,一切都遵循這一原則。我們自定義的 WASP(WhatsApp STUN 協議)就是一個例子。用戶設備與中繼服務器通信的標準協議是 TURN。TURN 是一種相當複雜的協議,使用多個臨時端口、無法很好地與防火牆配合使用,並且在分布式架構中無法很好地擴展。WASP 的核心與 TURN 相似,但 WASP 僅使用一個端口進行所有網絡通信,並更多地依賴用戶設備來做出決策和跟蹤連接狀態,這對於中繼服務器故障轉移來說效果很好。
為確保可靠性,我們的目標一直是確保任何人都可以撥打 WhatsApp 通話——無論是在高速網絡上使用最新設備,還是在網絡狀況不佳時使用低端設備。我們希望通話功能可以可靠運行,即使在極端負載時,因為那可能是人們最需要與親朋好友聯係的時候。


什麽是通話中繼?
兩個關鍵的基礎設施可以讓 WhatsApp 用戶進行通話:信令服務和通話中繼服務。
信令服務器協助設置通話的初始過程。當有人撥入時,它負責讓設備響鈴;當用戶接聽時,它負責連接通話。
一旦通話建立,中繼服務在整個通話期間起到維護連接的重要作用。通話中繼在用戶設備之間來回傳輸音頻和視頻數據包。


通話中繼解決了與建立 WhatsApp 通話相關的一些關鍵技術挑戰。


改善網絡延遲和數據包損失問題
最好的通話應當像親自交談一樣對話自然流暢,沒有延遲或中斷。這是我們為每次通話所追求的終極目標。兩個關鍵的技術挑戰會影響通話的臨場感:網絡延遲和數據包損失。
網絡延遲會導致對話滯後,幹擾對話的自然流暢度。延遲還會大大降低通話算法的最優運行,因為它們最終會在過時的信息上運行。
數據包損失會導致視頻凍結、音頻機器人化等問題,嚴重影響通話體驗。


延遲
改善延遲的最佳方式是通過盡可能最短的路徑路由通話——這意味著將中繼服務托管在離終端用戶盡可能近的位置。
為此,我們設計了WhatsApp中繼基礎設施,使其可在Meta在全球各地建立的數千個接入點(PoP)上運行。這些PoP最初是為了服務於Meta的內容交付網絡(CDN),能夠滿足Facebook和Instagram等產品對其提出的大規模需求。


由於這些接入點分布在比數據中心更多的區域,中繼服務距離終端用戶更近,從而降低了WhatsApp通話的延遲。另外,這些接入點集群通過極高質量和專用主幹鏈路互聯。
僅靠近終端用戶是不夠的;我們還必須為每次WhatsApp通話選擇最佳集群。為此,我們對曆史延遲數據應用複雜的定位算法,計算出每次通話的最佳集群。通話過程中,最優集群可能會發生變化——例如,當用戶從WiFi切換到蜂窩網絡時。如果我們檢測到正在進行的通話條件發生顯著變化,我們會重新計算最優集群。


數據包損失
解決數據包損失的最佳方式是防患於未然。大多數數據包損失源於網絡擁塞,而擁塞是由於帶寬使用不當(發送太多數據)造成的,通常是由於不準確地估計網絡鏈路帶寬所致。因此,準確估計帶寬和調節比特率是防止擁塞的關鍵。
然而,帶寬是高度可變的,在通話過程中會發生波動。許多數據包丟失和帶寬問題發生在最後一公裏,比如用戶的WiFi網絡中。中繼服務器協助準確估計每一段通話的帶寬。它通過測量數據包延遲和數據包丟失,並將這些作為反饋共享給用戶設備。快速準確地估計帶寬有助於設備調整比特率,減少網絡擁塞和數據包丟失。
某些網絡無論是否擁塞都會導致數據包丟失。在這種丟包網絡中,中繼服務使用主動數據包丟失緩解技術。其中一種技術稱為NACK(否定確認)。中繼服務器會緩存幾秒鍾的媒體數據包,並響應設備發送的NACK重傳這些數據包。與端到端重傳相比,從中繼服務重傳效率更高,因為中繼位於通話參與者之間的中間位置,減少了重傳的延遲。另外,中繼更有效率,因為它能夠隻在丟包的鏈路上重傳數據包。

最小化設備資源使用

音頻和視頻流數量的增加,尤其是在大型群組通話中,會導致更高的帶寬使用。更糟糕的是,某些國家的移動數據套餐仍然昂貴,我們不能假設用戶即使在WiFi上也有無限的數據流量。此外,編碼/解碼和加密/解密等操作是CPU密集型的,更多的CPU使用意味著更多的電池使用。因此,我們希望節約設備資源,在最大限度延長設備電池壽命的同時,最小化用戶的帶寬使用。

在音頻通話中節省帶寬的一個顯而易見的解決方案是,隻為正在說話的用戶傳輸流。這種解決方案稱為主導說話人檢測

然而,端到端加密使得主導說話人檢測變得更加複雜,因為它阻止了中繼服務檢查音頻內容和確定誰在說話。為解決這個問題,WhatsApp中繼服務器會從通話中的用戶設備請求音量信息。通過僅共享音量信息而不是音頻內容,中繼服務器獲得了足夠的信息來識別主導說話人,同時仍然保護了通話的隱私。

這種解決方案還存在一個額外的挑戰:當新的參與者開始說話時,通常會存在一定延遲,然後主導說話人算法才會比較所有音量水平,中繼才會開始為這個新的發言人轉發音頻。這可能導致他們最初的話語被剪掉。為消除這種延遲,我們允許設備在音量突然增加時覆蓋主導說話人算法。

優化網絡條件

我們希望為用戶提供網絡所能允許的最佳體驗。在這裏我們麵臨的最大技術挑戰往往不是中繼服務所遇到的各種網絡,而是單個通話中網絡條件的不對稱性。

考慮一種情況:一個視頻群組通話,其中有些用戶網絡狀況良好,而另一些用戶網絡狀況不佳。網絡狀況良好的設備傳輸高比特率的視頻流,導致網絡狀況不佳的設備發生擁塞,進而導致它們獲得糟糕的體驗。但由於端到端加密,中繼服務器無法訪問媒體內容,因此無法選擇性地為較差網絡降低視頻質量。

中繼服務器可以指示通話中的所有設備降低其比特率。這將允許網絡狀況較差的用戶參與通話,但網絡狀況良好的設備將接收低分辨率視頻,盡管它們所在的高容量網絡允許獲得更佳體驗。

為解決這個問題,我們使用了一種叫做"視頻模擬發送"的技術。當服務器檢測到通話中用戶網絡質量參差不齊時,它會指示網絡狀況良好的用戶"拆分"他們的流,並發送一路高比特率流和一路低比特率流。然後中繼服務選擇性地將高比特率流轉發給網絡狀況良好的用戶,將低比特率流轉發給網絡狀況較差的用戶。

這種方式允許通話中的所有用戶都獲得最佳體驗,同時仍然保留了端到端加密。

除了這種解決方案,我們還解決了用戶對視頻的不同需求。雖然每個人在通話中都期望聽到相同的音頻,但並非每個人都期望看到相同的視頻。大多數參與者可能希望觀看正在講話的用戶的視頻,而另一些人可能希望在用戶列表中"滾動"瀏覽。因此,服務器需要根據參與者的視頻是否需要,對其"打開"或"關閉"視頻。為實現這一點,我們使用了一種稱為"視頻訂閱"的功能,其中每個參與者都會通知服務器他們感興趣的視頻。結合帶寬估計,這些信息有助於中繼服務器決定哪些用戶應該傳輸視頻以及以何種比特率傳輸。

確保可擴展性、可靠性和可用性

可擴展性

每天服務數十億次通話絕非易事。為實現這種規模,我們不僅在數千個PoP上運行WhatsApp中繼服務,而且在每個PoP內運行數百個容器。

考慮一下單個PoP集群的結構。每個集群運行著數百個中繼容器。單個連接會均衡負載到這些容器上。事實上,同一通話中的多個參與者往往由完全不同的容器提供服務。這有助於我們均勻地在集群的所有容器之間平衡負載,即使單個通話的持續時間和群組大小有所不同

可靠性

沒有什麽比在重要對話的中途通話掉線更讓人沮喪的了。

可靠提供通話服務的一個挑戰是處理計劃內和計劃外的維護事件。當通話運行在數十萬個容器上時,至少服務器的一部分將持續進行某種形式的維護。

計劃內的維護事件(如軟件升級)將重啟容器,而為應對容量變化而進行的集群調整也會使部分容器離線。計劃外事件如斷電或軟件崩潰也可能導致容器重啟或離線。

為處理這些情況,我們專門為中繼服務設計了彈性容錯機製。當一個中繼容器發生故障時,負載均衡器會檢測到並將連接重新分發到健康的容器。新容器將接管故障容器之前在服務的連接。為繼續為那些連接提供服務,新容器需要恢複所有關於這些連接的上下文。這種上下文稱為"通話狀態"。

我們有兩種通話狀態:

關鍵通話狀態,對通話至關重要,包括群組大小和設備網絡地址等參數,沒有這些參數通話將無法運行。新參與者加入通話或參與者從WiFi切換到蜂窩網絡都是會改變關鍵通話狀態的事件示例。

臨時通話狀態,不斷變化,例如帶寬估計和當前哪個參與者正在講話。新參與者開始講話是會改變臨時狀態的事件示例。

我們使用狀態服務器存儲這些狀態,以便其他容器可以檢索。每當關鍵通話狀態發生變化時,都會將其保存到狀態服務器。如果通話狀態丟失,幾乎不可能從容器切換或重啟中恢複過來。

臨時狀態則更加寬容。如果臨時狀態丟失,通話質量可能會暫時下降,但可以很快恢複。臨時狀態可能根本不會保存到狀態服務器,或者隻會不頻繁地檢查點保存。

通過選擇性地存儲哪些狀態以及何時存儲,我們提高了 WhatsApp 通話的可靠性,而不會影響可擴展性。

雖然媒體數據包的轉發可以完全分布式處理,但每次通話都需要做出許多中央決策。一個很好的例子是中繼服務器的"主導說話人檢測",它需要比較通話中所有參與者的音頻音量水平。另一個例子是服務器的"帶寬分配",它需要比較一次通話中參與者的帶寬估計值,並告知設備應以何種比特率傳輸。為做出這些中央決策,我們將中繼服務的網絡層與決策層分離了。網絡層仍然是分布式的,處理媒體數據包的火力流,而決策層針對每次通話集中化,利用來自網絡層的元數據更新做出集中決策。

可用性

有時中繼服務處於極端負載之下,因為許多人正試圖撥打電話。這在體育賽事或自然災害期間很普遍,人們會試圖與親朋好友取得聯係。在那些時候,通話服務必須具有很高的可靠性和可用性,讓用戶在最需要時能夠連接。隻要互聯網可用,我們就希望 WhatsApp 通話對用戶來說是可能的。

WhatsApp 每年都要應對的一個最有趣的"極端事件"就是除夕——在這一天支持通話是 WhatsApp 最獨特的工程經曆之一。這些慶祝活動之所以特別,是因為它們幾乎在世界各地的每個國家都會舉行,而且都會在每個地區的午夜時分開始。隨著每個國家的鍾聲敲響午夜,我們都會看到該地區的通話量出現巨大的峰值。每個峰值剛好在午夜開始、上升非常陡峭,並持續約20分鍾。

由於峰值上升如此之快,一旦觀察到故障,幾乎無法人工采取任何響應措施。在極端高峰期間我們所看到的大部分恢複能力都已融入到中繼架構之中。

為確保可用性,我們會在除夕前幾周做大量規劃工作。我們使用數據科學來預測每個地區的預期流量,並運行性能測試來衡量中繼服務器能夠承載的最大流量。

每年流量模式都會發生變化,這會導致瓶頸位置發生轉移。這些變化可能是無法預測的,從而使預測變得困難。例如,在2022年除夕,我們看到歐洲地區的群組通話數量比往年大幅增加,這給該地區的中繼基礎設施帶來了壓力。

由於中繼服務器處理通話的能力是有物理極限的,我們明確定義了優先級,並采取防禦式運營方式。這裏的主要目標是防止災難性故障,如果中繼服務完全超出容量,則以預定的、漸進式的方式(而非一次性)優雅地失效。

隨著通話量增加和中繼服務接近容量限製,資源如CPU和內存會自動進行監控,並啟動節流。我們的優先級會指導係統按特定順序允許功能失效。例如,正在進行的通話比新通話更重要。我們的係統會限製新通話的建立,以允許基礎設施維護正在進行通話的質量。同樣,一對一通話比群組通話更重要。

我們在確保可用性方麵還麵臨著區域容量的挑戰。由於通話對延遲如此敏感,隻有區域容量才是關鍵。當我們在某個國家遇到通話量峰值時,它會壓垮當地接入點的容量。其他地區的接入點可能還有足夠的剩餘容量,但由於會引入太多額外延遲,因此無法用於中繼通話。我們在這裏的解決方案是將非延遲敏感型的Meta應用程序和流量重新定位到其他地區,從而為諸如 WhatsApp 通話等實時應用程序創建臨時的區域容量。

經驗總結

通過多年來在 WhatsApp 構建這種中繼架構的經驗,我們獲得了關鍵見解,並證明了在不影響通話隱私和質量的前提下,創建一個可擴展到數十億次通話的極其可靠的通話產品是可行的。我們的一些關鍵經驗教訓包括:

中繼架構的簡單性在實現高可靠性、性能和可擴展性方麵起到了至關重要的作用。 每個用戶的最佳體驗都取決於諸如設備和網絡等各種因素,而對於同一通話中的不同參與者,這些因素可能存在顯著差異。
雖然我們為可靠性設計係統,但仍會存在組件可能發生故障的情況。我們需要設計係統以可預測的方式失效,從而防止災難性故障。 在解決每一個技術挑戰和構建每一個解決方案時,將用戶需求放在核心位置是非常重要的。

[ 打印 ]
閱讀 ()評論 (0)
評論
目前還沒有任何評論
登錄後才可評論.