Kami menulis protokol kami di atas UDP

Siaran langsung pertama dari tempat itu muncul di Rusia hampir 70 tahun yang lalu dan disiarkan dari stasiun televisi bergerak (PTS), yang tampak seperti troli dan diizinkan untuk disiarkan dari luar studio. Dan hanya tiga tahun yang lalu Periscope diizinkan untuk menggunakan telepon seluler alih-alih β€œbis listrik”.

Tetapi aplikasi ini memiliki sejumlah masalah terkait, misalnya, keterlambatan penyiaran, ketidakmampuan menonton siaran dengan kualitas tinggi, dll.


Enam bulan kemudian, pada musim panas 2016, Odnoklassniki meluncurkan aplikasi mobile OK Live streaming mereka, di mana mereka mencoba menyelesaikan masalah ini.

Alexander Tobol bertanggung jawab atas bagian teknis video di Odnoklassniki dan di Highload ++ 2017 ia berbicara tentang cara menulis protokol UDP Anda, dan mengapa ini mungkin diperlukan.

Dari transkrip laporannya, Anda akan mempelajari semua tentang protokol streaming video lainnya, apa nuansanya, dan trik apa yang kadang-kadang diperlukan.


Mereka mengatakan bahwa kita harus selalu mulai dengan arsitektur dan TK - seharusnya tidak mungkin tanpa ini! Jadi mari kita lakukan.

Arsitektur dan TK


Pada slide di bawah ini adalah diagram arsitektur dari setiap layanan streaming: video diumpankan ke input, dikonversi dan dikirim ke output . Kami menambahkan lebih banyak persyaratan untuk arsitektur ini: video harus dipasok dari desktop dan ponsel, dan output harus pergi ke desktop yang sama, ponsel, smartTV, Chromcast, AppleTV dan perangkat lain - semua video dapat diputar.


Selanjutnya, kita beralih ke kerangka acuan. Jika Anda memiliki pelanggan, Anda memiliki TK. Jika Anda adalah jejaring sosial, Anda tidak memiliki TK. Bagaimana cara menebusnya?

Tentu saja Anda dapat mewawancarai pengguna dan mengetahui semua yang mereka inginkan. Tetapi itu akan menjadi sejumlah keinginan yang tidak berkorelasi dengan apa yang benar-benar dibutuhkan orang.

Kami memutuskan untuk mengambil jalan sebaliknya dan melihat apa yang TIDAK ingin dilihat pengguna dari layanan siaran.

  • Hal pertama yang tidak diinginkan pengguna adalah melihat penundaan pada awal siaran .
  • Pengguna tidak ingin melihat gambar streaming berkualitas rendah .
  • Jika siaran itu interaktif ketika pengguna berkomunikasi dengan audiensnya (siaran langsung, panggilan, dll.), Maka ia tidak ingin melihat penundaan antara streamer dan penonton .

Seperti inilah layanan streaming normal. Mari kita lihat apa yang dapat dilakukan untuk melakukan layanan streaming reguler, bukan yang biasa.


Anda bisa mulai dengan melihat semua protokol streaming, pilih yang paling menarik dan bandingkan. Tetapi kami melakukannya secara berbeda.

Apa yang dimiliki pesaing?


Kami mulai dengan menjelajahi layanan pesaing. Open Periscope - apa yang mereka miliki?

Seperti biasa, yang utama adalah arsitektur.


Sara Hyder, insinyur utama Periscope, menulis bahwa mereka menggunakan Wowza untuk backend. Jika kita membaca sedikit lebih banyak artikel, maka kita akan melihat apa yang mereka streaming menggunakan protokol RTMP , dan mendistribusikannya baik dalam RTMP atau dalam HLS. Mari kita lihat apa protokol ini dan bagaimana cara kerjanya.

Kami menguji Periscope pada tiga persyaratan utama kami.

Mereka memiliki kecepatan mulai yang dapat diterima (kurang dari satu detik di jaringan yang baik), kualitas konstan sekitar 600 px (bukan HD), dan pada saat yang sama penundaan bisa mencapai 12 detik .

Ngomong-ngomong, bagaimana mengukur keterlambatan penyiaran?

Ini adalah foto pengukuran keterlambatan. Ada ponsel dengan timer. Kami menyalakan siaran dan melihat gambar ponsel ini di layar. Selama 0,15 milidetik, gambar jatuh pada sensor kamera dan dihapus dari memori video ke layar ponsel. Setelah itu, kita menyalakan browser dan menonton siaran.

Aduh! Dia sedikit ketinggalan - sekitar 12 detik.

Untuk menemukan alasan penundaan, kami profil streaming video.

Jadi, ada ponsel, videonya masuk dari kamera dan masuk ke buffer video. Di sini penundaannya minimal (β‰ˆ0,15 ms). Kemudian encoder mengkodekan sinyal, mengemasnya dalam suatu paket dan mengirimkannya ke buffer soket. Semuanya terbang ke web. Selanjutnya, hal yang sama terjadi pada perangkat penerima.

Pada dasarnya, ada dua poin sulit utama untuk dipertimbangkan:

  • encoding / decoding video;
  • protokol jaringan .

Pengkodean / Penguraian Video


Saya akan menceritakan sedikit tentang coding. Anda tetap akan menjumpainya jika Anda melakukan Streaming Langsung Latensi Rendah.

Apa itu video? Ini adalah seperangkat bingkai, tetapi tidak cukup sederhana. Frame terdiri dari tiga jenis: I, P dan B-frame:

  • I-frame hanya jpg. Bahkan, ini adalah kerangka referensi, tidak bergantung pada siapa pun dan berisi gambar yang jelas.
  • Bingkai-P semata-mata bergantung pada bingkai sebelumnya.
  • Bingkai-B yang rumit mungkin bergantung pada masa depan. Ini berarti bahwa untuk menghitung b-frame, perlu bahwa frame masa depan juga datang dari kamera. Hanya dengan demikian b-frame dapat diterjemahkan dengan penundaan.

Ini menunjukkan bahwa frame B berbahaya . Mari kita coba untuk menghapusnya.

  1. Jika Anda streaming dari perangkat seluler, Anda dapat mencoba mengaktifkan profil dasar . Ini akan menonaktifkan B-frame.
  2. Anda dapat mencoba mengkonfigurasi codec dan mengurangi penundaan untuk frame masa depan sehingga frame tiba lebih cepat.
  3. Hal penting lainnya dalam menyetel codec adalah dimasukkannya CBR (laju bit konstan).


Cara kerja codec diilustrasikan dalam slide di atas. Dalam contoh ini, video adalah gambar statis, karena penyandiannya menghemat ruang disk, karena hampir tidak ada perubahan di sana, dan bitrate video rendah. Perubahan sedang terjadi - entropi bertambah, bitrate video bertambah - bagus untuk menyimpan ke disk.

Tetapi pada saat perubahan aktif dimulai, dan bitrate meningkat, kemungkinan besar semua data tidak akan masuk ke jaringan. Inilah yang terjadi ketika Anda melakukan panggilan video dan mulai berbelok, dan pelanggan Anda memperlambat gambar. Ini disebabkan oleh fakta bahwa jaringan tidak punya waktu untuk beradaptasi dengan mengubah laju bit.

Seseorang harus memasukkan CBR . Tidak semua codec Android akan mendukungnya dengan benar, tetapi mereka akan mengusahakannya. Artinya, Anda perlu memahami bahwa dengan CBR Anda tidak akan mendapatkan gambar dunia yang sempurna, seperti pada gambar bawah, tetapi masih layak untuk dinyalakan.

4. Dan di backend, Anda perlu menambahkan codec zerolatency ke H264 - ini akan memungkinkan Anda untuk tidak membuat dependensi dalam bingkai untuk masa depan.

Protokol Transfer Video


Pertimbangkan protokol streaming apa yang ditawarkan industri. Saya membaginya secara kondisional menjadi dua jenis:

  1. protokol streaming;
  2. protokol segmen.


Protokol streaming adalah protokol dari dunia panggilan p2p: RTMP, webRTC, RTSP / RTP . Mereka berbeda dalam hal pengguna menyetujui saluran mana yang mereka miliki, pilih bitrate codec sesuai dengan saluran. Dan mereka juga memiliki tim tambahan semacam ini, seperti "beri saya referensi". Jika Anda kehilangan bingkai, dalam protokol ini Anda dapat memintanya lagi.

Perbedaan antara protokol segmen adalah tidak ada yang bernegosiasi dengan siapa pun. Mereka memotong video menjadi segmen, menyimpan setiap segmen dalam berbagai kualitas, dan klien dapat memilih segmen mana yang akan ditonton. Setiap segmen dimulai dengan kerangka referensi.

Pertimbangkan protokol secara lebih rinci. Mari kita mulai dengan protokol streaming dan mencari tahu masalah apa yang mungkin kita temui jika kita menggunakan protokol streaming untuk streaming siaran.

Protokol Streaming


Periscope menggunakan RTMP. Protokol ini muncul pada tahun 2009, dan pada awalnya Adobe tidak sepenuhnya menentukannya. Kemudian dia mengalami kesulitan tertentu dengan fakta bahwa Adobe ingin menjual servernya secara eksklusif. Artinya, RTMP berkembang cukup sulit. Masalah utamanya adalah ia menggunakan TCP , tetapi karena beberapa alasan Periscope memilihnya.



Jika Anda membaca secara detail, ternyata Periscope menggunakan RTMP untuk menyiarkan dengan sejumlah kecil pemirsa. Hanya siaran seperti itu, jika Anda memiliki saluran yang tidak mencukupi, kemungkinan besar Anda tidak akan bisa menonton.



Pertimbangkan contoh spesifik. Ada pengguna dengan saluran komunikasi sempit yang menonton siaran Anda. Anda setuju dengannya pada RTMP tentang bitrate rendah dan mulai streaming untuknya secara pribadi.

Seorang pengguna dengan internet keren datang kepada Anda, Anda juga memiliki internet keren, tetapi Anda telah menyetujui kualitas rendah dengan seseorang, dan ternyata yang ketiga ini dengan internet keren sedang menonton aliran dalam kualitas buruk, terlepas dari kenyataan bahwa itu bisa terlihat bagus.

Kami memutuskan untuk memperbaiki masalah ini. Kami memungkinkan RTMP terpotong secara individual untuk setiap klien, yaitu streamer bernegosiasi dengan server, streaming dengan kualitas setinggi mungkin, dan setiap klien menerima kualitas yang dimungkinkan oleh jaringan.

Wow!

Tapi tetap saja, kami memiliki RTMP lebih dari TCP, dan tidak ada yang menjamin kami dari memblokir awal antrian.



Ini diilustrasikan dalam gambar: kami menerima bingkai audio dan video, RTMP mengemasnya, mungkin mereka mencampurnya entah bagaimana, dan mereka terbang ke jaringan.

Tapi misalkan kita kehilangan satu paket. Ada kemungkinan bahwa paket kuning yang hilang sama - ini umumnya P-frame dari beberapa yang sebelumnya - bisa saja dijatuhkan. Mungkin, minimal, seseorang dapat memutar audio. Tetapi TCP tidak akan memberi kita sisa paket, karena menjamin pengiriman dan urutan paket . Kita harus entah bagaimana berurusan dengan ini.


Ada masalah lain dengan menggunakan protokol TCP dalam streaming.

Katakanlah kita memiliki buffer dan bandwidth jaringan yang tinggi. Kami menghasilkan paket resolusi tinggi dari codec kami di sana. Lalu - op! - jaringan mulai bekerja lebih buruk. Di codec, kami telah mengindikasikan bahwa bitrate perlu diturunkan, tetapi paket yang sudah jadi sudah dalam antrian dan Anda tidak dapat menghapusnya dari sana dengan cara apa pun. TCP sangat ingin mendorong paket HD melalui 3G kami.

Kami tidak memiliki manajemen buffer, tidak ada prioritas, sehingga TCP sangat tidak cocok untuk streaming .



Mari kita lihat jaringan seluler sekarang. Mungkin mengejutkan bagi penduduk ibu kota, tetapi jaringan seluler rata-rata kami terlihat seperti ini:

  • Lalu lintas 1,1 Mbps;
  • Kehilangan paket 0,1%;
  • 300 ms RTT rata-rata.

Dan jika Anda melihat beberapa wilayah dan operator tertentu, maka mereka memiliki persentase kehilangan paket harian rata - rata lebih dari 3% , dan RTT dari 600 ms adalah normal.

TCP, di satu sisi, adalah protokol keren - sangat sulit untuk mengajarkan mobil untuk mengemudi di jalan TOL dan off-road. Tetapi untuk mengajarinya maka juga untuk terbang di atas jaringan nirkabel sangat sulit.



Kehilangan bahkan 0,001% dari paket menghasilkan pengurangan 30% dalam throughput. Artinya, pengguna kami tidak memanfaatkan saluran sebesar 30% karena ketidakefisienan protokol TCP dalam jaringan dengan kehilangan paket acak.

Di wilayah tertentu, packet loss mencapai 1%, maka pengguna memiliki sekitar 10% persen dari bandwidth.

Karena itu, kami tidak akan melakukan TCP .

Mari kita lihat apa lagi yang ada di dunia streaming dari UDP.

Protokol WebRTC telah bekerja dengan sangat baik untuk panggilan P2P. Di situs yang sangat populer mereka menulis bahwa menggunakannya untuk panggilan sangat keren, tetapi untuk mengirimkan video dan musik itu tidak baik.

Masalah utamanya adalah ia mengabaikan kerugian . Dengan semua situasi aneh, dia hanya jatuh.

Masih ada beberapa masalah dalam keterikatannya dengan panggilan, faktanya dia mengenkripsi semuanya. Karena itu, jika Anda menyiarkan siaran, dan tidak perlu mengenkripsi seluruh aliran audio / video dengan memulai WebRTC, Anda tetap akan menyaring prosesor Anda. Anda mungkin tidak membutuhkan ini.



Streaming RTP adalah protokol dasar untuk mengirimkan data melalui UDP. Di bawah ini pada slide ke kanan adalah serangkaian ekstensi dan RFC yang harus diterapkan di WebRTC untuk menyesuaikan protokol ini untuk panggilan. Pada prinsipnya, Anda dapat mencoba melakukan sesuatu seperti ini - memanggil satu set ekstensi ke RTP dan mendapatkan streaming UDP. Tetapi ini sangat sulit .

Masalah kedua adalah bahwa jika salah satu klien Anda tidak mendukung ekstensi apa pun, maka protokol tidak akan berfungsi.



Protokol Segmen


Contoh yang bagus dari protokol video tersegmentasi adalah MPEG-Dash . Ini terdiri dari file manifes yang Anda poskan di portal Anda. Ini berisi tautan ke file dalam kualitas yang berbeda, di awal file ada beberapa indeks yang mengatakan di mana file mana segmen dimulai.



Seluruh video dibagi menjadi beberapa segmen, misalnya, selama 3 detik, setiap segmen dimulai dengan kerangka referensi. Jika Anda menonton video dan perubahan bitrate Anda, maka Anda hanya di sisi klien mulai mengambil segmen kualitas yang Anda butuhkan.

Contoh lain dari streaming tersegmentasi adalah HLS .

MPEG-Dash adalah solusi dari Google, ini bekerja dengan baik di Android, dan solusi Apple lebih tua, ia memiliki sejumlah kelemahan tertentu.



Yang pertama adalah manifes utama berisi tautan ke manifes sekunder, manifes sekunder untuk setiap kualitas spesifik berisi tautan ke setiap segmen individu, dan setiap segmen individu diwakili oleh file terpisah.

Jika Anda melihat lebih detail, maka di dalam setiap segmen adalah MPEG2-TS. Protokol ini juga dibuat untuk satelit, ukuran paketnya adalah 188 byte . Sangat tidak nyaman untuk mengemas video dalam ukuran ini, terutama karena Anda selalu menyediakannya dengan header kecil.

Bahkan, ini sulit tidak hanya untuk server, yang untuk memproses 40 GB lalu lintas harus mengumpulkan 26 juta paket , tetapi juga sulit bagi klien. Karena itu, ketika kami menulis ulang pemutar iOS di MPEG-Dash, kami bahkan melihat beberapa peningkatan kinerja.



Namun Apple tidak tinggal diam. Pada 2016, mereka akhirnya mengumumkan bahwa mereka memiliki kesempatan untuk mendorong sebuah fragmen dari MPEG4 di HLS. Kemudian mereka berjanji untuk menambahkan ini hanya untuk pengembang, tetapi tampaknya sekarang dukungan untuk macOS dan iOS akan muncul.

Artinya, akan tampak bahwa streaming fragmen nyaman - datang, ambil fragmen yang diinginkan, mulai dari kerangka referensi - itu berfungsi.

Minus: sudah jelas bahwa kerangka referensi dari mana Anda memulai bukanlah bingkai yang dimiliki orang yang melakukan streaming sekarang. Karena itu, selalu ada penundaan .

Secara umum, dimungkinkan untuk menyelesaikan HLS hingga keterlambatan urutan 5 detik, seseorang mengatakan bahwa ia berhasil mendapatkan 4, tetapi pada prinsipnya, keputusan untuk menggunakan streaming fragmen untuk terjemahan tidak terlalu baik .



Kesulitan vs Penundaan


Mari kita lihat semua protokol yang tersedia dan urutkan berdasarkan dua parameter:

  • latensi yang mereka berikan antara siaran dan penonton;
  • kompleksitas

Semakin pendek penundaan jaminan protokol, semakin kompleks itu.



Apa yang kita inginkan?


Kami ingin membuat protokol UDP untuk streaming dari 1 ke N dengan penundaan yang sebanding dengan komunikasi p2p, dengan opsi enkripsi paket opsional tergantung pada apakah penyiaran publik atau swasta.

Opsi apa lagi yang ada? Anda bisa menunggu, misalnya, ketika Google merilis QUIC-nya.

Saya akan memberi tahu Anda sedikit apa itu. Google memposisikan Google QUIC sebagai pengganti TCP - semacam TCP 2.0. Ini telah dikembangkan sejak 2013, sekarang tidak memiliki spesifikasi, tetapi sepenuhnya tersedia di Google Chrome, dan menurut saya kadang-kadang mereka menyalakannya untuk beberapa pengguna untuk melihat cara kerjanya. Pada prinsipnya, Anda dapat masuk ke pengaturan, nyalakan QUIC, pergi ke situs Google mana saja dan dapatkan sumber daya ini melalui UDP.

Kami memutuskan untuk tidak menunggu sampai mereka semua menentukan, dan untuk mengajukan keputusan kami.

Persyaratan Protokol:

  1. Multithreading , yaitu, kami memiliki beberapa aliran - kontrol, video, audio.
  2. Jaminan pengiriman opsional - aliran kontrol memiliki jaminan 100%, video yang paling kami butuhkan - kami dapat meletakkan bingkai di sana, kami masih menginginkan audio.
  3. Prioritas aliran - sehingga audio maju, dan manajer umumnya terbang.
  4. Enkripsi opsional : semua data, atau hanya header dan data penting.



Ini adalah segitiga standar: jika jaringan yang baik, maka kualitas tinggi dan latensi rendah. Segera setelah jaringan yang tidak stabil muncul, paket-paket mulai menghilang, kami menyeimbangkan antara kualitas dan penundaan. Kami punya pilihan: menunggu sampai jaringan menjadi lebih baik dan mengirim semua yang telah menumpuk, atau turun dan entah bagaimana hidup dengannya.

Jika Anda mengurutkan protokol berdasarkan prinsip ini, maka dapat dilihat bahwa semakin pendek waktu tunggu, semakin buruk kualitasnya - kesimpulan yang cukup sederhana.

Kami ingin memasukkan protokol kami ke zona di mana penundaan dekat dengan WebRTC, tetapi pada saat yang sama dapat mendorongnya sedikit, karena bagaimanapun kita tidak memiliki panggilan, tetapi siaran. Pengguna akhirnya ingin menerima aliran kualitas.

Pengembangan


Mari kita mulai menulis protokol UDP, tetapi pertama-tama lihat statistiknya.



Ini adalah statistik kami di jaringan seluler. Dapat dilihat bahwa rata-rata Internet sedikit lebih dari megabit, paket loss sekitar 1% adalah normal, dan RTT di wilayah 600 ms - pada 3G, ini hanya nilai rata-rata.

Kami akan fokus pada ini ketika menulis protokol - ayo!

Protokol UDP


Kami membuka soket UDP, kami mengambil data, kami kemas, kami kirim. Kami mengambil paket kedua dari codec, kami masih mengirim. Segalanya tampak hebat!



Tapi kita mendapatkan gambar berikut: jika kita mulai mengirim paket UDP secara acak ke soket, maka menurut statistik, pada paket ke-21 probabilitas yang akan dicapai hanya 85%. Artinya, packet loss akan menjadi 15%, yang tidak baik. Ini perlu diperbaiki.



Ini ditetapkan sebagai standar. Ilustrasi menggambarkan kehidupan tanpa Pacer dan hidup dengan Pacer .

Pacer adalah hal yang menyebar paket dalam waktu dan mengendalikan kehilangan mereka; Itu terlihat pada kehilangan paket apa sekarang, tergantung pada ini menyesuaikan dengan kecepatan saluran.

Seperti yang kita ingat, untuk jaringan seluler, paket loss 1-3% adalah norma. Oleh karena itu, entah bagaimana kita harus bekerja dengan ini. Bagaimana jika kita kehilangan paket?

Kirim ulang




Dalam TCP, seperti yang Anda ketahui, ada algoritma pengiriman ulang cepat: kami mengirim satu paket, yang kedua, jika paket tersebut hilang, maka setelah beberapa saat (periode pengiriman ulang) kami mengirim paket yang sama.

Apa kelebihannya? Tidak ada masalah, tidak ada redundansi, tetapi ada minus - beberapa periode pengiriman ulang .



Tampaknya sangat sederhana: setelah beberapa waktu Anda perlu mengulangi paket jika Anda belum menerima konfirmasi tentang itu. Logikanya, ini mungkin waktu yang sama dengan waktu ping. ping β€” , RTT time , , .

, , , , jitter: ping-. , , 46 . jitter β€” 50.



. RTT , , acknowledge . , RFC6298, TCP , .

jitter. jitter ping 15%. , retransmit period , , 20% , RTT.



retransmit. acknowledge . , , . retransmit period, . , .

, retransmit . , , packet loss 5%, 400 , 400 1 packet-drop, , retransmit period , .

, . , , acknowledge . , β€” , , speculative retransmit .

retransmit, .

. , Forward Error Correction ? , , XOR. , , .



! round trip, .

, , ? XOR β€” , Reed-Solomon, Fountain codes .. : K , N , N .

!

, , , Forward Error Correction negative acknowledgement.

NACK




, parity protection ( ) , .

NACK:

  • , negative acknowledgement, .
  • FEC.

, :

  1. , FEC + NACK;
  2. , Fast retransmit.

, .



, , ( ). , , 11 , 60-80 . , , .

6 .



, , . , . , Wi-Fi 22 5 , 3G 34 8 .



: , 90% packet loss 10 , gap 25 , β€” FEC + NACK Fast retransmit?

, , , Google, QUIC 2013 , Forward Error Correction , , . 2015 .

FEC + NACK, .

, .



, , c :

  • 1 / ;
  • 1% packet loss;
  • 300 RTT;
  • 1 000 β€” ;
  • 1 000 .

10 . packet loss 1% 1 000 10. β€” 100 1 β€” , 2 , .

, . 500- , 10 .

:

  • 500 Forward Error Correction. , .
  • NACK, , .
  • Fast Retransmit, .

Forward Error Correction , β€” gap 200-300 .

Fast Retransmit


: , 10 , , , retransmit period , .



, retransmit period 350 , packet gap β€” 25-30 , 100. , , retransmit , .

, .


UDP , .



, , p/b-. . , .

, , , , , , 0,5 .

, , , , p/b, , , .

MTU


Karena kita menulis protokol sendiri, kita harus berurusan dengan fragmentasi IP. Saya pikir banyak orang tahu tentang ini, tetapi untuk berjaga-jaga, saya akan memberitahu Anda secara singkat.



Kami memiliki server, mengirimkan beberapa paket ke jaringan, mereka datang ke router dan pada levelnya MTU (unit transmisi maksimum) menjadi lebih rendah dari ukuran paket yang tiba. Ini membagi paket menjadi besar dan kecil (di sini 1100 dan 400 byte) dan mengirimkan.

Pada prinsipnya, tidak ada masalah, semuanya akan berkumpul pada klien dan akan bekerja. Tetapi jika kita kehilangan 1 paket, kita menjatuhkan semua paket, ditambah kita mendapatkan biaya tambahan untuk header paket. Karena itu, jika Anda menulis protokol Anda, sangat ideal untuk bekerja dalam jumlah MTU.

Bagaimana cara menghitungnya?

Bahkan, Google tidak repot-repot, menempatkan sekitar 1200 byte dalam QUIC dan tidak memilihnya, karena dengan demikian IP fragmentasi akan mengumpulkan semua paket.



Kami melakukan hal yang persis sama - pertama-tama kami menetapkan ukuran default dan mulai mengirim paket - biarkan memecahnya.

Secara paralel, jalankan utas terpisah dan buat soket dengan bendera larangan fragmentasi untuk semua paket. Jika router menemukan paket seperti itu dan tidak dapat memecah-mecah data ini, maka itu akan menjatuhkan paket dan mungkin mengirim Anda melalui ICMP bahwa ada masalah, tetapi kemungkinan besar, ICMP akan ditutup dan ini tidak akan terjadi. Karena itu, kami hanya, misalnya, mencoba tiga kali untuk mengirim paket dengan ukuran tertentu pada interval tertentu. Jika tidak mencapai, kami percaya bahwa MTU terlampaui dan selanjutnya menguranginya.

Dengan demikian, memiliki MTU dari antarmuka internet yang ada di perangkat, dan beberapa MTU minimum, kami cukup memilih MTU yang benar dengan pencarian satu dimensi. Setelah itu, kami menyesuaikan ukuran paket dalam protokol.

Bahkan terkadang berubah. Kami terkejut, tetapi dalam proses beralih Wi-Fi, dll. MTU berubah. Lebih baik tidak menghentikan proses paralel ini dan memperbaiki MTU dari waktu ke waktu.



Distribusi MTU lebih tinggi di dunia. Kami mendapat sekitar 1100 byte di portal.

Enkripsi


Kami mengatakan bahwa kami ingin mengelola enkripsi secara opsional. Kami membuat pilihan paling sederhana - Diffie-Hellman pada kurva elips. Kami melakukannya secara opsional - kami mengenkripsi hanya paket kontrol dan header sehingga man-in-the-middle tidak dapat menerima kunci siaran, menyadapnya, dan sebagainya.



Jika siaran bersifat pribadi, maka kami juga dapat menambahkan enkripsi semua data.

Paket dienkripsi dengan AES-256 secara independen, sehingga paket drop tidak mempengaruhi enkripsi paket lebih lanjut.

Prioritas


Ingat, kami menginginkan lebih banyak prioritas dari protokol.



Kami memiliki metadata, bingkai audio dan video, kami berhasil mengirimkannya ke jaringan. Kemudian jaringan kami terbakar di neraka dan untuk waktu yang lama tidak berfungsi - kami memahami bahwa kami perlu menjatuhkan paket.

Kami terutama menjatuhkan paket video, kemudian mencoba untuk menjatuhkan audio dan tidak pernah menyentuh paket kontrol, karena data seperti perubahan resolusi dan masalah penting lainnya dapat melewatinya.

Roti tambahan tentang UDP


Jika Anda akan menulis protokol UDP Anda, misalnya, dengan komunikasi dua arah, maka Anda perlu memahami bahwa ada NAT Unbinding dan kemungkinan Anda tidak dapat menemukan klien kembali dari server.



Pada slide, ada saat-saat ketika itu tidak mungkin untuk menjangkau klien dari server melalui UDP.

Banyak skeptis mengatakan bahwa router dirancang sedemikian rupa sehingga NAT Unbinding terutama memadati rute UDP. Tetapi hal di atas menunjukkan bahwa jika Keep-Alive atau ping kurang dari 30 detik, maka dengan probabilitas 99% akan memungkinkan untuk mencapai klien.

Ketersediaan UDP pada perangkat seluler di dunia




Google mengatakan 6%, tetapi ternyata 7% pengguna ponsel tidak dapat menggunakan UDP . Dalam hal ini, kami meninggalkan protokol kami yang indah dengan memprioritaskan, enkripsi, dan semuanya, hanya pada TCP.

Di UDP, VOIP sekarang berfungsi di WebRTC, Google QUIC, dan banyak gim bekerja di UDP. Karena itu, saya tidak akan percaya bahwa UDP akan ditutup pada perangkat seluler.

Sebagai hasilnya, kami:

  • Mengurangi penundaan antara streamer dan watcher menjadi 1 s.
  • Kami menyingkirkan efek kumulatif dalam buffer, yaitu siaran tidak ketinggalan.
  • Jumlah kios di penonton telah berkurang .
  • Mereka mampu mendukung streaming pada perangkat seluler FullHD.


  • Penundaan dalam aplikasi seluler OK Live kami adalah 25 ms - 10 ms lebih lama dari pemindai kamera berfungsi, tetapi tidak begitu menakutkan.
  • Webcasting menunjukkan penundaan hanya 690 ms - ruang!

Apa lagi yang bisa streaming di Odnoklassniki



  • Terima protokol OKMP kami dari perangkat seluler;
  • dapat menerima RTMP dan WebRTC;
  • membagikan HLS, MPEG-Dash, dll.

Jika Anda berhati-hati, Anda perhatikan bahwa saya mengatakan bahwa kami dapat mengambil, misalnya, WebRTC dari pengguna dan mengubahnya menjadi RTMP.



Ada nuansa. Faktanya, WebRTC adalah protokol berorientasi paket dan menggunakan codec audio OPUS. Anda tidak dapat menggunakan OPUS dalam RTMP.

Di server backend, kami menggunakan RTMP di mana-mana. Oleh karena itu, kami harus membuat beberapa perbaikan di FF MPEG, yang memungkinkan kami untuk mendorong OPUS ke RTMP, mengubahnya menjadi AAC dan memberikannya kepada pengguna yang sudah ada di HLS atau yang lainnya.

Seperti apa rupanya di dalam diri kita?



  • Pengguna yang menggunakan salah satu protokol mengunggah video asli ke server unggah kami.
  • Di sana kami menyebarkan protokol.
  • Kami mengirim RTMP ke salah satu server transformasi video.
  • Dokumen asli selalu disimpan dalam penyimpanan terdistribusi sehingga tidak ada yang hilang.
  • Setelah itu, semua video masuk ke server distribusi.

Untuk zat besi, kami memiliki yang berikut:


Saya akan menceritakan sedikit tentang toleransi kesalahan:

  • Upload-server didistribusikan di pusat data yang berbeda, berdiri di belakang IP yang berbeda.
  • Pengguna datang, menerima IP pada DNS.
  • Upload-server mengirimkan video ke server slicing, mereka memotong dan memberikannya ke server distribusi.
  • Untuk siaran yang lebih populer, kami mulai menambahkan lebih banyak server distribusi.
  • Kami menyimpan semua yang datang dari pengguna di repositori, sehingga nanti kami dapat membuat arsip siaran dan tidak kehilangan apa pun.
  • Penyimpanan yang toleran terhadap kesalahan didistribusikan di tiga pusat data.

Untuk menentukan server mana yang saat ini bertanggung jawab atas terjemahan, kami menggunakan ZooKeeper . Untuk setiap terjemahan, kami menyimpan node dan membuat node sementara untuk setiap server. Sebenarnya, ini adalah hal yang memungkinkan aliran membuat antrian server yang akan diproses. Selalu pemimpin saat ini di baris ini terlibat dalam pemrosesan aliran.

Kami akan menguji toleransi kesalahan dengan cepat. Kami segera mulai dengan hilangnya seluruh pusat data.

Apa yang akan terjadi

  • Pengguna DNS akan mengambil IP berikutnya dari server unggah lain.
  • Pada saat ini, ZooKeeper akan mengerti bahwa server di pusat data tersebut telah mati, dan akan memilih slicing server untuk server yang lain.
  • Server unduhan akan mencari tahu siapa yang sekarang bertanggung jawab atas transformasi aliran ini dan akan mendistribusikannya.

Pada prinsipnya, semua ini akan terjadi dengan penundaan minimal.

Menggunakan protokol dalam produk

Kami membuat aplikasi seluler OK Live streaming. Ini sepenuhnya terintegrasi dengan portal. Pengguna di sana dapat berkomunikasi, melakukan siaran langsung, ada peta siaran, daftar siaran populer - secara umum, semua yang Anda inginkan.



Kami juga menambahkan kemampuan untuk menyiarkan dalam FullHD. Anda dapat menghubungkan kamera aksi di Android ke perangkat Android.



Sekarang kami memiliki mekanisme yang memungkinkan siaran langsung. Misalnya, kami membuat hubungan langsung dengan Presiden melalui OK Live dan menyiarkannya di seluruh negeri . Pengguna menyaksikan dan melalui aliran yang datang dapat mengudara dan mengajukan pertanyaan mereka.

Faktanya, dua aliran yang datang dengan penundaan minimum menyediakan format konferensi publik tertentu.

Bahkan, kami bertemu di suatu tempat dalam 2 detik - satu detik di sana dan kedua di belakang. Ingat "troli" yang saya bicarakan di awal artikel - sekarang terlihat seperti 2 truk besar. Untuk siaran TV, menghapus dari kamera dan hanya mencampur semuanya dengan penundaan sekitar 1-2 detik adalah hal yang normal.

Faktanya, kami berhasil mereproduksi sesuatu yang sebanding dengan TCP modern saat ini.



Siaran langsung adalah tren saat ini. Selama satu setengah tahun terakhir di portal OK, mereka telah berlipat tiga (bukan tanpa bantuan aplikasi OK Live).



Semua siaran direkam secara default. Kami memiliki sekitar 50 ribu aliran per hari, ini menghasilkan sekitar 17 terabyte lalu lintas per hari, tetapi secara umum semua video di portal menghasilkan sekitar satu petabyte data per bulan.



Apa yang kami dapatkan:

  • Bisa menjamin durasi penundaan antara streamer dan audiens.
  • Kami membuat aplikasi FullHD seluler pertama untuk streaming pada saluran Internet seluler yang berubah secara dinamis.
  • Kami mendapat kesempatan untuk kehilangan pusat data dan pada saat yang sama tidak mengganggu siaran

Apa yang kamu pelajari:

  • Apa itu video dan bagaimana cara streaming itu.
  • Anda dapat menulis protokol UDP Anda jika Anda tahu pasti bahwa Anda memiliki tugas yang sangat spesifik dan pengguna tertentu.
  • Tentang arsitektur layanan streaming apa pun - video memasukkan input, mengonversi, dan keluar.

Di Highload ++ Siberia, Alexander Tobol berjanji untuk berbicara tentang layanan panggilan OK, akan menarik untuk mengetahui apa yang berhasil diterapkan dari apa yang dibahas dalam artikel ini, dan apa yang harus diimplementasikan sepenuhnya lagi.

Di bagian yang sama, laporan direncanakan pada topik yang sangat terspesialisasi:

  • Eugene Rossinsky (ivi) pada sistem untuk mengumpulkan statistik terperinci tentang pengoperasian node CDN.
  • Anton Rusakova (Badoo) tentang integrasi sistem pembayaran tanpa menggunakan penagihan mereka sendiri.

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


All Articles