Czego używasz, gdy potrzebujesz niezawodnego UDP?

93

Jeśli masz sytuację, w której połączenie TCP jest potencjalnie zbyt wolne, a „połączenie” UDP jest potencjalnie zbyt zawodne, czego używasz? Istnieją różne standardowe niezawodne protokoły UDP, jakie masz z nimi doświadczenia?

Proszę omówić jeden protokół dla każdej odpowiedzi, a jeśli ktoś już wspomniał o tym, z którego korzystasz, rozważ głosowanie i użycie komentarza do opracowania, jeśli to konieczne.

Interesują mnie różne opcje, z których TCP znajduje się na jednym końcu skali, a UDP na drugim. Dostępne są różne niezawodne opcje UDP, z których każda przenosi niektóre elementy protokołu TCP do UDP.

Wiem, że często TCP jest właściwym wyborem, ale posiadanie listy alternatyw często pomaga dojść do takiego wniosku. Rzeczy takie jak Enet, RUDP itp., Które są zbudowane na UDP, mają różne zalety i wady, czy z nich korzystałeś, jakie masz doświadczenia?

Aby uniknąć wątpliwości, nie ma więcej informacji, jest to pytanie hipotetyczne i miałem nadzieję, że przyniesie listę odpowiedzi, które wyszczególniają różne opcje i alternatywy dostępne dla kogoś, kto musi podjąć decyzję.

Len Holgate
źródło
1
To pytanie wydaje się być nie na temat, ponieważ jest to ankieta dotycząca technologii
Dave Hillier,
Ci, którzy uważają, że TCP jest najlepszy we wszystkich przypadkach, przeczytaj: en.wikipedia.org/wiki/Bandwidth-delay_product
nullptr
Wikipedia ma ładną tabelę porównującą różne aspekty UDP, UDP Lite, TCP, Multipath TCP, SCTP, DCCP i RUDP . SCTP obsługuje większość funkcji z tej listy.
Evgeniy Berezovsky
@EugeneBeresovsky Zrobiłem trochę badań na temat SCTP, większość informacji, w tym z odpowiedzi SO, pochodzi z 2013 roku i wcześniej.Większość ludzi pisała wtedy, że adopcja SCTP była bardzo niska.Zastanawiam się, jak to jest dzisiaj? Zobacz też ten wątek stackoverflow.com/questions/1171555/…
Michael IV
@MichaelIvanov Adopcja jest rzeczywiście niska. Ale jeśli zamierzasz używać go w centrum danych, nie przejmujesz się adopcją zewnętrzną, o ile przełączniki i routery nie powodują problemów (których w centrum danych nie powinny), a masz system operacyjny i wsparcie biblioteki, co może stanowić problem, jak opisano w jednej z odpowiedzi na pytanie, do którego nawiązałeś łącze.
Evgeniy Berezovsky

Odpowiedzi:

25

Trudno odpowiedzieć na to pytanie bez dodatkowych informacji o domenie problemu. Na przykład, jakiej ilości danych używasz? Jak często? Jaki jest charakter danych? (np. czy są to niepowtarzalne, jednorazowe dane? Czy jest to strumień przykładowych danych? itp.) Dla jakiej platformy projektujesz? (np. komputer stacjonarny / serwer / urządzenie wbudowane) Aby określić, co rozumiesz przez „zbyt wolno”, jakiego medium sieciowego używasz?

Ale w (bardzo!) Kategoriach ogólnych myślę, że będziesz musiał bardzo się postarać, aby pokonać tcp dla szybkości, chyba że możesz poczynić twarde założenia dotyczące danych, które próbujesz wysłać.

Na przykład, jeśli dane, które próbujesz wysłać, są takie, że możesz tolerować utratę pojedynczego pakietu (np. Regularnie próbkowane dane, w których częstotliwość próbkowania jest wielokrotnie wyższa niż szerokość pasma sygnału), prawdopodobnie możesz poświęcić pewną niezawodność transmisji, upewniając się, że można wykryć uszkodzenie danych (np. za pomocą dobrego CRC)

Ale jeśli nie możesz tolerować utraty pojedynczego pakietu, będziesz musiał zacząć wprowadzać typy technik zapewniających niezawodność, które już posiada tcp. I bez wkładania rozsądnej ilości pracy może się okazać, że zaczynasz budować te elementy w rozwiązanie przestrzeni użytkownika ze wszystkimi nieodłącznymi problemami z szybkością.

Andrew Edgecombe
źródło
4
Ok, dostosuję pytanie. Bardziej interesują mnie zalety i wady różnych niezawodnych protokołów UDP, a nie odpowiedź typu „użyj TCP”;)
Len Holgate
9
@Andrew - bardzo ŁATWE jest pokonanie TCP w dwóch przypadkach: (1) Twoja aplikacja ma mniejsze wymagania dotyczące niezawodności niż „wszystkie dane, zawsze w porządku, bez duplikatów, bez nadmiernego kolejkowania”. Lub (2) używasz multiemisji. Niezawodny protokół UDP jest bardzo powszechny w środowiskach multiemisji.
Tom
4
Ponadto TCP strasznie cierpi, gdy jest używany przez połączenie WAN (problemy z długim dystansem). Dlaczego, proste. TCP używa okien, w których pakiety w oknie muszą zostać potwierdzone. Protokoły ACK cierpią z powodu opóźnień spowodowanych odległością linii. Google: WAN TCP „prędkość światła”
Ajaxx,
3
@Ajaxx, masz co do tego rację, jednak TCP / IP robi to celowo z powodu ostatniego załamania Internetu. Jeśli robisz protokół o wysokiej przepływności bez żadnej kontroli przeciążenia, wstydź się. Jeśli jesteś właścicielem sieci, zaszalej.
Kevin Nisbet,
2
„gdzie częstotliwość próbkowania jest znacznie wyższa niż częstotliwość Nyquista” - z definicji częstotliwość próbkowania jest zawsze dwukrotnie większa niż częstotliwość Nyquista.
Steve
27

A co z SCTP . Jest to standardowy protokół IETF (RFC 4960)

Ma zdolność kruszenia, która może pomóc w zwiększeniu szybkości.

Aktualizacja: porównanie między TCP i SCTP pokazuje, że wydajności są porównywalne, chyba że można użyć dwóch interfejsów.

Aktualizacja: ładny artykuł wprowadzający .

filant
źródło
To dobrze, bardziej interesują mnie rzeczy, które można zbudować na podstawie UDP niż na IP, ale z pewnością jest to coś, co pasuje do przestrzeni rozwiązań.
Len Holgate,
SCTP ma wiele wspaniałych funkcji (takich jak multihoming), a dzięki częściowemu rozszerzeniu niezawodności (RFC 3758) jest niezwykle elastyczną opcją. Jest zawarty w najnowszych wersjach jądra Linuksa, ale dla Windows będziesz musiał zainstalować własny stos SCTP.
Andrew Johnson,
6
SCTP może być tunelowany przez UDP. tools.ietf.org/id/draft-ietf-sigtran-sctptunnel-00.txt
Miles
Dzięki Miles, to przydatny link!
Len Holgate
1
Tak ... Ale coś, co jest zbudowane na bazie UDP, a nie na tym samym poziomie co UDP, prawdopodobnie będzie łatwiejsze do wdrożenia w przestrzeni użytkownika, przynajmniej w systemie Windows ...
Len Holgate
22

ENET - http://enet.bespin.org/

Pracowałem z ENET jako niezawodnym protokołem UDP i napisałem wersję przyjazną dla gniazd asynchronicznych dla mojego klienta, który używa go na swoich serwerach. Działa całkiem nieźle, ale nie podoba mi się narzut, jaki pingowanie peer to peer dodaje do bezczynnych połączeń; gdy masz dużo połączeń, regularne pingowanie wszystkich z nich jest bardzo pracochłonne.

ENET daje możliwość wysyłania wielu „kanałów” danych, a wysyłane dane są zawodne, wiarygodne lub sekwencjonowane. Obejmuje również wspomniany wcześniej ping peer to peer, który działa jak utrzymywanie przy życiu.

Len Holgate
źródło
14

Mamy kilku klientów z branży obronnej, którzy używają UDT (transfer danych oparty na UDP) (patrz http://udt.sourceforge.net/ ) i jesteśmy z niego bardzo zadowoleni. Widzę, że ma również przyjazną licencję BSD.

Chris Markle
źródło
2
Czy możesz opisać swoich klientów i ich przypadki użycia, szczególnie w sektorze obronnym? Raczej nie, ale warto spróbować. Właściwie rzuciłem moim przełożonym pomysł dotyczący UDT w aplikacji do przesyłania plików, ale tak naprawdę nigdzie to nie poszło.
Thomas Owens
10

RUDP - niezawodny protokół datagramów użytkownika

Zapewnia to:

  • Potwierdzenie odebranych pakietów
  • Kontrola okien i zatorów
  • Retransmisja utraconych pakietów
  • Nadmierne buforowanie (szybsze niż przesyłanie strumieniowe w czasie rzeczywistym)

Wydaje się, że jest nieco bardziej konfigurowalny pod względem utrzymania przy życiu niż ENet, ale nie daje tak wielu opcji (tj. Wszystkie dane są wiarygodne i sekwencjonowane, a nie tylko bity, które zdecydujesz, że powinny być). Wdrożenie wydaje się dość proste.

Len Holgate
źródło
Patrzyłem na to, ale wydaje się, że nie ma wielu wdrożeń. Masz rekomendację?
Nicholas,
Nie, przepraszam. W końcu nie użyłem go i zawsze zamierzałem wykonać implementację od zera.
Len Holgate,
9

Jak zauważyli inni, twoje pytanie jest bardzo ogólne i to, czy coś jest „szybsze” niż TCP, zależy w dużej mierze od typu aplikacji.

Protokół TCP jest generalnie tak szybki, jak to tylko możliwe, aby zapewnić niezawodne przesyłanie strumieniowe danych z jednego hosta do drugiego. Jeśli jednak aplikacja wykonuje dużo małych serii ruchu i czeka na odpowiedzi, bardziej odpowiedni może być protokół UDP, aby zminimalizować opóźnienia.

Jest łatwy środek. Algorytm Nagle jest częścią protokołu TCP, która pomaga zapewnić, że nadawca nie przytłoczy odbiornika dużego strumienia danych, powodując przeciążenie i utratę pakietów.

Jeśli potrzebujesz niezawodnego dostarczania w kolejności protokołu TCP, a także szybkiej odpowiedzi protokołu UDP i nie musisz martwić się o przeciążenie spowodowane wysyłaniem dużych strumieni danych, możesz wyłączyć algorytm Nagle:

int opt = -1;
if (setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY, (char *)&opt, sizeof(opt)))
  printf("Error disabling Nagle's algorithm.\n");
smo
źródło
Jak powiedziałem, zakładając, że TCP jest na jednym końcu skali, a UDP na drugim, co jeszcze jest.
Len Holgate
Jeśli chcesz być pedantyczny, większość omawianych protokołów jest zbudowanych na bazie UDP.
smo
Założenie, że TCP znajduje się na jednym końcu, a UDP na drugim, jest fałszywe. np. UDP nie ma kontroli przepływu, możesz łatwo wysyłać pakiety zbyt szybko, powodując, że router pomiędzy nimi odrzuca je wszystkie. Więc co robisz ? Zignorować utracone pakiety lub wysłać je ponownie? Wyślij je ponownie, a skończysz mniej więcej ponowną implementacją TCP. Inną opcją niezawodnej komunikacji jest SCTP.
nr
1
Szybka odpowiedź niekoniecznie oznacza wysoką przepustowość.
Matt
1
Nie zgadzam się. Kiedy nagle jest używane w protokołach opartych na TCP z wieloma mniejszymi pakietami, połączy je razem i utworzy więcej większych pakietów. Powoduje to niewielkie opóźnienie w wysyłaniu, więc opóźnienie może nieznacznie wzrosnąć. Jednak przepustowość może być niższa przy wyłączeniu nagle, ponieważ więcej pakietów = więcej nagłówków pakietów = większy narzut. Pakiety upuszczane w sieci LAN mają zwykle więcej wspólnego z wypełnianiem buforów wejściowych. Jeśli masz wielu klientów wysyłających dane do tego samego hosta, może to nie mieć żadnego znaczenia. Nie wierzę, że wyłączenie się i nagle nagle wpłynie na to w praktyce.
Matt
8

Każdy, kto zdecyduje, że powyższa lista nie wystarczy i że chce opracować swój własny niezawodny UDP, zdecydowanie powinien zapoznać się ze specyfikacją Google QUIC, ponieważ obejmuje ona wiele skomplikowanych przypadków narożnych i potencjalnych ataków typu „odmowa usługi”. Nie bawiłem się jeszcze implementacją tego i możesz nie chcieć lub potrzebować wszystkiego, co zapewnia, ale dokument jest wart przeczytania przed rozpoczęciem nowego, „niezawodnego” projektu UDP.

Dobry punkt wyjścia do QUIC jest tutaj , na blogu Chromium.

Aktualny dokument projektowy QUIC można znaleźć tutaj .

Len Holgate
źródło
4

Jeśli masz sytuację, w której połączenie TCP jest potencjalnie zbyt wolne, a „połączenie” UDP jest potencjalnie zbyt zawodne, czego używasz? Istnieją różne standardowe niezawodne protokoły UDP, jakie masz z nimi doświadczenia?

Kluczowym słowem w Twoim zdaniu jest „potencjalnie”. Myślę, że naprawdę musisz udowodnić sobie, że TCP jest w rzeczywistości zbyt wolny dla twoich potrzeb, jeśli potrzebujesz niezawodności w swoim protokole.

Jeśli chcesz uzyskać niezawodność z UDP, w zasadzie zamierzasz ponownie zaimplementować niektóre funkcje TCP oprócz UDP, co prawdopodobnie spowoduje, że wszystko będzie wolniejsze niż po prostu używanie TCP w pierwszej kolejności.

17 z 26
źródło
Tak, powiedział to Andrew Edgecombe, ale, jak powiedziałem, interesują mnie zalety i wady JAKICH istnieją alternatywy. Bez tej listy alternatyw i ich zalet i wad trudno jest zdecydować, co jest najlepsze.
Len Holgate,
Biorąc pod uwagę znaną funkcję niezawodności, czasami strumień UDP może być ręcznie dostrajany, aby wyprzedzić strumień TCP w systemie operacyjnym hte. Jednak rzadko.
Joshua
1
@ 17 z 26, zgadzam się z Len Holgate, TCP będzie wolniejszy niż niezawodny UDP w pewnych okolicznościach. Podobnie jak w przypadku wysokiej sieci BDP, załóżmy, że masz połączenie internetowe 1 Gb / s z Chin do Nowego Jorku, jestem pewien, że TCP będzie do niczego, aby wykorzystać prawie całą prędkość 1 Gb / s. TCP jest lepszy dla większości połączeń na Ziemi, ale nie dla sieci z produktem opóźniającym o dużej przepustowości.
nullptr
3

Może to być RFC 5405 , „Wytyczne dotyczące używania Unicast UDP dla projektantów aplikacji”.

bortzmeyer
źródło
2

Czy rozważałeś kompresję danych?

Jak wspomniano powyżej, brakuje nam informacji o dokładnym charakterze problemu, ale kompresja danych w celu ich przeniesienia może pomóc.

filant
źródło
1
Zwłaszcza w przypadku nowoczesnych bibliotek kompresji. Niektórzy są szybcy jak memcpy. np. lz4.
Matt
2

RUDP . Wiele serwerów z gniazdami do gier implementuje coś podobnego.

Inżynier
źródło
-2

Najlepszym sposobem na osiągnięcie niezawodności przy użyciu UDP jest zbudowanie niezawodności w samej aplikacji (na przykład poprzez dodanie mechanizmów potwierdzania i retransmisji)

kushan singh
źródło