SFU en cascade: amélioration de l'évolutivité et de la qualité des médias dans les applications WebRTC

Le déploiement de serveurs multimédias pour WebRTC présente deux difficultés: la mise à l'échelle, c'est-à-dire aller au-delà de l'utilisation d'un seul serveur et optimiser les délais pour tous les utilisateurs de la conférence. Si le simple sharding dans l'esprit «envoyer tous les utilisateurs de la conférence X au serveur Y» évolue facilement horizontalement, il est loin d'être optimal en termes de délais. La distribution de la conférence entre des serveurs non seulement proches des utilisateurs, mais également interconnectés - sonne comme une solution aux deux problèmes. Aujourd'hui, nous avons préparé une traduction de matériel détaillé de Boris Grozev de Jitsi: problèmes de SFU en cascade, avec une description de l'approche et quelques difficultés, ainsi que des détails de mise en œuvre. Il vaut la peine de dire que les conférences Voximplant utilisent également SFU ; Nous travaillons actuellement sur la mise en cascade de SFU, qui devrait apparaître sur notre plateforme l'année prochaine.


Neurones de souris. Image NIHD ( CC-BY-2.0 )

Les communications en temps réel sont très sensibles au réseau: bande passante, latence et perte de paquets. Une diminution du débit binaire entraîne une diminution de la qualité vidéo, un long délai de réseau entraîne un long délai pour les utilisateurs finaux. La perte de paquets peut rendre le son intermittent et entraîner des gels sur la vidéo (en raison du saut d'image).

Par conséquent, il est très important pour la conférence de choisir l'itinéraire optimal entre les appareils / utilisateurs finaux. Lorsqu'il n'y a que deux utilisateurs, c'est facile - WebRTC utilise le protocole ICE pour établir une connexion entre les participants. Si possible, les participants se connectent directement, sinon un serveur TURN est utilisé. WebRTC peut résoudre un nom de domaine pour obtenir l'adresse d'un serveur TURN, vous pouvez donc facilement sélectionner un TURN local basé sur DNS, par exemple, en utilisant les propriétés AWS Route53 .

Cependant, lorsque le routage de plusieurs participants s'effectue via un serveur multimédia central, la situation devient compliquée. De nombreux services WebRTC utilisent des unités de transfert sélectif (SFU) pour transférer plus efficacement l'audio et la vidéo entre 3 participants ou plus.

Problème avec une étoile


Dans la topologie en étoile, tous les participants se connectent à un seul serveur via lequel ils échangent des flux multimédias. De toute évidence, le choix de l'emplacement du serveur est d'une grande importance: si tous les participants sont situés aux États-Unis, l'utilisation d'un serveur à Sydney n'est pas une bonne idée.


De nombreux services utilisent une approche simple qui fonctionne bien dans la plupart des cas: ils choisissent un serveur plus proche du premier participant à la conférence. Cependant, il y a des moments où cette solution n'est pas optimale. Imaginez que nous avons trois participants sur la photo ci-dessus. Si un Australien (appelant C) est le premier à rejoindre la conférence, l'algorithme choisira un serveur en Australie, mais le serveur 1 aux États-Unis sera le meilleur choix, car il est plus proche de la plupart des participants.

Le scénario décrit n'est pas très fréquent, mais il se produit. Si nous supposons que l'utilisateur est connecté dans un ordre aléatoire, la situation décrite se produit avec ⅓ de toutes les conférences avec 3 participants, dont l'une est très supprimée.

Autre scénario plus fréquent: nous avons deux groupes de participants dans des endroits différents. Dans ce cas, l'ordre de connexion est sans importance, nous aurons toujours un groupe de participants proches qui sont obligés d'échanger des médias avec un serveur distant. Par exemple, 2 participants d'Australie (C&D) et 2 des États-Unis (A&B).


Le passage au serveur 1 ne sera pas optimal pour les membres C&D. Le serveur 2 n'est pas optimal pour A&B. Autrement dit, quel que soit le serveur utilisé, il y aura toujours des participants connectés au serveur distant (= non optimal).

Mais si nous n'avions pas de limite de serveur unique? On pourrait connecter chaque participant au serveur le plus proche, il ne resterait plus qu'à connecter ces serveurs.

Solution: en cascade


Nous reportons la question de la connexion des serveurs; Voyons d'abord quel sera l'effet.


La connexion SFU entre C et D n'a pas changé - le serveur 2 est toujours utilisé. Le serveur 1 est utilisé pour les participants A et B, et c'est évidemment mieux. La chose la plus intéressante est la connexion entre, par exemple, A et C: au lieu de A <=> Server 2 <=> C, la route A <=> Server 1 <=> Server 2 <=> C est utilisée.

Effet implicite sur le taux de change


Le mélange SFU a ses avantages et ses inconvénients. D'une part, dans la situation décrite, le temps d'échange entre les participants devient plus long lorsque de nouveaux sauts sur le réseau sont ajoutés. D'un autre côté, il y a une diminution de ce temps lorsque nous parlons de la connexion «client» - «premier serveur», car nous pouvons restaurer le flux multimédia avec un délai inférieur sur le principe du saut par saut.

Comment ça marche? WebRTC utilise RTP (généralement via UDP) pour transmettre des médias. Cela signifie que le transport n'est pas fiable. Lorsqu'un paquet UDP est perdu, vous pouvez ignorer la perte ou demander un nouvel envoi (retransmission) à l'aide du paquet RTCP NACK - le choix est déjà sur la conscience de l'application. Par exemple, une application peut ignorer la perte de paquets audio et demander la retransmission de certains (mais pas tous) des paquets vidéo, selon qu'ils sont nécessaires pour décoder les trames suivantes ou non.


Retransmission de paquets RTP, serveur unique

En cas de cascade, la retransmission peut être limitée au serveur local, c'est-à-dire effectué sur chaque site individuel. Par exemple, dans la route A-S1-S2-C, si un paquet est perdu entre A et S1, alors S1 le remarquera et demandera une retransmission; similaire à la perte entre S2 et C. Et même si le paquet est perdu entre les serveurs, le côté récepteur peut également demander une retransmission.


Retransmission de paquets RTP, deux serveurs. Notez que le serveur 2 ne demande pas le paquet 2, car NACK est arrivé peu de temps après l'envoi du paquet.

Le client utilise un tampon de gigue pour retarder la lecture vidéo et parvient à recevoir des paquets retardés / retransmis. La taille de la mémoire tampon change dynamiquement en fonction du temps d'échange entre les parties. Lorsque des retransmissions bond par bond se produisent, le retard diminue et, par conséquent, le tampon peut être plus petit - en conséquence, le retard global diminue également.

En bref: même si le temps d'échange entre les participants est plus élevé, cela peut conduire à une diminution du délai de transfert des supports entre les participants. Nous n'avons pas encore étudié cet effet dans la pratique.

Présentation des SFU en cascade: Jitsi Meet Case


Alarme vs Médias


Jetons un coup d'œil à l'alarme. Dès le début, Jitsi Meet a partagé le concept d'un serveur de signalisation ( Jicofo ) et d'un serveur multimédia / SFU. Cela a permis l'introduction du support en cascade est relativement simple. Premièrement, nous pourrions gérer toute la logique de signalisation en un seul endroit; deuxièmement, nous avions déjà un protocole de signalisation entre Jicofo et le serveur multimédia. Nous n'avions besoin que d'étendre un peu la fonctionnalité: nous prenions déjà en charge plusieurs SFU connectées à un serveur de signalisation, nous devions ajouter la capacité d'une SFU à se connecter à de nombreux serveurs de signalisation.

En conséquence, deux pools de serveurs indépendants sont apparus: l'un pour les instances jicofo, l'autre pour les instances de serveur de médias, voir le diagramme:


Un exemple d'organisation de serveurs sur AWS avec la possibilité d'une cascade entre différents centres de données.

La deuxième partie du système est la communication de pont à pont. Nous voulions rendre cette partie aussi simple que possible, donc il n'y a pas de signalisation compliquée entre les ponts. Toute alarme va entre jicofo et jitsi-videobridge; La connexion en pont est utilisée uniquement pour les messages audio / vidéo et de liaison de données.

Protocole Octo


Pour gérer cette interaction, nous avons pris le protocole Octo, qui encapsule les paquets RTP dans des en-têtes simples de longueur fixe, et vous permet également d'envoyer des messages texte. Dans l'implémentation actuelle, les ponts sont connectés par une topologie entièrement maillée (full mesh), mais d'autres topologies sont également possibles. Par exemple, utilisez un serveur central (étoile pour les ponts) ou une arborescence pour chaque pont.

Explication: Au lieu de l'envelopper dans un en-tête Octo, vous pouvez utiliser l'extension d'en-tête RTP, qui effectuera des flux entre les ponts sur du RTP pur (S). Les futures versions d'Octo pourront utiliser cette approche.

Deuxième explication: Octo ne veut rien dire. Au début, nous voulions utiliser un serveur central, et cela nous rappelait une pieuvre. Le nom du projet est donc apparu.

Format d'en-tête octo

Dans la terminologie Jitsi, lorsqu'un pont fait partie d'une conférence avec plusieurs ponts, il dispose d'un canal Octo supplémentaire (en fait, un canal pour l'audio et un pour la vidéo). Cette chaîne est chargée d'envoyer / recevoir des médias vers / depuis d'autres ponts. Chaque pont se voit attribuer un port libre pour Octo (4096 par défaut), nous avons donc besoin du champ ID de conférence pour gérer plusieurs conférences.

Pour le moment, le protocole n'a pas de mécanismes de sécurité intégrés et nous déléguons cette responsabilité aux niveaux inférieurs. C'est la chose la plus proche que nous ferons dans un avenir proche, mais pour l'instant les ponts devraient être dans un réseau sécurisé (par exemple, une instance AWS VPC distincte).

Simulcast


La diffusion simultanée permet à chaque participant d'envoyer plusieurs flux multimédias avec différents débits, tandis que le pont aide à déterminer ceux qui sont nécessaires. Pour que cela fonctionne correctement, nous transférons tous les flux de diffusion simultanée entre les ponts. Grâce à cela, vous pouvez basculer rapidement entre les flux, car le pont local n'a pas besoin de demander un nouveau flux. Cependant, ce n'est pas optimal du point de vue du trafic de pont à pont, car certains threads sont rarement utilisés et ne chargent la bande passante que pour rien.

Sélection active des membres


Nous voulions également avoir la possibilité de souscrire à un participant / orateur actif de la conférence. Cela s'est avéré simple - nous avons appris à chaque pont à déterminer indépendamment le participant principal, puis à informer nos clients locaux. Cela signifie que la détermination se produit plusieurs fois, mais elle n'est pas coûteuse et vous permet de simplifier certains points (par exemple, vous n'avez pas besoin de décider quel pont doit être responsable de DSI et de vous soucier du routage des messages).

Sélection de pont


Dans l'implémentation actuelle, cet algorithme est simple. Lorsqu'un nouveau participant rejoint la conférence, Jicofo doit déterminer quel pont lui attribuer. Cela se fait en fonction de la région du participant et de l'encombrement des ponts. Si dans la même région il y a un pont libre, alors il est nommé. Sinon, un autre pont est utilisé.

Pour plus d'informations sur Octo, consultez la documentation .

Développez SFU en cascade


Pour le déploiement, nous avons utilisé des machines dans Amazon AWS. Nous avions des serveurs (alarmes et médias) dans 6 régions:

  • us-east-1 (Virginie du Nord);
  • us-west-2 (Oregon);
  • eu-west-1 (Irlande);
  • eu-central-1 (Francfort);
  • ap-se-1 (Singapour);
  • ap-se-2 (Sydney).

Nous avons utilisé des instances HAProxy géoréférencées pour déterminer la région membre. Le domaine meet.jit.si est géré par Route53 et résout l'instance HAProxy, qui ajoute la région aux en-têtes HTTP de la demande envoyée. L'en-tête est ensuite utilisé comme valeur de la variable config.deploymentInfo.userRegion , qui est disponible sur le client grâce au fichier /config.js .

L'interface jitsi montre combien de ponts sont utilisés et à quels utilisateurs spécifiques sont attachés - à des fins de diagnostic et de démonstration. En survolant le coin supérieur gauche de la vidéo locale, vous verrez le nombre total de serveurs et le serveur auquel vous êtes connecté. De même, vous pouvez voir les paramètres du deuxième participant. Vous verrez également le temps d'échange entre votre navigateur et le navigateur de l'interlocuteur (paramètre E2E RTT).


En voyant qui est connecté à quel serveur, vous pouvez voir si la cascade est utilisée.

Conclusion


Octo est apparu à l'origine comme un test A / B. Les premiers résultats ont été bons, maintenant Octo est accessible à tous. Il y a encore beaucoup de trafic à traverser et un examen plus attentif des performances; il est également prévu d'utiliser ces développements pour soutenir des conférences encore plus importantes (lorsqu'une SFU ne suffit plus).

Source: https://habr.com/ru/post/fr432708/


All Articles