Czy warto multipleksować strumienie blokujące w połączenie TCP?

13

Potrzebuję kilku kanałów dupleks między dwoma hostami. Istnieje wiele zalet ustanowienia tylko jednego połączenia TCP. Ale wątpię, by multipleksowanie spowodowało pewne nieuniknione problemy. Czy zaszkodzi to wydajności lub znacznie zwiększy opóźnienia? A co z wykorzystaniem pamięci i procesora? Czy masz jakieś sugestie lub zastrzeżenia?

Sherwood Wang
źródło

Odpowiedzi:

10

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, ControlPatha ControlPersistw 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 .

ysdx
źródło
Nie sądzę, aby HOL był prawdziwym problemem, jeśli istnieje mechanizm kontroli przepływu. Otwarte wiele połączeń TCP tworzy również wiele buforów okien, które mogą nie być bardziej wydajne pod względem pamięci.
Sherwood Wang
Rozważyłem SCTP. Wygląda jednak na to, że SCTP nie był jeszcze zbyt przenośny, a urządzenia NAT źle go obsługują.
Sherwood Wang
@ SherwoodWang, Posiadanie mechanizmu kontroli przepływu w protokole multipleksowania nie zapobiegnie blokowaniu HOL.
ysdx
Gdy u nadawcy nie ma dostępnych danych, nadawca może wysłać ramkę kontroli przepływu, aby poinformować odbiorcę o przełączeniu do następnego multipleksowanego kanału i kontynuować wysyłanie ramek danych tego kanału. Gdy odbiornik jest pełny, można również zastosować podobny mechanizm. Zdecydowanie zapobiega blokowaniu HOL z zaledwie połową opóźnienia w obie strony.
Sherwood Wang
@ SherwoodWang, problem TCP HOL jest naprawdę po stronie odbierającej. Jeśli jakiś pakiet został utracony podczas transmisji, odbiornik nie może przekazać następujących pakietów do przestrzeni użytkownika. Musi poczekać, aż pakiet zostanie ponownie przesłany i odebrany. Wszystkie ponownie powiązane dane (zdarzenie z innego multipleksowanego strumienia) są blokowane do momentu odebrania tego pakietu.
ysdx
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).

gbjbaanb
źródło
2

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.

Martin Kochański
źródło