Es gibt zwei Schwierigkeiten bei der Bereitstellung von Medienservern für WebRTC: Skalierung, d. H. über die Verwendung eines Servers hinaus und Optimierung der Verzögerungen für alle Konferenzbenutzer. Während einfaches Sharding im Sinne von "Alle Benutzer der X-Konferenz an Server Y senden" leicht horizontal skaliert werden kann, ist es in Bezug auf Verzögerungen alles andere als optimal. Die Verteilung der Konferenz auf Server, die nicht nur in der Nähe der Benutzer, sondern auch miteinander verbunden sind, klingt nach einer Lösung für beide Probleme. Heute haben wir eine Übersetzung von detailliertem Material von Boris Grozev aus Jitsi vorbereitet: Probleme der Kaskadierung von SFUs mit einer Beschreibung des Ansatzes und einiger Schwierigkeiten sowie Implementierungsdetails. Es ist erwähnenswert, dass Voximplant-Konferenzen
auch SFU verwenden . Wir arbeiten derzeit an der Kaskadierung der SFU, die nächstes Jahr auf unserer Plattform erscheinen soll.
Mausneuronen. NIHD- Bild ( CC-BY-2.0 )Echtzeitkommunikation reagiert sehr empfindlich auf das Netzwerk: Bandbreite, Latenz und Paketverlust. Eine Verringerung der Bitrate führt zu einer Verringerung der Videoqualität, eine lange Netzwerkverzögerung führt zu einer langen Verzögerung für Endbenutzer. Der Verlust von Paketen kann dazu führen, dass der Ton unterbrochen wird und das Video einfriert (aufgrund von Bildsprüngen).
Daher ist es für die Konferenz sehr wichtig, die optimale Route zwischen den Endgeräten / Benutzern zu wählen. Wenn nur zwei Benutzer vorhanden sind, ist dies ganz einfach: WebRTC verwendet
das ICE-Protokoll , um eine Verbindung zwischen den Teilnehmern herzustellen. Wenn möglich, stellen die Teilnehmer eine direkte Verbindung her, andernfalls wird ein TURN-Server verwendet. WebRTC kann einen Domänennamen auflösen, um die Adresse eines TURN-Servers abzurufen, sodass Sie einfach eine lokale TURN basierend auf DNS auswählen können, z. B. mithilfe der
AWS Route53- Eigenschaften.
Wenn jedoch das Routing mehrerer Teilnehmer über einen zentralen Medienserver erfolgt, wird die Situation kompliziert. Viele WebRTC-Dienste verwenden Selective Forwarding Units (SFUs), um Audio und Video zwischen drei oder mehr Teilnehmern effizienter zu übertragen.
Problem mit einem Stern
In der Sterntopologie stellen alle Teilnehmer eine Verbindung zu einem einzelnen Server her, über den sie Medienströme austauschen. Offensichtlich ist die Wahl des Serverstandorts von großer Bedeutung: Wenn sich alle Teilnehmer in den USA befinden, ist die Verwendung eines Servers in Sydney keine gute Idee.
Viele Dienste verwenden einen einfachen Ansatz, der in den meisten Fällen gut funktioniert: Sie wählen einen Server, der näher am ersten Konferenzteilnehmer liegt. Es gibt jedoch Zeiten, in denen diese Lösung nicht optimal ist. Stellen Sie sich vor, wir haben drei Teilnehmer aus dem obigen Bild. Wenn ein Australier (Anrufer C) als erster an der Konferenz teilnimmt, wählt der Algorithmus einen Server in Australien aus, jedoch ist Server 1 in den USA die beste Wahl, da Er ist den meisten Teilnehmern näher.
Das beschriebene Szenario ist nicht sehr häufig, tritt jedoch auf. Wenn wir davon ausgehen, dass der Benutzer in zufälliger Reihenfolge verbunden ist, tritt die beschriebene Situation bei ⅓ aller Konferenzen mit 3 Teilnehmern auf, von denen eine sehr gelöscht ist.
Ein weiteres und häufigeres Szenario: Wir haben zwei Teilnehmergruppen an verschiedenen Standorten. In diesem Fall ist die Verbindungsreihenfolge unwichtig. Wir haben immer eine Gruppe eng anliegender Teilnehmer, die gezwungen sind, Medien mit einem Remote-Server auszutauschen. Zum Beispiel 2 Teilnehmer aus Australien (C & D) und 2 aus den USA (A & B).
Der Wechsel zu Server 1 ist für C & D-Mitglieder nicht optimal. Server 2 ist für A & B nicht optimal. Das heißt, unabhängig davon, welcher Server verwendet wird, sind immer Teilnehmer mit dem Remote-Server (= nicht optimal) verbunden.
Aber wenn wir kein einziges Serverlimit hätten? Wir könnten jeden Teilnehmer mit dem nächsten Server verbinden, es würde nur bleiben, um diese Server zu verbinden.
Lösung: Kaskadierung
Wir verschieben die Frage, wie die Server verbunden werden sollen. Lassen Sie uns zuerst sehen, wie sich das auswirken wird.
Die SFU-Verbindung zwischen C und D hat sich nicht geändert - Server 2 wird weiterhin verwendet. Server 1 wird für die Teilnehmer A und B verwendet, und dies ist offensichtlich besser. Das Interessanteste ist die Verbindung zwischen beispielsweise A und C: Anstelle von A <=> Server 2 <=> C wird die Route A <=> Server 1 <=> Server 2 <=> C verwendet.
Implizite Auswirkung auf den Wechselkurs
Der SFU-Mix hat Vor- und Nachteile. Einerseits wird in der beschriebenen Situation die Austauschzeit zwischen Teilnehmern länger, wenn neue Sprünge im Netzwerk hinzugefügt werden. Andererseits nimmt diese Zeit ab, wenn wir über die Verbindung „Client“ - „erster Server“ sprechen, da wir den Medienstrom mit einer geringeren Verzögerung nach dem Hop-by-Hop-Prinzip wiederherstellen können.
Wie funktioniert es WebRTC verwendet RTP (normalerweise über UDP) zum Übertragen von Medien. Dies bedeutet, dass der Transport unzuverlässig ist. Wenn ein UDP-Paket verloren geht, können Sie den Verlust ignorieren oder eine erneute Übertragung (Neuübertragung) mithilfe des
RTCP-NACK- Pakets
anfordern. Die Auswahl liegt bereits im Gewissen der Anwendung. Beispielsweise kann eine Anwendung den Verlust von Audiopaketen ignorieren und die erneute Übertragung einiger (aber nicht aller) Videopakete anfordern, je nachdem, ob sie zum Decodieren nachfolgender Frames benötigt werden oder nicht.
Neuübertragung von RTP-Paketen, einzelner ServerBei einer Kaskadierung kann die erneute Übertragung auf den lokalen Server beschränkt sein, dh an jedem einzelnen Standort durchgeführt werden. Wenn beispielsweise auf der Route A-S1-S2-C ein Paket zwischen A und S1 verloren geht, bemerkt S1 dies und fordert eine erneute Übertragung an. Ähnlich wie beim Verlust zwischen S2 und C. Und selbst wenn das Paket zwischen Servern verloren geht, kann die empfangende Seite auch eine erneute Übertragung anfordern.
RTP-Paket-Neuübertragung, zwei Server. Beachten Sie, dass Server 2 Paket 2 nicht anfordert, da NACK kurz nach dem Senden des Pakets eingetroffen ist.Der Client verwendet einen Jitterpuffer, um die Videowiedergabe zu verzögern und verzögerte / erneut übertragene Pakete zu empfangen. Die Puffergröße ändert sich dynamisch in Abhängigkeit von der Austauschzeit zwischen den Parteien. Wenn Hop-by-Hop-Neuübertragungen auftreten, nimmt die Verzögerung ab, und infolgedessen kann der Puffer kleiner sein - infolgedessen nimmt auch die Gesamtverzögerung ab.
Kurz gesagt: Selbst wenn die Austauschzeit zwischen den Teilnehmern höher ist, kann dies zu einer Verringerung der Verzögerung bei der Übertragung von Medien zwischen den Teilnehmern führen. Diesen Effekt müssen wir in der Praxis noch untersuchen.
Einführung in kaskadierende SFUs: Jitsi Meet Case
Alarm vs. Medien
Werfen wir einen Blick auf den Alarm. Jitsi Meet teilte von Anfang an das Konzept eines Signalisierungsservers (
Jicofo ) und eines Medienservers / einer SFU. Dies ermöglichte die Einführung einer Kaskadenunterstützung ist relativ einfach. Erstens könnten wir die gesamte Signalisierungslogik an einem Ort handhaben; Zweitens hatten wir bereits ein Signalisierungsprotokoll zwischen Jicofo und dem Medienserver. Wir mussten die Funktionalität nur ein wenig erweitern: Wir haben bereits mehrere SFUs unterstützt, die mit einem Signalisierungsserver verbunden sind. Wir mussten die Fähigkeit einer SFU hinzufügen, eine Verbindung zu vielen Signalisierungsservern herzustellen.
Als Ergebnis wurden zwei unabhängige Serverpools angezeigt: einer für Jicofo-Instanzen, der andere für Medienserverinstanzen (siehe Abbildung):
Ein Beispiel für die Organisation von Servern in AWS mit der Möglichkeit einer Kaskade zwischen verschiedenen Rechenzentren.Der zweite Teil des Systems ist die Bridge-to-Bridge-Kommunikation. Wir wollten diesen Teil so einfach wie möglich gestalten, damit es keine komplizierten Signale zwischen den Brücken gibt. Alle Alarme gehen zwischen jicofo und jitsi-videobridge; Die Bridge-Verbindung wird nur für Audio- / Video- und Datenverbindungsnachrichten verwendet.
Octo-Protokoll
Um diese Interaktion zu verwalten, haben wir das Octo-Protokoll verwendet, das RTP-Pakete in einfache Header fester Länge einschließt und Ihnen auch das Senden von Textnachrichten ermöglicht. In der aktuellen Implementierung sind die Brücken durch eine Vollmaschentopologie (Vollnetz) verbunden, es sind jedoch auch andere Topologien möglich. Verwenden Sie beispielsweise einen zentralen Server (Stern für Brücken) oder eine Baumstruktur für jede Brücke.
Erläuterung: Anstatt es in einen Octo-Header einzuschließen, können Sie die RTP-Header-Erweiterung verwenden, mit der Bridges auf reinem (S) RTP zwischen Bridges ausgeführt werden. Zukünftige Versionen von Octo können diesen Ansatz verwenden.
Zweite Erklärung: Octo bedeutet nichts. Zuerst wollten wir einen zentralen Server verwenden, der uns an einen Tintenfisch erinnerte. So erschien der Name für das Projekt.
Octo-Header-FormatIn der Jitsi-Terminologie verfügt eine Bridge, wenn sie Teil einer Konferenz mit mehreren Bridges ist, über einen zusätzlichen Octo-Kanal (tatsächlich einen Kanal für Audio und einen für Video). Dieser Kanal ist für das Senden / Empfangen von Medien zu / von anderen Bridges verantwortlich. Jeder Bridge wird ein freier Port für Octo zugewiesen (standardmäßig 4096). Daher benötigen wir das Feld Konferenz-ID, um mehrere Konferenzen abwickeln zu können.
Derzeit sind im Protokoll keine Sicherheitsmechanismen integriert, und wir delegieren diese Verantwortung an die unteren Ebenen. Dies ist das Nächste, was wir in naher Zukunft tun werden. Derzeit sollten sich die Bridges jedoch in einem sicheren Netzwerk befinden (z. B. einer separaten AWS VPC-Instanz).
Simulcast
Mit Simulcast kann jeder Teilnehmer mehrere Medienströme mit unterschiedlichen Bitraten senden, während die Bridge dabei hilft, festzustellen, welche benötigt werden. Damit dies korrekt funktioniert, übertragen wir alle Simulcast-Streams zwischen den Brücken. Dank dessen können Sie schnell zwischen Streams wechseln, da die lokale Bridge keinen neuen Stream anfordern muss. Dies ist jedoch unter dem Gesichtspunkt des Verkehrs von Brücke zu Brücke nicht optimal, da Einige Threads werden selten verwendet und laden nur die Bandbreite ohne Zweck.
Aktive Mitgliederauswahl
Wir wollten auch die Möglichkeit haben, einen aktiven Teilnehmer / Sprecher der Konferenz zu abonnieren. Es stellte sich als einfach heraus - wir haben jeder Brücke beigebracht, den Hauptteilnehmer unabhängig zu bestimmen und dann unsere lokalen Kunden zu benachrichtigen. Dies bedeutet, dass die Ermittlung mehrmals erfolgt, jedoch nicht kostspielig ist und Sie einige Punkte vereinfachen können (z. B. müssen Sie nicht entscheiden, welche Bridge für
DSI verantwortlich sein soll, und sich um das Weiterleiten von Nachrichten kümmern).
Brückenauswahl
In der aktuellen Implementierung ist dieser Algorithmus einfach. Wenn ein neuer Teilnehmer an der Konferenz teilnimmt, muss Jicofo bestimmen, welche Brücke ihm zugewiesen werden soll. Dies erfolgt basierend auf der Region des Teilnehmers und der Überlastung der Brücken. Wenn es in derselben Region eine freie Brücke gibt, wird sie ernannt. Andernfalls wird eine andere Brücke verwendet.
Weitere Informationen zu Octo finden Sie in der
Dokumentation .
Erweitern Sie die kaskadierende SFU
Für die Bereitstellung haben wir Computer in Amazon AWS verwendet. Wir hatten Server (Alarme und Medien) in 6 Regionen:
- us-east-1 (North Virginia);
- us-west-2 (Oregon);
- eu-west-1 (Irland);
- eu-central-1 (Frankfurt);
- ap-se-1 (Singapur);
- ap-se-2 (Sydney).
Wir haben
georeferenzierte HAProxy- Instanzen verwendet, um die Mitgliedsregion zu bestimmen. Die Domäne meet.jit.si wird von
Route53 verwaltet und in die HAProxy-Instanz aufgelöst, die die Region zu den HTTP-Headern der gesendeten Anforderung hinzufügt. Der Header wird später als Wert der Variablen
config.deploymentInfo.userRegion
, die dank der Datei
/config.js
auf dem Client
/config.js
ist.
Die Jitsi-Oberfläche zeigt an, wie viele Bridges verwendet werden und an welche spezifischen Benutzer angeschlossen sind - zu Diagnose- und Demonstrationszwecken. Wenn Sie den Mauszeiger über die obere linke Ecke des lokalen Videos bewegen, werden die Gesamtzahl der Server und der Server angezeigt, mit dem Sie verbunden sind. Ebenso können Sie die Parameter des zweiten Teilnehmers sehen. Sie sehen auch die Austauschzeit zwischen Ihrem Browser und dem Browser des Gesprächspartners (Parameter E2E RTT).
Indem Sie sehen, wer mit welchem Server verbunden ist, können Sie sehen, ob Kaskadierung verwendet wird.Fazit
Octo erschien ursprünglich als A / B-Test. Die ersten Ergebnisse waren gut, so dass Octo jetzt für alle verfügbar ist. Es ist immer noch viel Verkehr zu passieren und die Leistung genauer zu betrachten. Es ist auch geplant, diese Entwicklungen zu nutzen, um noch größere Konferenzen zu unterstützen (wenn eine SFU nicht mehr ausreicht).