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 сервера.

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


У меня проблемы с выяснением, какой регулятор мощности я использую. Я пытался бежать, 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 : максимальное количество пакетов, которые могут быть помещены в очередь, когда определенный интерфейс получает пакеты быстрее, чем ядро ​​может их обработать.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.