QUIC’te Datagram Olmadan Zamanındalık Sağlamak
(quic.video)- Canlı video ve internet sohbetlerinde önemli olan “güvenilmez iletim”in kendisi değil, eski verileri geriye itip en güncel verileri zamanında iletmektir
- Bir yönlendirici tıkanmış paketleri atmayıp kuyrukta uzun süre biriktirirse bufferbloat oluşur; gerçek zamanlı hizmetlerde bu, arabelleğe almaktan daha kötü gecikmelere yol açabilir
- Doğrudan UDP üzerinde protokol oluşturursanız yeniden iletim, tıkanıklık kontrolü, şifreleme, RTT tahmini, yol doğrulama, akış kontrolü vb. şeyleri yeniden uygulamanız gerekir; bu yüzden QUIC kütüphanesi kullanmak daha güvenlidir
- Yalnızca QUIC ile de gecikme tabanlı tıkanıklık kontrolü, bağımsız stream bölme ve önceliklendirmeyi birleştirerek datagram olmadan zamanındalık sağlanabilir
- QUIC, WebTransport ve MoQ standartlarına datagram desteği ekleniyor olsa da sonuç, yeni bir video protokolünü UDP üzerine tekrar yığmak yerine Media over QUIC akışına uymanın daha iyi olduğu yönünde
Amaç “istikrarsızlık” değil, zamanındalık
- TCP ve UDP seçimi çoğu zaman “güvenilir iletim” ve “güvenilmez iletim” olarak açıklanır, ancak uygulamaların istediği şey istikrarsızlığın kendisi değildir
- Canlı videoda veya internet sohbetlerinde eski verilerin tamamını almaktansa en güncel verinin önce ulaşması daha önemlidir
- Gerçek zamanlı bir konuşmada yüzün üzerinde arabelleğe alma döndürücüsü çıkması ya da 5 saniye önceki sesi duymak istenmez
- Canlı video sektörü ve oyun sektörü, bu zamanındalık için TCP stream’leri yerine sık sık UDP datagram’ları kullanır
Datagram’lar ve ağ kuyrukları
- Datagram, kaynak adresten hedef adrese gönderilen 0 ve 1’lerden oluşan bir zarftır; genellikle güvenli boyut olarak 1200 bayt kabul edilir
- Datagram’lar sessizce kaybolabilir ve sırası değişmiş şekilde varabilir
- Fiziksel katmanda veri analog sinyale dönüştürülüp ortamdan geçer; serileştirme, ters serileştirme, arabelleğe alma, kuyruğa alma, yeniden iletim, atma, bozulma, gecikme, yeniden sıralama, çoğaltma ve kayıp yaşanabilir
- Ağa çok fazla veri girerse yönlendiriciler rastgele bitleri değil, paket sınırlarında veriyi atar
Bufferbloat ve tıkanıklık kontrolü
- Yönlendiriciler paketleri hemen atmayıp kuyrukta biriktirdiğinde bufferbloat oluşur
- Bufferbloat tüm paketleri saniyelerce geciktirebilir ve gerçek zamanlı iletim için en kötü durumu yaratır
- Kuyruğa almayı önlemek için paket varış zamanı geri bildirimiyle yönlendirici kuyruğu tahmin edilmeli, gönderici de gönderim miktarını azaltarak kuyruğu boşaltmalıdır
- Bu alan tıkanıklık kontrolü kapsamına girer; paketleri sınırsız hızda göndermek felakete yol açabilir
Doğrudan UDP üzerinde inşa ederken üstlenilen işlevler
- UDP’yi doğrudan kullanarak bir aktarım protokolü oluşturmak için en azından şu işlevler gerekir
- Daha iyi bir protokol oluşturmak için şu işlevler de gerekir
- Olgunluğu artırmak için çalışma ortamını ve dağıtımı da dikkate almak gerekir
- WebRTC, SRT, Sye, RIST gibi canlı video protokolleri UDP üzerinde oluşturulmuş örneklerdir
- Bu da yeni bir protokolü doğrudan oluşturmaktansa QUIC kütüphanesi kullanmanın daha iyi olduğu sonucuna götürür
QUIC stream’leriyle zamanındalık sağlamak
- QUIC’te zamanındalık elde etmenin yolları üç başlıkta özetlenebilir
- Arabellek şişmesini önleme: BBR gibi gecikme tabanlı tıkanıklık kontrolü kuyruğa almayı algılar ve gönderim miktarını azaltır
- WebRTC’nin transport-wide-cc’si daha iyi bir yönteme örnek olarak görülebilir
- Stream bölme: Her stream içindeki baytlar sıralıdır ve güvenilir biçimde iletilir; stream’ler video karesi, oyun güncellemesi, sohbet mesajı, JSON blob gibi atomik birimler olabilir
- Stream önceliklendirme: Stream’ler bağımsız olduğu için sıradan bağımsız olarak varabilir ve QUIC stack’ine önemli stream’leri önce iletmesi söylenebilir
- Düşük öncelikli stream’ler aç kalabilir; bant genişliği israfını önlemek için kapatılabilir
- Bu yaklaşım Media over QUIC’in özüdür
- Datagram’ların fire-and-forget niteliği yalnızca gerçek zamanlı gecikme gerektiğinde uygundur; bunun dışında QUIC stream’leri kullanılabilir
Datagram’lar etrafındaki uzlaşmalar ve istisnalar
- QUIC ve ilgili standartlar datagram desteğini de içerir
- QUIC, genişletme yoluyla datagram desteği sağlar
- WebTransport datagram desteğini zorunlu kılar
- Güncel MoQ sürümü datagram desteği eklemiştir
- Sonraki MoQ sürümünün datagram desteğini zorunlu kılması bekleniyor
- Datagram desteği, uygulaması önemsiz olduğu ve denemelere izin verebildiği için dahil edilebilir
- OPUS yerleşik FEC desteğine sahiptir; bu da MoQ’nun her ses “frame”ini datagram olarak gönderme işlevini desteklemesine örnek olur
- Eski bir protokol olan DNS istisna sayılabilir, ancak yeni tasarımlarda DNS over HTTPS gibi bir yönü izlemenin daha iyi olduğu düşünülür
- Sonuç, yeni bir video protokolünü UDP üzerinde yeniden oluşturmak yerine Media over QUIC’e katılmaya götürür
1 yorum
Hacker News yorumları
Örneğin NB-IoT gibi en kötü durumda gidiş-dönüş gecikmesinin 10 saniye olduğu ortamlarda, el sıkışma ve MTU keşfi için gidiş-dönüş süreleri boşa harcanıyor; artık işe yaramayan verileri de göndermeye devam etmeye çalışıyor; kapsama kötüleşip gecikme artınca TCP bunu tıkanıklık kaynaklı paket kaybı olarak görüp bant genişliğini düşürüyor
Ayrıca yük dengeleyiciler ya da middlebox’lar “4 saniyedir yanıt yok, herhâlde kayboldu” deyip bağlantıyı kesebiliyor; TCP’nin veri yapısını dikkate almadan paketleri bölmesi nedeniyle tamamı alınmadan yorumlanamaması da ayrı bir eksiklik
Bazı durumlarda yararlıdır, ancak n’inci paket henüz yokken n+1’inci paketten yararlanılabilecek çok durum vardır
Büyük dosya aktarımında silinti kodlaması ile %5 paket kaybı otomatik olarak işlenebilir ya da fountain code kullanılarak alıcı “hepsini aldım” diyene kadar gönderim yapılabilir
fountain code, derin uzay sondalarının veri gönderme biçimidir; Jüpiter ya da Mars’a kadar olan gecikme de epey ciddidir
TLS el sıkışmasını başlatmak için TCP el sıkışmasının bitmesi gerekir, ancak QUIC ilk el sıkışmanın içinde TLS pazarlığını işleyen protokol düzeyi desteğe sahiptir
Ağ protokolü ile şifrelemeyi gevşek biçimde birleştirebilmek daha zarif görünebilir, ama artık neredeyse tüm aktarımların şifrelendiği bir dünyada her bağlantıda bir gidiş-dönüş süresini azaltabilmenin pratik avantajı daha büyük görünüyor
R&D tarafında QUIC kullanan yeni bir sistem yaptılar ve sırası değişerek gelen verilerle ilgili sorunların çoğunu çözdüler, ancak adaptör olmadan doğrudan desteklenmesi gereken üçüncü taraf sensörler yalnızca UDP desteklediği için hâlâ her şeyde UDP datagramları kullanılıyor
Daha yaygın ve daha iyi ifade best-effort; UDP datagram teslimi için elinden geleni yapar, yalnızca datagramlar düşürülebilir
Bu, UDP’nin doğası gereği güvenilmez olduğu anlamına gelmez
https://en.wikipedia.org/wiki/Best-effort_delivery
Gerçekte A’dan B’ye bir mesaj göndermek için sonuna kadar uğraştığı anlamına değil, daha çok “denedik işte” anlamına gelir
Yoldaki bir yönlendirici tıkalıysa ya da link flap yüzünden hızlı yeniden yönlendirme öncesi yaklaşık 50 ms’lik bir blackhole oluşursa sonuç “eh, denedik” olur
Buna karşılık TCP’nin güvenilir teslimi birçok kez yeniden dener ve uygulamaya sırası doğru bir veri akışı sunar
reliable/unreliable da kötü terimler olabilir ama best-effort’ün daha iyi olduğunu söylemek zor
Güvenilir olmayan sistemler yaklaşık %95 oranında harikadır ve ham throughput için de iyidir; ancak son %5’in çok büyük fark yarattığı durumlar sık görülür
“Çaba” genelde zorluk karşısında bir miktar ısrar anlamına gelir; kaynak sorunu çıktı diye paketi atmak çaba diye adlandırılamaz, best effort hiç denemez
Hukuk ve iş dilindeki “best efforts”, kesin taahhütten daha zayıftır ama açıkça eli kolu bırakmak da değildir; ağ dünyasındaki kullanımı bundan epey farklı
Ayrı olarak UDP ve TCP’nin checksum’ları da datagram teslim edildiğinde bütünlüğü iyi garanti etmez; donanımdan sadece biraz daha iyidir
Ama best-effort, teslim garantisi için bir şeyler yapılıyormuş hissi veriyor; gerçekte ise garip görünen ya da şanssızlık eseri dolu bir buffer’a denk gelen paket basitçe atılıyor
lossy hoşuma gidiyor, ama bu “zor problem sadece iki tanedir” kapsamındaki adlandırma sorunlarından biri
Paketin ulaşması gerekiyorsa TCP kullanın; çok önemli değilse UDP kullanın
Basitleştirilmiş bir açıklama ama best effort aptalca bir terim; içinde effort yok
Tıkanıklık kontrolü kesinlikle gerekli, ama onun dışında çok soru işareti var
Datagram öncelikli bir dünyada birden fazla veri bağlantısını çok verimli biçimde birleştirmek ya da ağ sınırları arasında dolaşırken bağlantıyı koparmadan roaming yapmak sorun olmazdı
Birçok uygulama sırası değişmiş frame’leri ek maliyet olmadan işleyebilir ve UDP modeline göre yazılırsa çok daha hızlı olabilir
Gerçekte daha düşük güvenilirliğe sahip bir aktarım yöntemine geçmek, yazılımı otomatik olarak daha güvenilir ya da verimli hâle getirmez
Aksine, ekibin ele alması gereken hata modları ve karmaşıklık ciddi ölçüde artar
Yine de bağlantının bir yerinde dar bir darboğaz varsa, zaten o darboğazda atılacak paketleri muazzam miktarda üretmenin pek anlamı yok gibi görünüyor
Web siteleri, ses ve video genel olarak sırası değişmiş karelerle pek uyumlu değildir; çoğu kişi de sesin ya da videonun kesilmesini istemez
Bazı video oyunlarında eksik paketler yok sayılabilir, ama bu tür durumlar zaten UDP ile yazılmıştır
Çünkü bu paketler yeniden gönderilmeyeceğinden, fazla trafiği azaltmanın etkili bir yolu olduğu düşünülür
Şimdi UDP üzerinde agresif biçimde yeniden iletim yapan protokoller ortaya çıktı; bunun durumu nasıl değiştirdiğini merak ediyorum
Birkaç yıl önce QUIC’in bu yüzden HTTP/1·HTTP/2’ye kıyasla yeniden iletim sorunları yaşadığını da hatırlıyorum
Makalede daha temsilî bir ifade bulunabilirse tekrar değiştirebiliriz
Bu, HN başlık yönergelerindeki “özgün başlığı kullanın; yanıltıcı veya yemleme niteliğindeyse istisna” kuralına dayanıyor: https://news.ycombinator.com/newsguidelines.html
Uygulamaya bağlı olarak mantıklıdır
Örneğin gerçek zamanlı çok oyunculu bir oyunda işlem geride kalırsa, oyun durumu zaten değişmiş olduğundan geride kalan öğeler artık önemli değildir
Yüksek frekanslı işlem uygulamalarında da bazı durumlarda 100 ms önce olan değil, yalnızca en güncel piyasa verisi önemlidir
Yazı, UDP’nin uygun olduğu örnekler olarak oyunları ve canlı videoyu da veriyor
Başta “yaygın kanı”yı sunup ardından ona karşı çıkan bir yapısı var
Örneğin DHCP, SLAAC, UPnP, mDNS, tinc, BitTorrent gibi yerel keşifler; yerel ağ akışı gibi broadcast kullanımları; WireGuard, IPSec, OpenVPN, VLAN gibi kapsüllemeler buna girer
Yeniden iletim bir yana, sırayı yeniden düzenlemek için yapılan tamponlama bile gecikmeyi artırdığından, kaybı hata düzeltme veya paket kaybı gizleme ile tolere etmek daha iyidir
UDP ile TCP’nin davranışları ve ödünleşimleri farklıdır; mesele yalnızca kullanım senaryonuza göre seçim yapmadan önce bunları anlamaktır
“X’i asla yapma” türü kapı bekçiliğine gerek yok
Sadece başlığa bakınca bile bunun insanları UDP kullanmaktan alıkoymaya çalışan bir yazı olmadığı oldukça açık
Nitekim yazının sonunda yazar UDP tabanlı QUIC kullanımını öneriyor
Elbette çok daha fazla ayrıntıyı kendinizin halletmesi gerekir
Bonus olarak, ağların düşük seviyeli yönlerini öğrenmenin de iyi bir yoludur