SFUs المتتالية: تحسين قابلية التوسع وجودة الوسائط في تطبيقات WebRTC

هناك نوعان من الصعوبات في نشر خوادم الوسائط لـ WebRTC: القياس ، أي تجاوز استخدام خادم واحد وتحسين التأخير لجميع مستخدمي المؤتمر. على الرغم من أن المقياس البسيط بروح "إرسال جميع مستخدمي مؤتمر X إلى الخادم Y" يسهل على المستوى الأفقي بسهولة ، إلا أنه بعيد عن المستوى الأمثل من حيث التأخيرات. إن توزيع المؤتمر بين خوادم ليست قريبة فقط من المستخدمين ، ولكن أيضًا مترابط - يبدو كحل لكلتا المشكلتين. لقد أعددنا اليوم ترجمة لمواد مفصلة من Boris Grozev من Jitsi: مشكلات وحدات SFU المتتالية ، مع وصف للنهج وبعض الصعوبات ، بالإضافة إلى تفاصيل التنفيذ. تجدر الإشارة إلى أن مؤتمرات Voximplant تستخدم SFU أيضًا ؛ نحن نعمل حاليًا على تتابع SFU ، والذي من المقرر أن يظهر على برنامجنا العام المقبل.


الخلايا العصبية الماوس. صورة NIHD ( CC-BY-2.0 )

تعتبر الاتصالات في الوقت الفعلي حساسة للغاية للشبكة: عرض النطاق الترددي ، زمن الوصول ، وفقدان الحزمة. يؤدي انخفاض معدل البت إلى انخفاض في جودة الفيديو ، ويؤدي تأخير الشبكة الطويل إلى تأخير طويل للمستخدمين النهائيين. يمكن أن يؤدي فقد الحزم إلى انقطاع الصوت وتؤدي إلى تجمد الفيديو (بسبب تخطي الإطار).

لذلك ، من المهم جدًا للمؤتمر أن يختار المسار الأمثل بين الأجهزة / المستخدمين النهائيين. عندما يكون هناك مستخدمان فقط ، يكون ذلك سهلاً - يستخدم WebRTC بروتوكول ICE لتأسيس اتصال بين المشاركين. إذا كان ذلك ممكنًا ، يتصل المشاركون مباشرةً ، وإلا فسيتم استخدام خادم TURN. يمكن لـ WebRTC حل اسم مجال للحصول على عنوان خادم TURN ، بحيث يمكنك بسهولة اختيار TURN محلي يعتمد على DNS ، على سبيل المثال ، باستخدام خصائص AWS Route53 .

ومع ذلك ، عندما يحدث توجيه العديد من المشاركين من خلال خادم وسائط مركزي واحد ، يصبح الموقف معقدًا. تستخدم العديد من خدمات WebRTC وحدات إعادة التوجيه الانتقائية (SFUs) لنقل الصوت والفيديو بين 3 أو أكثر من المشاركين بشكل أكثر كفاءة.

مشكلة مع نجم


في طبولوجيا النجوم ، يتصل جميع المشاركين بخادم واحد يتبادلون من خلاله تدفقات الوسائط. من الواضح أن اختيار موقع الخادم له أهمية كبيرة: إذا كان جميع المشاركين موجودين في الولايات المتحدة ، فإن استخدام خادم في سيدني ليس فكرة جيدة.


تستخدم العديد من الخدمات مقاربة بسيطة تعمل بشكل جيد في معظم الحالات: فهي تختار خادمًا أقرب إلى المشارك الأول في المؤتمر. ومع ذلك ، هناك أوقات يكون فيها هذا الحل غير مثالي. تخيل أن لدينا ثلاثة مشاركين من الصورة أعلاه. إذا كان الأسترالي (Caller C) هو أول من ينضم إلى المؤتمر ، فستختار الخوارزمية خادمًا في أستراليا ، ومع ذلك سيكون Server 1 في الولايات المتحدة هو الخيار الأفضل ، لأن إنه أقرب إلى معظم المشاركين.

السيناريو الموضح ليس متكررًا جدًا ، ولكنه يحدث بالفعل. إذا افترضنا أن المستخدم متصل بترتيب عشوائي ، فسيحدث الموقف الموصوف مع conferences لجميع المؤتمرات التي تضم 3 مشاركين ، يتم حذف أحدها بشكل كبير.

سيناريو آخر وأكثر تكرارا: لدينا مجموعتان من المشاركين في مواقع مختلفة. في هذه الحالة ، يكون أمر الاتصال غير مهم ، سيكون لدينا دائمًا مجموعة من المشاركين عن كثب الذين يضطرون إلى تبادل الوسائط مع خادم بعيد. على سبيل المثال ، مشاركان من أستراليا (C&D) ومشاركان من الولايات المتحدة الأمريكية (A&B).


لن يكون التبديل إلى الخادم 1 هو الأمثل لأعضاء C&D. خادم 2 ليس الأمثل ل A & B. أي أنه بغض النظر عن الخادم المستخدم ، سيكون هناك دائمًا مشاركون متصلون بالخادم البعيد (= غير الأمثل).

ولكن إذا لم يكن لدينا حد خادم واحد؟ يمكننا توصيل كل مشارك بأقرب خادم ، ويبقى فقط لتوصيل هذه الخوادم.

الحل: المتتالية


نؤجل مسألة كيفية توصيل الخوادم ؛ دعونا أولا نرى ما سيكون التأثير.


لم يتغير اتصال SFU بين C و D - لا يزال يتم استخدام الخادم 2. يتم استخدام الخادم 1. للمشاركين A و B ، وهذا أفضل بشكل واضح. الشيء الأكثر إثارة للاهتمام هو الاتصال بين ، على سبيل المثال ، A و C: بدلاً من A <=> Server 2 <=> C ، يتم استخدام المسار A <=> Server 1 <=> Server 2 <=> C.

تأثير ضمني على سعر الصرف


مزيج SFU له إيجابيات وسلبيات. من ناحية ، في الحالة الموضحة ، يصبح وقت التبادل بين المشاركين أطول عند إضافة قفزات جديدة على الشبكة. من ناحية أخرى ، هناك انخفاض في هذا الوقت عندما نتحدث عن اتصال "العميل" - "الخادم الأول" ، لأنه يمكننا استعادة تدفق الوسائط بتأخير أقل من خلال مبدأ قفزة.

كيف يعمل؟ يستخدم WebRTC RTP (عادة عبر UDP) لنقل الوسائط. هذا يعني أن النقل غير موثوق به. عند فقد حزمة UDP ، يمكنك تجاهل الخسارة أو طلب إعادة إرسال (إعادة الإرسال) باستخدام حزمة RTCP NACK - الخيار موجود بالفعل في ضمير التطبيق. على سبيل المثال ، قد يتجاهل أحد التطبيقات فقدان حزم الصوت ويطلب إعادة إرسال بعض حزم الفيديو (وليس كلها) ، اعتمادًا على ما إذا كانت هناك حاجة إليها لفك تشفير الإطارات اللاحقة أم لا.


إعادة إرسال حزمة RTP ، خادم واحد

عندما يكون هناك تسلسل ، قد تكون إعادة الإرسال مقصورة على الخادم المحلي ، أي ، يتم تنفيذها على كل موقع على حدة. على سبيل المثال ، في المسار A-S1-S2-C ، في حالة فقد حزمة بين A و S1 ، فإن S1 ستلاحظ ذلك وتطلب إعادة الإرسال ؛ على غرار الخسارة بين S2 و C. وحتى إذا فقدت الحزمة بين الخوادم ، فقد يطلب جانب الاستقبال أيضًا إعادة الإرسال.


نقل حزمة RTP ، خادمين. لاحظ أن Server 2 لا يطلب الحزمة 2 ، لأن NACK وصل بعد وقت قصير من إرسال الحزمة.

يستخدم العميل مخزن مؤقت jitter لتأخير تشغيل الفيديو وإدارة لتلقي الحزم تأخير / إعادة إرسال. يتغير حجم المخزن المؤقت ديناميكيًا اعتمادًا على وقت التبادل بين الأطراف. عند حدوث عمليات إعادة الإرسال في القفز ، ينخفض ​​التأخير ، ونتيجة لذلك ، قد يكون المخزن المؤقت أصغر - نتيجة لذلك ، يتناقص التأخير الكلي أيضًا.

باختصار: حتى لو كان وقت التبادل بين المشاركين أعلى ، فقد يؤدي ذلك إلى انخفاض التأخير في نقل الوسائط بين المشاركين. لا يزال يتعين علينا دراسة هذا التأثير في الممارسة العملية.

تقديم المتتالية SFUs: Jitsi Meet Case


المنبه مقابل وسائل الإعلام


دعونا نلقي نظرة على ناقوس الخطر. منذ البداية ، شارك Jitsi Meet مفهوم خادم الإشارة ( Jicofo ) وخادم الوسائط / SFU. هذا يسمح بإدخال الدعم المتتالي بسيط نسبيا. أولاً ، يمكننا معالجة كل منطق الإشارات في مكان واحد ؛ ثانياً ، لدينا بالفعل بروتوكول تشوير بين Jicofo وخادم الوسائط. كنا بحاجة فقط لتوسيع الوظيفة قليلاً: لقد دعمنا بالفعل عدة وحدات SFU متصلة بخادم إشارة واحد ، وكان علينا إضافة قدرة وحدة SFU واحدة على الاتصال بالعديد من خوادم الإشارة.

نتيجة لذلك ، ظهر تجمّعان مستقلان للخوادم: أحدهما لمثيلات jicofo ، والآخر لمثيلات خادم الوسائط ، انظر المخطط:


مثال على تنظيم الخوادم على AWS مع إمكانية سلسلة من مراكز البيانات المختلفة.

الجزء الثاني من النظام هو الاتصال من جسر إلى جسر. أردنا أن نجعل هذا الجزء بسيطًا قدر الإمكان ، لذلك لا توجد إشارة معقدة بين الجسور. يذهب كل التنبيه بين jicofo و jitsi-videobridge ؛ يتم استخدام اتصال الجسر فقط لرسائل الصوت / الفيديو وربط البيانات.

بروتوكول اوكتو


لإدارة هذا التفاعل ، اتخذنا بروتوكول Octo ، الذي يلتف حزم RTP في رؤوس بسيطة ذات طول ثابت ، ويسمح لك أيضًا بإرسال رسائل نصية. في التطبيق الحالي ، يتم توصيل الجسور بواسطة طوبولوجيا شبكية كاملة (شبكة كاملة) ، ولكن طبولوجيا أخرى ممكنة أيضًا. على سبيل المثال ، استخدم خادمًا مركزيًا (نجمة للجسور) أو بنية شجرة لكل جسر.

Explanation: بدلا من لفه في رأس Octo ، يمكنك استخدام امتداد رأس RTP ، مما سيجعل التدفقات بين الجسور على RTP الخالص (S). يمكن أن تستخدم الإصدارات المستقبلية من Octo هذا النهج.

التفسير الثاني: Octo لا يعني شيئًا. في البداية ، أردنا استخدام خادم مركزي ، وذكرنا الأخطبوط. لذلك ظهر اسم المشروع.

تنسيق رأس Octo

في مصطلحات Jitsi ، عندما يكون الجسر جزءًا من مؤتمر به جسور متعددة ، فإنه يحتوي على قناة Octo إضافية (في الواقع ، قناة واحدة للصوت وواحدة للفيديو). هذه القناة مسؤولة عن إرسال / استقبال الوسائط إلى / من الجسور الأخرى. يتم تعيين منفذ مجاني لكل جسر لـ Octo (4096 افتراضيًا) ، لذلك نحن بحاجة إلى حقل معرف المؤتمر للتعامل مع مؤتمرات متعددة.

في الوقت الحالي ، لا يشتمل البروتوكول على آليات أمنية مضمّنة ونفوض هذه المسؤولية إلى المستويات الأدنى. هذا هو أقرب شيء سنفعله في المستقبل القريب ، ولكن في الوقت الحالي يجب أن تكون الجسور في شبكة آمنة (على سبيل المثال ، نسخة AWS VPC منفصلة).

سيمولكاست


يتيح Simulcast لكل مشارك إرسال تدفقات وسائط متعددة باستخدام معدلات بت مختلفة ، بينما يساعد الجسر في تحديد أي منها مطلوب. لكي يعمل هذا بشكل صحيح ، نقوم بنقل جميع تدفقات simulcast بين الجسور. بفضل هذا ، يمكنك التبديل بسرعة بين التدفقات ، لأن الجسر المحلي لا يحتاج إلى طلب دفق جديد. ومع ذلك ، هذا ليس الأمثل من وجهة نظر حركة المرور من جسر إلى جسر ، كما نادراً ما يتم استخدام بعض مؤشرات الترابط ويتم تحميل النطاق الترددي فقط دون أي غرض.

اختيار عضو نشط


أردنا أيضًا فرصة الاشتراك في مشارك / متحدث نشط في المؤتمر. لقد أصبح الأمر بسيطًا - قمنا بتدريس كل جسر لتحديد المشارك الرئيسي بشكل مستقل ، ثم إخطار عملائنا المحليين. هذا يعني أن التحديد يحدث عدة مرات ، لكنه ليس مكلفًا ويسمح لك بتبسيط بعض النقاط (على سبيل المثال ، لا تحتاج إلى تحديد الجسر الذي يجب أن يكون مسؤولاً عن DSI وتقلق بشأن توجيه الرسائل).

اختيار الجسر


في التطبيق الحالي ، هذه الخوارزمية بسيطة. عندما ينضم مشارك جديد إلى المؤتمر ، يجب على Jicofo تحديد الجسر الذي سيخصص له. يتم ذلك بناءً على منطقة المشارك وازدحام الجسور. إذا كان هناك جسر مجاني في نفس المنطقة ، فسيتم تعيينه. خلاف ذلك ، يتم استخدام بعض الجسور الأخرى.

لمزيد من المعلومات حول Octo ، راجع الوثائق .

توسيع المتتالية SFU


للنشر ، استخدمنا آلات في Amazon AWS. كان لدينا خوادم (أجهزة الإنذار والوسائط) في 6 مناطق:

  • لنا شرق -1 (شمال فرجينيا) ؛
  • لنا غرب 2 (ولاية أوريغون) ؛
  • eu-west-1 (أيرلندا) ؛
  • الاتحاد الأوروبي 1 (فرانكفورت) ؛
  • ap-se-1 (سنغافورة) ؛
  • ap-se-2 (سيدني).

استخدمنا مثيلات HAProxy المرجعية الجغرافية لتحديد منطقة الأعضاء. تتم إدارة نطاق meet.jit.si بواسطة Route53 ويحل إلى مثيل HAProxy ، الذي يضيف المنطقة إلى رؤوس HTTP للطلب المرسل. يتم استخدام الرأس لاحقًا config.deploymentInfo.userRegion لمتغير config.deploymentInfo.userRegion ، والذي يتوفر على العميل بفضل ملف /config.js .

تُظهر واجهة jitsi عدد الجسور المستخدمة والمستخدمين المتصلين بها - لأغراض التشخيص والبيان العملي. يؤدي التمرير فوق الزاوية اليسرى العليا من الفيديو المحلي إلى إظهار إجمالي عدد الخوادم والخادم الذي تتصل به. وبالمثل ، يمكنك أن ترى معالم المشارك الثاني. سترى أيضًا وقت التبادل بين متصفحك ومتصفح المحاور (المعلمة E2E RTT).


من خلال معرفة من المتصل بالخادم ، يمكنك معرفة ما إذا كان يتم استخدام المتتالية.

الخاتمة


بدا أوكتو في الأصل بمثابة اختبار A / B. كانت النتائج الأولى جيدة ، لذلك أصبح Octo متاحًا للجميع الآن. لا يزال هناك الكثير من حركة المرور لاجتيازه وإلقاء نظرة فاحصة على الأداء ؛ من المخطط أيضًا استخدام هذه التطورات لدعم المؤتمرات الأكبر حجمًا (عندما لا تكون وحدة SFU كافية).

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


All Articles