TLDR: Główną wadą, którą możesz zauważyć, gdy multipleksujesz wiele kanałów nad TCP (jeśli zrobisz to dobrze), jest zwiększone opóźnienie z powodu blokowania „head-of-line” między kanałami.
Następstwo: jeśli nie zależy ci na opóźnieniu, wszystko powinno być w porządku.
Z drugiej strony użycie pojedynczego połączenia TCP „oznacza mniejszą konkurencję z innymi przepływami i dłuższymi połączeniami, co z kolei prowadzi do lepszego wykorzystania dostępnej przepustowości sieci” .
Blokowanie nagłówka linii przez TCP
Jeśli multipleksujesz wiele kanałów na tym samym strumieniu TCP, kanały mogą cierpieć z powodu blokowania „head-of-line” :
Blokowanie head-of-line (HOL) może wystąpić, gdy protokoły transportowe oferują usługę zamówioną lub częściowo zamówioną: Jeśli segmenty zostaną utracone, kolejne wiadomości muszą czekać na pomyślną retransmisję w kolejce odbiorczej, a zatem są opóźnione.
Kiedy multipleksujesz wiele strumieni na TCP, otrzymujesz HOL między kanałami .
Jeśli kanał A zapełnił bufor wysyłania TCP, musisz poczekać, aż wszystkie te dane zostaną odebrane, zanim jakiekolwiek nowe dane kanału B będą mogły zostać skutecznie przesłane do warstwy zdalnej aplikacji.
Zobacz „Multipleksowanie nad TCP”, aby uzyskać więcej informacji na temat kanałów multipleksujących nad TCP i dyskusji na temat hackernews .
Przykłady multipleksowania przez TCP
Multipleksowanie kanałów przez SSH (przez TCP)
Typowym tego przykładem jest SSH. SSH może multipleksowania wielu kanałów (patrz ControlMaster
, ControlPath
a ControlPersist
w OpenSSH). Korzystanie z tego zmniejsza koszt inicjowania nowej sesji SSH (początkowe opóźnienie), ale ciężki transfer na jednym kanale zwykle zwiększa opóźnienie / interaktywność innych (co nie dzieje się, jeśli używasz wielu strumieni TCP): jeśli używasz interaktywnego sesje i rozpocznij intensywne przesyłanie dużych plików na tym samym kanale, Twoja sesja zacznie być mniej interaktywna.
Multipleksowany HTTP / 2 przez TCP
HTTP / 2 wykorzystuje multipleksowanie żądań / odpowiedzi przez TCP w celu naprawienia blokowania HOL. Ta funkcja jest reklamowana w wielu artykułach i artykułach na temat HTTP / 2. W HTTP / 2 RFC zastrzeżeń:
HTTP / 1.1 dodał potokowanie żądań, ale ta tylko częściowo rozwiązana współbieżność żądań nadal cierpi z powodu blokowania na początku linii.
[...]
Wynikowy protokół jest bardziej przyjazny dla sieci, ponieważ można użyć mniejszej liczby połączeń TCP w porównaniu z HTTP / 1.x. Oznacza to mniejszą konkurencję z innymi przepływami i dłuższymi połączeniami, co z kolei prowadzi do lepszego wykorzystania dostępnej przepustowości sieci.
Jednak nie dyskutuje się, że blokowanie HOL nie zostało całkowicie rozwiązane. HTTP / 2 przez TCP nadal cierpi ) z powodu blokowania HOL na poziomie TCP .
Jest to omówione w tym
artykule LWN na temat QUIC:
HTTP / 2 został zaprojektowany w celu rozwiązania tego problemu za pomocą wielu „strumieni” wbudowanych w jedno połączenie . [...] stwarza nowy problem: utrata pojedynczego pakietu zatrzyma transmisję wszystkich strumieni jednocześnie, tworząc nowe problemy z opóźnieniami. Ten wariant problemu blokowania nagłówka linii jest wbudowany w sam TCP i nie można go naprawić za pomocą większej liczby poprawek na poziomie HTTP.
Inne strategie multipleksowania
SCTP
Jest to jedna z cech wyróżniających SCTP (multistreaming), możesz mieć wiele niezależnych strumieni w tym samym powiązaniu SCTP, a każdy strumień nie blokuje innych.
Zobacz SSH przez SCTP - Optymalizacja protokołu wielokanałowego poprzez dostosowanie go do SCTP w celu uzyskania efektu użycia SCTP w celu uniknięcia blokowania HOL międzykanałowego w SSH:
SCTP zachowuje tylko kolejność wiadomości w jednym strumieniu, aby złagodzić efekt znany jako blokowanie na początku linii. Jeśli wiadomość zostanie utracona, kolejne wiadomości muszą zostać opóźnione do momentu ponownego przesłania utraconej wiadomości w celu zachowania kolejności. Ponieważ tylko wiadomości z tego samego strumienia muszą być opóźnione, liczba dotkniętych wiadomości po utracie jest zmniejszona.
[...]
Dzięki odwzorowaniu kanałów SSH na strumienie SCTP korzyść z wielostrumieniowości jest udostępniana SSH, co stanowi ograniczenie blokowania „head-of-line” .
SCTP niekoniecznie jest łatwy do wdrożenia (ze względu na dostępność systemu operacyjnego, interakcję ze skrzynką pośrednią itp.). Możliwe jest wdrożenie go przez UDP w przestrzeni użytkownika .
QUIC (multipleksowanie przez UDP)
Innym przykładem jest eksperymentalny protokół QUIC używany do multipleksowania HTTP przez UDP (ponieważ multipleksowanie wielu strumieni na TCP, ponieważ HTTP / 2 cierpi na blokowanie HOL ):
QUIC to nowy transport, który zmniejsza opóźnienie w porównaniu do TCP. Na powierzchni, QUIC jest bardzo podobny do TCP + TLS + HTTP / 2 zaimplementowanego na UDP.
[...]
Multipleksowanie bez blokowania nagłówka linii
Protokół Google QUIC: przeniesienie sieci z TCP na UDP zapewnia dobry przegląd blokowania QUIC i HOL podczas multipleksowania kanałów na TCP.
Niedawna prezentacja twierdzi, że HTTP przez QUIC poprawia opóźnienie, ale poprawa blokowania HOL jest „mniejszą korzyścią”:
0-RTT, ponad 50% poprawy opóźnienia
[…]
Mniej retransmisji opartych na limicie czasu poprawia opóźnienie ogona […]
Inne, mniejsze korzyści, np. Blokowanie szefa linii
Zauważ, że chociaż QUIC jest opisany jako „bardzo podobny do TCP + TLS + HTTP / 2 zaimplementowany na UDP”, w rzeczywistości jest to transport ogólnego przeznaczenia, który może być używany niezależnie od HTTP / 2 i może odpowiadać twoim potrzebom.
Uwaga: HTTP / QUIC si zostanie znormalizowany jako HTTP / 3 .
Powiedziałbym, że musisz przeczytać Przewodnik ZeroMQ , wzorce, które podaje z przyczynami i wadami, są niezbędne.
Ale w przeciwnym razie nie ma problemu z odłączeniem kanału sieciowego od dostarczania danych aplikacji. Będziesz musiał wziąć pod uwagę multipleksowanie i demultipleksowanie wysłanych pakietów danych (i zaleciłbym tutaj architekturę opartą na pakietach, nie przesyłając strumieniowo danych w ciągłym przepływie) i buforowanie ich na każdym końcu.
W przeciwnym razie może to mieć niewielki wpływ, może być potrzebna więcej pamięci - ale tylko nieznacznie - do buforowania danych i trochę więcej procesora, ponieważ obsługuje się więcej kodu do blokowania i analizowania pakietów, ale nic znaczącego. (chyba że piszesz coś specjalistycznego, co wymaga dużej przepustowości, a wydajność ma krytyczne znaczenie).
źródło
Tak, zbudowałem system bazy danych klient-serwer, stosując dokładnie tę zasadę.
Kanały multipleksowane na jednym połączeniu TCP wysyłają pakiety danych, które są następnie rozdzielane do odpowiednich odbiorców na drugim końcu.
Przenoszenie połączenia przez jeden szalony kanał jest wykonywane przez nadawcę połączenia TCP, który dokonuje okrągłego wyboru, który pakiet ma zostać przesłany spośród kanałów, które mają gotowe dane do wysłania.
Aby poradzić sobie z przypadkiem, gdy jeden kanał decyduje się na wysłanie pakietu 1 GB i blokuje wszystkich pozostałych, nadawca może podzielić pakiet na części i wysłać tylko jedną część, zanim nada kolejnemu kanałowi kolej. Na końcu odbierającym ponowne składanie fragmentów w pakiet jest wykonywane, zanim odbiorca zobaczy pakiet.
źródło