Комментарии 31
Начну с бесспорного утверждения: если вы создаёте чувствительную к задержкам распределённую систему, работающую на современном оборудовании датацентра, смело включайте TCP_NODELAY (то есть отключайте алгоритм Нейгла).
Если вы создаёте чувствительную к задержкам распределённую систему, используйте UDP. И ARP подкручивайте.
Вариант не проходить tcp хендшейк для каждого сообщения заново и просто использовать существующее соединение не рассматривается? ARP, кстати, можно не подкручивать (из-за использования конкретного термина, полагаю вы про таймеры), а делать gratuitous (а в ряде кейсов, например если клиент - обычный пользователь обычного оператора, имеющего вагон security штук а-ля rpf, подкручивать что-либо бесполезно в принципе). Про применимость arp в контексте ipv6 вообще душнить не буду.
Короче говоря, вы крайне категоричны.TCP/UDP - всего лишь транспорт. И, увы, на лэтэнси гораздо сильнее влияют совершенно другие, более физические вещи.
К сожалению часто это невозможно т.к. нужен, например, HTTP. А поддержка HTTP/3 нынче не очень широка в разных библиотеках и часто экспериментальна.
Даже интересно - хотя бы HFTшники (вот уж где latency важно) опускаются до UDP?
Не знаю про HFT (надеюсь, прокомментируют более близкие к теме люди), но это далеко не самая чувствительная область. В HFT вы рискуете максимум деньгами. А бывают приложения, где от задержек зависят жизни людей.
Хотя, конечно, за большие деньги и убить могут, но никто ведь не узнает, что дело было в задержке, поэтому программиста вряд ли убьют и даже посадят, если что.
бывают приложения, где от задержек зависят жизни людей.
А от потерянных пакетов они не зависят?
Потерянные пакеты необязательно ловить средствами именно TCP.
Но вообще такие системы строятся так, что пакеты в штатном режиме не теряются.
Причина потери пакетов – либо сбой в работе оборудования, либо переполнение пропускной способности канала.
Выглядит так, что в таком случае TCP/IP стек - вообще лишнее, нужен просто надёжный аппаратный канал и какое то минимальное API поверх него. UDP/IP - уже не самая легковесная прослойка, надо думать, как IP пакеты нарежутся на аппаратные фреймы и т.д.
Тут дело в том, что свой драйвер под каждую сетевую карту геморройно писать.
Хотя мы как-то писали свой стек, было дело.
Уже упомянутый в треде DPDK не поможет? Даже в ядро лазить не придётся.
В DPDK тоже есть свои драйверы, причём только для небольшого числа железок.
Там куча железа поддерживается и нет никакой проблемы просто взять лучшую поддерживаемую сетевуху, допустим, если есть такая необходимость. В HFT & co стоимость конечного железа это мизерный процент от всех трат.
Для HFT да. А для промышленной автоматизации выбор железа определяется другими характеристиками. Какой-нибудь там температурной или радиационной стойкостью, например.
Для промышленных сетей лучше всего, как мне кажется, использовать что-то вроде https://en.wikipedia.org/wiki/Data_center_bridging
Если ретрансмит дорог (как при связи в Марсом, например, или Вояджерами), то нужно просто использовать коды избыточности, чтобы можно было компенсировать потерянный пакет.
Понятно, что если пакет никак не связан с остальными и он целиком потеряется - то применять избыточность сложно. Но, думаю, можно найти выход.
Они часто и до DPDK опускаются
Такие издержки в 4 000%, конечно, раздражают, но в слабо нагруженных сетях ещё терпимы.
и
Эти крохотные пакеты поступали из двух основных источников: интерактивных приложений вроде оболочек, где пользователь вводил по одному байту за раз
Судя по описанию и датам в тексте, это проблема эпохи палеолита, когда сети в 10 Мб\с были чем-то из научной фантастики, а в качестве процессора везде использовался Intel 80386.
В современных сетях я ни разу о такой проблеме даже не слышал.
в embedded системах с TCP/IP это становится важным, например когда у нас в сети куча девайсов по mqtt работают
Сейчас даже в таких системах используются преимущественно 100 Мбит трансиверы, чтобы из-за одного 10 Мбит девайса вся сеть не падала в 10 Мбит. А на 100 Мбит отправить 1,5 кБ пакет классическим способом будет быстрей, чем вот так извращаться с единичными байтами. Если же трафик тарифицируемый или сеть сильно загружена, то часто можно на стороне источника данных насобирать в буфер килобайт данных, после чего выплюнуть в сеть весь буфер.
Если смотреть на вопрос шире конкретного TCP_NODELAY, то это противопоставление эффктивного использования полосы пропускания и минимизации задержек.
В локальных сетях это выстреливало в части VoIP и конвергентной инфраструктуры.
Или вот к примеру вполне современный гайд от vmware, как оптимизировать vSphere по сетевым задержкам https://www.vmware.com/docs/perf-latency-tuning-vsphere8
Судя по описанию и датам в тексте, это проблема эпохи палеолит
В ssh до недавнего времени посылали по одному байту. только потом начали подбирать пароли при интерактивном вводе: https://habr.com/ru/companies/ruvds/articles/770792/
Судя по описанию и датам в тексте, это проблема эпохи палеолита
Там первой же строчкой в статье
Занимаясь отладкой проблем в легаси-системах
Ваш К.О.
Вообще странно что в современных ядрах Linux эту опцию сокета не выключат по дефолту. По идее обратной совместимости в современном мире оно не должно сломать.
Обратной совместимости сломать не должно, но бенчмарки ухудшит.
А так вроде это в /etc/ настроить можно.
Вообще странно что в современных ядрах Linux эту опцию сокета не выключат по дефолту.
Ядро Linux используется в очень уж разных системах, далеко не только в датацентрах, как в этой статье. Поэтому луше умолчание для нее вынести в конфигурацию (файл и т.п.). И IMHO разумно дать возможность эту опцию настраивать отдельно для каждого сетевого интерфейса, как это было сделано в Windows в давние времена, когда она была ешё NT - к разным интерфейсам даже в одной системе могут бытьподключены весьма разные сети.
Дело всегда в TCP_NODELAY