Где возможные места задержек очереди/буферизации в многоадресной рассылке Linux?

Мы интенсивно используем многоадресный обмен сообщениями между многими серверами Linux в локальной сети. Мы видим много задержек. В основном мы отправляем огромное количество мелких посылок. Нас больше волнует задержка, чем пропускная способность. Машины все современные, многоядерные (минимум четыре, обычно восемь, 16, если считать гиперпоточность) машины, всегда с нагрузкой 2.0 или меньше, обычно с нагрузкой меньше 1.0. Сетевое оборудование также загружено менее чем на 50%.

Задержки, которые мы видим, выглядят как задержки в очереди: пакеты быстро начинают увеличиваться в задержке, пока не станет казаться, что они застревают, а затем возвращаются в нормальное состояние.

Структура обмена сообщениями в основном такова: в «потоке отправки» извлекайте сообщения из очереди, добавляйте метку времени (используя gettimeofday()), затем вызывайте send(). Программа-получатель получает сообщение, отмечает время получения и помещает его в очередь. В отдельном потоке обрабатывается очередь, анализируя разницу между отправкой и получением временных меток. (Обратите внимание, что наши внутренние очереди не являются частью проблемы, поскольку метки времени добавляются вне нашей внутренней очереди.)

Мы действительно не знаем, с чего начать искать ответ на эту проблему. Мы не знакомы с внутренностями Linux. Мы подозреваем, что ядро ​​ставит в очередь или буферизует пакеты либо на стороне отправки, либо на стороне приема (или на обеих сторонах). Но мы не знаем, как это отследить и проследить.

Мы используем CentOS 4.x (ядро RHEL 2.6.9).


person Matt    schedule 17.02.2010    source источник
comment
Начните с трассировки wireshark, чтобы увидеть, вызвана ли очередь сетевым оборудованием или даже потерянными пакетами (даже простые коммутаторы стоят в очереди как сумасшедшие и часто являются основным источником потери пакетов).   -  person nos    schedule 18.02.2010
comment
Мы определенно не отбрасываем пакеты, так как упорядочиваем все внутренние сообщения и проверяем их на отбрасывание. Запуск чего-то вроде Wireshark является инвазивным и не подходит для производственной среды. Мы не можем дублировать эти задержки в тестовой среде. Таким образом, мы пытаемся логически понять поведение ядра Linux в отношении многоадресной отправки и получения.   -  person Matt    schedule 18.02.2010
comment
Также добавлю, что в некоторых случаях отправитель и получатель находятся на одной машине. Мы все еще видим эти эффекты задержки в этом сценарии. Это полностью исключает часть проблемы, связанную с сетевым оборудованием.   -  person Matt    schedule 18.02.2010


Ответы (3)


Пакеты могут ставиться в очередь в ядре отправки и приема, сетевой карте и сетевой инфраструктуре. Вы найдете множество элементов, которые вы можете протестировать и настроить.

Для сетевой карты вы обычно можете найти параметры объединения прерываний - как долго сетевая карта будет ждать, прежде чем уведомить ядро ​​​​или отправить по сети, ожидая пакетной обработки пакетов.

Для Linux у вас есть «буферы» отправки и получения, чем они больше, тем больше вероятность того, что вы столкнетесь с большей задержкой, поскольку пакеты обрабатываются в пакетных операциях.

Для архитектуры и версии Linux вы должны знать, насколько дорогими являются переключения контекста и включены ли блокировки или упреждающее планирование. Подумайте о том, чтобы свести к минимуму количество запущенных приложений, используя сходство процессов для привязки процессов к определенным ядрам.

Не забывайте о времени, версия ядра Linux, которую вы используете, имеет ужасную точность на gettimeofday() часах (2-4 мс) и является довольно дорогим вызовом. Рассмотрите возможность использования альтернатив, таких как чтение из основного TSC или внешнего устройства HPET.

Диаграмма от Intel: http://www.theinquirer.net/IMG/142/96142/latency-580x358.png?1272514422

person Steve-o    schedule 19.03.2010

Это большой вопрос. В CentOS, как и в большинстве разновидностей *nix, есть буфер приема/отправки UDP для каждого многоадресного сокета. Размер этого буфера контролируется sysctl.conf, вы можете просмотреть размер ваших буферов, вызвав /sbin/sysctl -a

Элементы ниже показывают мой размер по умолчанию и максимальный размер приема udp в байтах. Чем больше эти числа, тем больше буферизация и, следовательно, задержка, которую может создать сеть/ядро, если ваше приложение слишком медленно потребляет данные. Если вы создали хорошую устойчивость к потере данных, вы можете сделать эти буферы очень маленькими, и вы не увидите увеличения задержки и восстановления, описанных выше. Компромисс заключается в потере данных при переполнении буфера, что вы, возможно, уже видели.

[~]$ /sbin/sysctl -a | память net.core.rmem_default = 16777216 net.core.wmem_default = 16777216 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216

В большинстве случаев вам нужно установить default = на ваш максимум, если вы не контролируете это при создании своего сокета.

последнее, что вы можете сделать (в зависимости от версии вашего ядра), это просмотреть статистику UDP PID для вашего процесса или, по крайней мере, для всего окна.

кошка /proc/net/snmp | grep -i Udp Udp: InDatagrams NoPorts InErrors OutDatagrams Udp: 81658157063 145 616548928 3896986

кошка /proc/PID/net/snmp | grep -i Udp Udp: InDatagrams NoPorts InErrors OutDatagrams Udp: 81658157063 145 616548928 3896986

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

Дайте мне знать, что вы думаете, и я могу дать вам больше информации о том, где искать в вашем приложении, чтобы повысить производительность.

person avirtuos    schedule 19.02.2010
comment
Так справедливо ли сказать, что на стороне отправки нет буферизации в ядре? А на принимающей стороне нет буферизации ядра, ЕСЛИ данные не потребляются достаточно быстро? К сожалению, у меня нет статистики UDP для каждого PID (я не уверен, что мое ядро ​​2.6.9-78.ELlargesmp недостаточно новое или просто не настроено для этого). В любом случае, меня определенно интересует любая информация о том, как повысить производительность наших приложений. Также обратите внимание, что на самом деле нас интересуют лишь несколько миллисекунд — это фактически приложение реального времени. Спасибо! - person Matt; 23.02.2010
comment
Ваше суммирование почти на 100% соответствует моему пониманию многоадресного стека в Linux. Единственное отличие состоит в том, что очередь на стороне «отправки» может возникать независимо от того, насколько быстро вы потребляете данные на другом конце. Очередь на стороне отправки является результатом недостаточной скорости сети, низкого качества сетевой карты и общих проблем с производительностью (загрузка, память и т. д.). Очереди на стороне отправки не очень распространены. И да, это все в миллисекундах или больше. - person avirtuos; 24.02.2010
comment
Еще одна вещь: если ваша сетевая карта использует драйверы Intel E1000 на стороне отправки, вы можете увидеть задержку в 0,1 мс из-за того, как драйвер обрабатывает аппаратные прерывания. - person avirtuos; 24.02.2010

Если вы решите, что вам нужно перехватывать пакеты в производственной среде, возможно, стоит рассмотреть возможность использования портов монитора на ваших коммутаторах и перехвата пакетов с помощью непроизводственных машин. Это также позволит вам захватывать пакеты в нескольких точках на пути передачи и сравнивать то, что вы видите.

person Vatine    schedule 19.03.2010
comment
Кроме того, обратите внимание на одну из многочисленных консалтинговых компаний или специалистов по мониторингу со специальными аппаратными устройствами, такими как TS-Associates. -associates.com/view/tipoff - person Steve-o; 19.03.2010