tcpdump увеличивает производительность udp

13

Я запускаю набор нагрузочных тестов, чтобы определить производительность следующей настройки:

Node.js test suite (client) --> StatsD (server) --> Graphite (server)

Вкратце, набор тестов node.js отправляет определенное количество метрик каждые x секунд в экземпляр StatsD, который находится на другом сервере. Затем StatsD сбрасывает метрики каждую секунду в экземпляр Graphite, расположенный на том же сервере. Затем я смотрю, сколько метрик фактически было отправлено набором тестов и сколько было получено Graphite для определения потери пакетов между набором тестов и Graphite.

Однако я заметил, что иногда я получаю очень большие скорости отбрасывания пакетов (обратите внимание, что он отправляется по протоколу UDP), в пределах 20-50%. И вот тогда я начал изучать, где эти пакеты отбрасывались, видя, что это может быть связано с некоторой проблемой производительности StatsD. Поэтому я начал регистрировать показатели в каждой части системы, чтобы отслеживать, где произошло это падение. И здесь все становится странным.

Я использую tcpdump для создания файла захвата, который я проверяю после завершения теста. Но всякий раз, когда я запускаю тесты с запущенным tcpdump, потеря пакетов практически отсутствует! Похоже, что tcpdump каким-то образом повышает производительность моих тестов, и я не могу понять, почему и как это происходит. Я запускаю следующую команду для регистрации сообщений tcpdump на сервере и клиенте:

tcpdump -i any -n port 8125 -w test.cap

В одном конкретном тестовом примере я посылаю 40000 метрик / с. Тест при запуске tcpdump имеет потерю пакетов около 4%, в то время как тест без потери пакетов составляет около 20%

Обе системы работают как виртуальные машины Xen со следующей настройкой:

  • Intel Xeon E5-2630 v2 с частотой 2,60 ГГц
  • 2 ГБ ОЗУ
  • Ubuntu 14.04 x86_64

Вещи, которые я уже проверил на возможные причины:

  • Увеличение размера буфера приема / отправки UDP.
  • Нагрузка процессора влияет на тест. (максимальная загрузка 40-50%, как на стороне клиента, так и на стороне сервера)
  • Запуск tcpdump на определенных интерфейсах вместо 'any'.
  • Запуск tcpdump с '-p' для отключения случайного режима.
  • Запуск tcpdump только на сервере. Это привело к потере пакетов на 20% и, похоже, не повлияло на тесты.
  • Запуск tcpdump только на клиенте. Это привело к увеличению производительности.
  • Увеличение netdev_max_backlog и netdev_budget до 2 ^ 32-1. Это не имеет значения.
  • Перепробовал все возможные настройки случайного режима на каждом нике (сервер включен и клиент выключен, сервер выключен и клиент включен, оба включены, оба выключены). Это не имеет значения.
Рубен Хомс
источник
3
По умолчанию tcpdump переводит сетевой интерфейс в беспорядочный режим. Возможно, вы захотите пропустить -pопцию, чтобы пропустить это, чтобы увидеть, если это имеет значение.
Зоредаче
Итак, вы запускаете tcpdump как на клиенте, так и на сервере, и скорость потери пакетов падает? Что произойдет, если вы запустите его только на клиенте, и что произойдет, если вы запустите его только на сервере? (И, да, также попробуйте отключить неразборчивый режим и, возможно, также попробуйте захватить на определенном сетевом интерфейсе, используемом для теста, а не на «любом» устройстве, чтобы увидеть , имеет ли это значение.)
Спасибо за ваши комментарии. Я испробовал обе ваши рекомендации и отредактировал свой вопрос, чтобы отразить то, что я пробовал, но это не повлияло на проблему.
Рубен Хомс
Приводит ли nics на обеих машинах к случайному режиму тот же эффект, что и запуск tcpdump? ifconfig eth0 promiscвключает и ifconfig eth0 -promiscотключает беспорядочный режим на eth0. Если это имеет значение, попробуйте сравнить 4 возможных комбинации включения / выключения на обеих машинах. Это может помочь точно определить источник проблем.
Фокс
@Fox Спасибо за ответ! Я перепробовал все возможные комбинации для всех игроков, но без разницы в результатах. Я обновил свой вопрос, чтобы отразить это.
Рубен Хомс

Ответы:

10

Когда tcpdump запущен, он будет довольно быстро при чтении во входящих кадрах. Моя гипотеза состоит в том, что настройки буфера кольцевого пакета NIC могут быть немного маленькими; когда tcpdump работает, он очищается более своевременно.

Если вы являетесь подписчиком Red Hat, то эта статья поддержки очень полезна. Обзор приема пакетов . Там есть кое-что, что, я думаю, вы еще не рассматривали.

Подумайте, как ваша система работает с IRQ; подумайте об увеличении «dev_weight» сетевого интерфейса (что означает, что больше пакетов будет прочитано из NIC в пространство пользователя); посмотрите, как часто приложение читает сокет (может ли оно использовать выделенный поток, существуют ли известные проблемы / обходные пути, касающиеся масштабируемости).

Увеличьте буфер кадра NIC (используя ethtoolкоманду - посмотрите на --set-ringаргументы и т. Д.).

Посмотрите на «масштабирование на стороне приема» и используйте хотя бы столько потоков приема для чтения в трафике.

Интересно, делает ли tcpdump что-то классное, например, использует поддержку ядра для кольцевых буферов пакетов ? Это поможет объяснить поведение, которое вы видите.

Кэмерон Керр
источник
Поскольку это среда Xen, вы, вероятно, должны (по крайней мере, некоторые из них) сделать это на хосте Xen.
Кэмерон Керр
Это то, о чем я раньше не думал, очень интересные вещи, спасибо! Я попробую это, как только получу доступ к хосту Xen и сообщу, как это происходит.
Рубен Хомс
2

Какого губернатора вы используете? Я видел подобное поведение с "по требованию" или "консервативным" губернатором.

Попробуйте использовать регулятор производительности и отключить все энергосберегающие функции в BIOS сервера.

Это что-то меняет?

shodanshok
источник
У меня проблемы с выяснением, какой регулятор мощности я использую. Я пытался бежать, cpufreq-infoно получил сообщение no or unknown cpufreq driver is active on this CPU. Также при использовании cpupower frequency-infoвозвращается no or unknown cpufreq driver is active on this CPU. Хотя я не могу подтвердить это на данный момент, сайт производителя виртуальных машин заставляет меня поверить, что он работает в режиме «производительности», поскольку у меня есть процессор Intel ..
Рубен Хомс
Можете ли вы показать вывод следующих команд? 1) cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor2) cat /proc/cpuinfo3)lsmod | grep cpu
Шоданшок
Здесь вы идете
Рубен Хомс
1

Другой способ - это ip_conntarckмодуль. Вы уверены, что ваш linux-box может принять новое соединение? проверить через:

root@debian:/home/mohsen# sysctl net.ipv4.netfilter.ip_conntrack_max
net.ipv4.netfilter.ip_conntrack_max = 65536
root@debian:/home/mohsen# sysctl  net.ipv4.netfilter.ip_conntrack_count
net.ipv4.netfilter.ip_conntrack_count = 29

Вы должны проверить

net.ipv4.netfilter.ip_conntrack_max >  net.ipv4.netfilter.ip_conntrack_count

если max == count, ваше максимальное соединение заполнено, и ваш linux-box не может принять новое соединение.
Если у вас нет ip_conntrack, вы можете легко загрузить черезmodprobe ip_conntrack

Персидский залив
источник
2
И если это так, то вы должны посмотреть на цель NOTRACK в «сырой» таблице, чтобы предотвратить отслеживание соединения для этого. Я сделал это недавно для занятого DNS-сервера, и он убрал iptables из узкого места и вызвал тайм-ауты разрешения DNS.
Кэмерон Керр
И вот пример того, как я использовал правила NOTRACK, чтобы IPTables не выполняли никакого отслеживания соединения для UDP DNS. distracted-it.blogspot.co.nz/2015/05/…
Кэмерон Керр
1

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

  1. использование tcpdump на клиенте уменьшает количество отброшенных пакетов: tcpdump замедляет работу клиента, и поэтому сервер видит гораздо более низкую скорость упаковщика, с которой он все еще может частично справиться. Вы должны быть в состоянии подтвердить эту гипотезу, проверив счетчики пакетов RX / TX на клиенте и сервере

  2. Вы упомянули, что вы увеличили размер приема / отправки UDP-буфера, не могли бы вы подробно рассказать, как? Важно, чтобы на сервере вы изменили и rmem_max, и rmem_default, например: sysctl -w net.core.rmem_max=524287 sysctl -w net.core.wmem_max=524287 sysctl -w net.core.rmem_default=524287 sysctl -w net.core.wmem_default=524287

Тестирование ваших настроек

Остановите statsd и приложение узла, затем в режиме ожидания системы используйте iperf для проверки скорости передачи пакетов, которую может обработать сеть / ядро. Если вы можете передавать 40K пакетов / с с помощью iperf, но не можете использовать statsd, тогда вам следует сконцентрировать свои усилия на настройке statsd.

Другие переменные

Также не забудьте настроить net.core.netdev_max_backlog : максимальное количество пакетов, которые могут быть помещены в очередь, когда определенный интерфейс получает пакеты быстрее, чем ядро ​​может их обработать.

unicoletti
источник