Как стать автором
Обновить

TCP против UDP или будущее сетевых протоколов

Время на прочтение27 мин
Количество просмотров170K
Всего голосов 162: ↑159 и ↓3+156
Комментарии75

Комментарии 75

Самый нестабильный WIFI с потерями обычно во время путешествия — в отеле, в аэропорту, на вокзале. Но в таких местах и UDP обычно заблокирован, открыта только TCP дырочка на 443 и 80.
НЛО прилетело и опубликовало эту надпись здесь
сейчас UDP недоступен менее чем в 3% сетей и число таких сетей стремительно падает
на случай недосупности UDP почти во всех протоколах есть есть fallback на TCP
Точно не знаю, но предполагаю что торренты блокируют.
Все круто расписали, даже без конечной цели инфа очень полезная, но результаты, честно говоря, не впечатляют и смахивают на стат. погрешность… Стоило ли оно усилий, городить свой TCP поверх UDP?
используя свой протокол поверх UDP получилось на 7-10% увеличить скорость загрузки контента (API + картинки) на устройства пользователя, гугл сейчас публикует более скромный результат для QUIC в 3%
увеличение пользовательской активности на 1% оценено на десятках миллионов DAU по системе А/Б тестирования, основанной на матстатистике
которая говорит что с вероятностью 99.98% именно изменение протокола приводит как минимум к 1% роста активности )
но мы продолжаем работы над протоколом и эксперименты

Ну, если вы делаете универсальный транспорт с гарантированной доставкой, то вы в тех же условиях, как и те, кто совершенствует TCP.
А значит, драматически отличных результатов ожидать не стоит.


Но если это user space stack, можно было бы использовать дополнительную информацию, которая у вас есть в приложении – о данных, о сессиях?
TCP этого знать не может.

да, мы используем дополнительную информацию с уровня приложения
и это не универсальный транспорт, это транспорт доставки сообщений длинной до 1Мб в беспроводных сетях
«Совершенствует TCP» — это вы отлично пошутили.

Представил себе миллиарды маршрутизаторов по всему миру в которые залетает свежий апдейт с поддержкой новейших фич TCP прямо в день их выхода.
Да, но у вас throughput в 5 раз просел…
в ОК порядка 8000 серверов
сервера раздающие трафик составляют менее 5% оборудования, мы можем себе это позволить )
а throughput мы поднимем, как только появятся доработки ядра под UDP
Хорошо было бы иметь протокол стандартизированный, который можно настраивать, выбирая те фичи и гарантии, которые тебе нужны. Порой TCP или UDP выбирают в тех ситуациях, где было бы лучше что-то посередине, но это сложно, поэтому берут что есть и либо пилят костыли, либо живут с недостатками. Смотришь на какой-нить RTMP — да, TCP очень сильно упрощает протокольную часть, но за это приходится платить гарантиями TCP, которые тут не нужны и мешают только. Не разбирался правда, есть ли у QUIC возможность такой конфигурации.
согласен, было бы круто сказать что у тебя в рамках мультиплексированного соединение есть не только приоритеты, но и возможность иметь стрим с гарантированным packet loss, например не более 1% PL (для видео этой пройдет незаметно)
или сказать что есть стрим, где пакеты теряют свой смысл после задержки более 1 сек, для конференц связи или live трансляций например
для медиастриминга мы используем друго свое решение habr.com/ru/company/oleg-bunin/blog/413479
а далее читаем про эффект «TCP Starvation/UDP dominance» и начинаем грустить.
Потому как благое начинание сделать эффективный протокол мешает жить другим и тупо ломает сеть.
вы не замечали, что при прочих равных google сайты и сервисы работают быстрее?
Google сначала они придумали BBR (congestion control в TCP), который в случае конкуренции за канал с другими congestion control-ами их выжимает
никто не знает, какой CC у google сейчас на серверах как для TCP так и для QUIC/UDP
но уверен что самый агрессивный из доступных
Мне кажется что с «прочими равными» на практике сравнивать Google затруднительно, т.к. его точки входа находятся буквально везде и конкуренция за канал минимальна, потому что она заканчивается на узле связи провайдера (в самом крайнем случае- эксченджа), где гугл воткнут в роутер отдельным портом с каналом заведомо достаточно широким, чтобы отдавать все что нужно максимально быстро.
Ну то есть очевидно в каких-то условиях BBR имеет влияние, но оценить его крайне сложно.
На RIPE 76 обсуждалась проблема того, что соединения с BBR угнетают другие соединения и предложена концепция BBR2. www.slideshare.net/apnic/tcp-and-bbr
Чем мне UDP нравится, так это за его простоту и понятность протокола.
В TCP только версий RFC уже две: RFC 761 и 793, не говоря про расширение RFC 1323.
А у UDP как был RFC 768, так он и остался.
подробности для желающих уточнить
Если где какую RFC забыл, прошу поправить в комментариях.
С приходом UDP будет наверное еще больше RFC для протоколов поверх. Тот же QUIC. Голый UDP мало кому нужен и полезен. И ладно если RFC будет. Как было так и продолжится туча проприетарных малодокументированных поделок поверх, которые добавляют тот или иной компонент надежности.
Крутой доклад, очень по6равился.

Статья для сильных духом!


На самом деле любой packet loss — следствие того, что сеть перегружена

Тут, наверное, пропущена частица "не": На самом деле не любой packet loss...


Также можно зайти в сеть в браузере и тоже увидеть, что там есть GQUIC.

Интересно, что у меня в Хроме (76 версия) нет колонки Protocol, вместо нее Type. Не нашел, как включить.


Если вы будете писать свой протокол, вам нужен чек лист:

Если у вас нет ресурсов, готовьте свою инфраструктуру под QUIC. Он рано или поздно к вам придет.

На мой взгляд, в этих местах грех не упомянуть про Aeron, который, во многом — обобщенный фреймворк поверх UDP (с решением многих проблем, перечисленных в этом докладе) для простых смертных.

да, в каждой версии Chrome что-то меняется по диагностике работы QUIC
wireshark точно поможет найти quic пакеты )
мы делали свой протокол поверх UDP исключительно для беспроводных сетей, учитывая их особенности по bw/pl/jitter
например у нас есть FEC )
Aeron подойдет для высокоскоростных магистралей и сетей уровня ДЦ
но challenge accepted — сделаю тесты

Интересно. FEC работает в проде?

Работает, но его нужно правильно готовить )
в следующем докладе обязательно расскажу

По заголовку колонок щёлкаете, там можно выбрать дополнительные. У меня тоже отключено было по умолчанию. После включения, кстати, QUIC нигде не нашёл, только h2 (HTTP/2.0, видимо).

Очень крутой доклад, большое спасибо. Как пример реализации multipath на основе UDP могу добавить LRT (LiveU Reliable Transport).
Для мультиплексирования можно SCTP использовать. Не понятно, зачем было пилить QUIC, если можно было допилить SCTP.
у SCTP есть минусы:
— нет IP-migration
— 4-way handshake вместо 0-RTT
— на старте соединение нужно указать кол-во потоков
— не решает проблему head-of-line-blocking для стримов

tools.ietf.org/html/draft-joseph-quic-comparison-quic-sctp-00
Все 4 пункта — враньё.

А чуть более развёрнуто можно?

Развёрнуто там уже на пачку документов в Standards Track, я только некоторые по теме сказанных перечислю:

— нет IP-migration

Непонятно, что alatobol имел в виду под миграцией, то ли смену адресов на ходу, то ли миграцию а-ля IPv4 -> IPv6, но в SCTP позаботились об обеих проблемах, потому два:
RFC 5061 Stream Control Transmission Protocol (SCTP) Dynamic Address Reconfiguration
RFC 6951 UDP Encapsulation of Stream Control Transmission Protocol (SCTP) Packets for End-Host to End-Host Communication

— на старте соединение нужно указать кол-во потоков

RFC 6525 Stream Control Transmission Protocol (SCTP) Stream Reconfiguration

Про 4-way надо отдельно пояснить, оно типа «вроде бы правда» — на самом деле, нет, это защита от SYN flood (то, что в TCP с ограниченным успехом делают syn cookies). И такое требование, защиты от пира, которого вы еще не знаете, будет неизбежно для любого протокола. В том числи и для QUIC (и даже особенно для QUIC ввиду легкости спуфинга UDP). Зато в SCTP передача данных идет штатно уже на третьем пакете — то, что из TCP когда-то выкидывали, а сейчас пытаются возродить в виде TFO.

То есть, почувствуйте разницу и тонкость манипуляции: 4-way handshake в первый раз vs 0-RTT потом (и то вовсе не при любых условиях).

Но самое наглое вранье, конечно, про head-of-line-blocking — SCTP именно в том числе для того создавался, чтоб потеря пакета в одном потоке не тормозила остальные.

В целом, что касается современных драфтов IETF — мне попадался уже один, предлагавший API BSD-сокетов заменить, где автор плавал в теме. Так что качеству драфта от Гугла, тем более преследующего цель показать свой продукт в выгодном свете, я уже не удивляюсь.

Вот взять хотя бы один из ключевых вопросов архитектуры: мы, типа, решили в QUIC оставить семантику потока байт. А где обоснование, НАХЕРА?.. Большое количество протоколов поверх TCP вынуждено изобретать свой фрейминг, например. Что, говорите, так в HTTP было?.. Тогда тут же возникают уже 2 вопроса:
— если у вас частное решение для HTTP, тогда сравнение с общим протоколом имеет мало смысла
— если вы всё равно новую версию протокола делаете, не пора ли отойти от втискивания всего во всё тот же старый концепт безразмерного потока байт?..
И т.д.
А где обоснование, НАХЕРА?

У меня после многочисленного количества переизобретений протоколов поверх TCP разного назначения появилось стойкое ощущение, что потоковые протоколы бесполезны. Даже если ты передаешь реально какой-то поток (кроме файлов есть что-то еще?), то все равно он передается блочно и любой фреймовый протокол отлично подойдет для этого. Потоковый же протокол только постоянно требует изобретать фрейминг. Вот правильно в websocket сделали.
Websocket — отличный пример протокола-костыля, который не нужен от слова «совсем», работай оно всё поверх SCTP. Да и сейчас-то, на TCP, он тоже вызывает кривую физиономию…

реально какой-то поток (кроме файлов есть что-то еще?),


Нуу… подумал и придумал рафинированный пример: несжатый 8-битный PCM audio :)
Websocket в том смысле, что поверх TCP они реализовали фреймовый протокол. Это было очень правильным решением.

Нуу… подумал и придумал рафинированный пример: несжатый 8-битный PCM audio :)

Ну да, натянуть такое можно. Просто в реале даже аудио пишется фреймами, которые в зависимости от кодека самый разный размер могут иметь. Плюс API обычно эти фреймы пачками выдают так или иначе.
про head-of-line-blocking

Я так понял, alatobol про то, что если в каком-то одном стриме потеряется SSN, то на принимающей стороне отправка «наверх» по данному стриму приостановится, пока этот SSN не дойдет.
Не уверен, но вроде тоже был какой-то драфт про «сброс» стрима, т.е. забыть, что что-то потерялось и продолжать, как будто бы чанк с этим SSN дошел.
Я так понял, alatobol про то, что если в каком-то одном стриме потеряется SSN, то на принимающей стороне отправка «наверх» по данному стриму приостановится, пока этот SSN не дойдет.

Ну так внутри потока эта проблема будет для любого протокола, который ориентирован на собственно поток — ведь верхний уровень «дырку» не поймёт. Но не заблокируются соседние потоки, в отличие от мультиплексирования всех потоков в одном TCP-соединении.

Если протокол приложения таков, что это действительно составляет проблемы, тогда надо:
  1. Уменьшать размер фрейма, до «меньше типичного MTU»
  2. Использовать Unordered-фреймы (в SCTP есть), им пофиг


Не уверен, но вроде тоже был какой-то драфт про «сброс» стрима, т.е. забыть, что что-то потерялось и продолжать, как будто бы чанк с этим SSN дошел.


Сброс стримов тоже был (уже RFC 6525, не драфт), но Вы, судя по всему, о Partial Reliability, т.е. разрешать потерю некоторых пакетов (для гейминга, скажем) — да, такое в SCTP тоже есть (RFC 3758).
но Вы, судя по всему, о Partial Reliability

Вроде бы и да, а вроде бы и нет, надо вчитываться в RFC :-)
Слегка пробежался и вроде бы в Partial Reliability вперед пропихивается cumulative TSN, а значит это может повлиять на несколько стримов, т.е. если у нас есть стримы, по которым мы осуществляем надежную доставку и стримы, где допускается дроп чанков, то подвинуть cumulative TSN мы сможем не всегда. Например, не cможем, пока в стримах с надежной доставкой есть гапы.

Мне эта фича видится немного по другому: двигать не cumulative TSN, а SSN и с SSN, если надо, то и cumulative TSN (хотя, наверное для некоторых протоколов подойдет unordered delivery, это надо каждый случай/протокол разбирать, анализировать...).
Я все же про «допиливание»: у гугла много ресурсов, было бы здорово, если бы они допилили именно SCTP — написали бы драфты в IETF (или вообще довели бы их до законченных RFC), вместо того, что бы пилить свой GQUIC. Но это так, чисто мои хотелки :-)
Да что там допиливать-то, всё уже есть. Разве что новые congestion control те же… Главное, что от их размеров было бы толково — популяризация, а значит включение поддержки остальными, и тогда протоколом смогли бы пользоваться большинство разработчиков.

А драйвер SCTP для Windows уже перестал ломать возможность отправки HTTP-запросов у приложений на .NET Framework?

Тем паче, что в сетях VoLTE широко используется протокол diameter как раз поверх sctp, к концу года ожидается нагрузка на сети в размере полумиллиарда пакетов диаметра в секунду. Выбор sctp был не случайным, ведь диаметр отвечает за кредит-контрол и тп вещи и был нужен устойчивый к потерям и обнаружению факта потерь, тип протокола. Так что у sctp хорошие перспективы, особенно после ввода 5G в массовую эксплуатацию.

Спасибо за отличную статью.


Описанная выгода от использования нескольких параллельных TCP совпадает и с личным опытом.


На Android 9 я видел TFO на эмуляторе

Проверил на несколько дней назад обновившемся телефоне.


Похоже, на железе тоже уже есть. Или это Termux отсебятину показывает?


Packet pacing, TCP, disabled by TSO

Не раз сталкивался, что TSO (скорее всего из-за багов в реализации) приводит к нестабильности TCP соединений. И её отключение увеличивает как стабильность, так и скорость.


Возможно, кому-то пригодится заметка как packet pacing можно использовать с TCP на Linux в т.ч. в сочетании с параллельными соединениями.

когда мы смотрели на реальных устройствах было выключено (смотрели samsung-и, meizu, huawei), очень здорово, если включили

спасибо за TCP pacing!, на досуге попробую сделать эксперимент на пользователях )
А я вот проверил телефон (тоже Android 9, Asus) на предмет TLS 1.3 и тоже есть.
Вот рута, чтобы проверить TFO, у меня нет.
Я знаю отличную шутку про UDP, но боюсь она до вас не дойдёт… (с)
Если она до вас не дойдёт, то я её повторю.
UDP не делает переотправку сам по себе, стало быть повторы это уже за пределами UDP (и шутки). Она из разряда:
«В мире 10 типа людей: первые понимают двоичные числа а вторые — нет»
Извините, если кому сломал магию самой шутки, она действительно с тонким английскимадминским юмором.
Сорри, перепутал вот с этой «А еще знаю анекдот про TCP. Если он до вас не дойдет, я повторю его снова.»
И это правильный ответ! Два чаю этому господину.
Благодаря прочтению статьи, до меня дошла ваша шутка.
Доклад классный и познавательный. Спасибо. А всякие адаптивные ухищрения с доставкой видео, типа HLS — не выход?
HLS может быть выходом в зависимости от задачи, для нас и HLS не выход
habr.com/ru/company/oleg-bunin/blog/413479

а по нашему UDP протоколу мы гоняем и API json-ы и картинки
А почему perfomance у udp получился меньше чем у tcp? Какие-то специфичные оптимизации tcp протокола?

Large send offload, в статье и комментариях упоминается как "TSO".

Хорошо копнули, не статья, а энциклопедия получилась. Спасибо.
Все течет, все меняется
За статью спасибо, я ей буду пугать разработчиков если они начнут жаловаться что им тяжело

Позанудствую.
BitTorrent перешёл на UDP с delay based congestion control где-то в 2010. До четверти траффика в интернете так ходило.

Возможно, я где-то не уточнил ) точное число по оператору МТС
32% — UDP трафик, 28% — QUIC

на проводах другое распределение, там много торрентов )
Ну вот, опять. Да сколько ж можно. Опять эти велосипедисты видят мир в бинарной дихотомии TCP vs UDP. Опять и опять они изобретают очередной велосипед поверх UDP для решения какой-то своей частной задачи, не думая об остальной сети (в комментах уже упомянули). Опять и опять они приносят в жертву долгосрочную стабильность своим сиюминутным изменениям версий…

И всё это при том, что не просто «надо придумать новый протокол», как думают авторы пунктов опроса, а давно уже есть SCTP, который вот это всё умеет — и несколько «соединений» внутри одной ассоциации, и разные наборы IP-адресов/multipath, и много чего еще. А главное — не просто реализован в ядрах FreeBSD и Linux, но есть и юзерспейсные драйвера, и даже режим «поверх UDP» для решения проблемы «файрволы не знают новый протокол».
просто оставлю это тут tools.ietf.org/html/draft-joseph-quic-comparison-quic-sctp-00

ну т.е. это про то, что google не много думает об остальной сети в целом и ваших приложениях в частности
особенно хороша история с BBR vs Cubic: в ней последний страдает при congestion-е

Предположу, что частное решение всегда будет эффективнее универсального.
Ну и внедрение SCTP можно сравнивать с IPv6.

Вовсе не всегда (пример — malloc в ядре, частные решения ухудшают жинь другим подсистемам).
Нет, нельзя сравнивать, вариант без апдейта миддлбоксов существует.
Вы неправильно его называете — smUDP. Логичнее было бы smTCP-over-UDP

Почему автор называет транспортные протоколы сетевыми? Тот самый момент, когда программист пишет о будущем сетей со своей колокольни...

можно где то измерять в ваших сферических интернетах, но на деле udp неэффективен в 90% мест которые находятся в россии, и при этом с 1 ноября будет ещё хуже… провайдеры же типа мегафон и ёты очень хорошо не любят udp и если вы ориентируетесь получать прибыль то просто обязаны учитывать этот момент, потому что пользователи вполне могут отказаться от нестабильного сервиса
верю что конкурентный рынок не позволит и так сделать, уже сейчас у МТС более 32% трафика UDP (28% из них QUIC), и в МТС на эти реалии смотрят нормально )
Толку от TFO если по умолчанию на клиентах он не включен? И в firefox и в Edge нужно в настройках кликать. Ну вот я сайт сделал на своём сайте поддержку TFO — за неделю использования ниодного соединения с TFO (кроме моих собственных) :)
да для мобильных реальность выглядит аналогично более 90% устройств не поддерживают TFO
У меня тоже стояла задача передачи видео по интернету на дальние расстояния (RTT >100ms) и я пробовал различные реализации через UDP, но по факту они все оказывались хуже TCP. Тогда я решил выбрать tcp congestion protocol на стороне сервера, который бы лучше работал с клиентским Cubic на дальних расстояния… Собрал стенд с задержками и потерей пакетов 1-5% и начал тестировать. По моим тестам лучше всего себя показал Yeah. Поставил его и стало немного лучше, но все равно при потерях >3% скорость одиночного соединения недостаточна для качественного видео. Все потому, что размер окна падает ниже требуемого уровня при таких задержках. Сама сеть может передать поток даже с такими потерями, но размер окна не позволяет ей. Тогда я подумал, а почему просто взять и не ограничить минимальный размер окна? Ведь выбирает его tcp congestion protocol на передающей стороне… максимальный битрейт видео известен, RTT известно, поэтому легко выяснить минимально нужный размер окна. Тогда я просто немного изменил имеющуюся реализацию Yeah и попробовал. Оказалось, что моя реализация отлично работает и может «проглотить» до 15% потерь, хотя стандартная затыкалась уже на 3%. Конечно это не спасает от ситуации когда сеть в принципе не готова пропустить такой поток данных ( например при плохом WiFi соединении).
Интересное решение, было бы здорово его сравнить с QUIC или нашим протоколом
мы для стриминга видео по TCP мы используем BBR (для сетей с потерями он больше подходит чем Cubic)
Можете попробовать собрать и протестировать bitbucket.org/ddv2005/tcp_yeah_ext
Для сборки нужен tcp_vegas.h от установленной версии ядра. Модуль имеет несколько параметров которые можно менять на ходу. Минимальное окно меняется от min_cwnd (при min_rtt) до max_min_cwnd (при max_rtt) линейно в зависимости от rtt (round trip time).
А где креатив? Цепляние за известное, старое, в какое будущее нас приведет? Мысли в оковах дел не улучшают.

В начале своей карьеры писал как раз надежный протокол поверх UDP для аналога Скайпа, которого тогда не было. Идея была в том, что гарантировалась знание о состоянии канала на обеих его сторонах и возможность управлять передачей (напр., запрашивать недоставленные пакеты).

Но в конце-концов не пошло именно из-за сетей за HTTP-прокси.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий