Я запускаю набор нагрузочных тестов, чтобы определить производительность следующей настройки:
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. Это не имеет значения.
- Перепробовал все возможные настройки случайного режима на каждом нике (сервер включен и клиент выключен, сервер выключен и клиент включен, оба включены, оба выключены). Это не имеет значения.
-p
опцию, чтобы пропустить это, чтобы увидеть, если это имеет значение.ifconfig eth0 promisc
включает иifconfig eth0 -promisc
отключает беспорядочный режим на eth0. Если это имеет значение, попробуйте сравнить 4 возможных комбинации включения / выключения на обеих машинах. Это может помочь точно определить источник проблем.Ответы:
Когда tcpdump запущен, он будет довольно быстро при чтении во входящих кадрах. Моя гипотеза состоит в том, что настройки буфера кольцевого пакета NIC могут быть немного маленькими; когда tcpdump работает, он очищается более своевременно.
Если вы являетесь подписчиком Red Hat, то эта статья поддержки очень полезна. Обзор приема пакетов . Там есть кое-что, что, я думаю, вы еще не рассматривали.
Подумайте, как ваша система работает с IRQ; подумайте об увеличении «dev_weight» сетевого интерфейса (что означает, что больше пакетов будет прочитано из NIC в пространство пользователя); посмотрите, как часто приложение читает сокет (может ли оно использовать выделенный поток, существуют ли известные проблемы / обходные пути, касающиеся масштабируемости).
Увеличьте буфер кадра NIC (используя
ethtool
команду - посмотрите на--set-ring
аргументы и т. Д.).Посмотрите на «масштабирование на стороне приема» и используйте хотя бы столько потоков приема для чтения в трафике.
Интересно, делает ли tcpdump что-то классное, например, использует поддержку ядра для кольцевых буферов пакетов ? Это поможет объяснить поведение, которое вы видите.
источник
Какого губернатора вы используете? Я видел подобное поведение с "по требованию" или "консервативным" губернатором.
Попробуйте использовать регулятор производительности и отключить все энергосберегающие функции в 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 ..cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
2)cat /proc/cpuinfo
3)lsmod | grep cpu
Другой способ - это
ip_conntarck
модуль. Вы уверены, что ваш linux-box может принять новое соединение? проверить через:Вы должны проверить
если max == count, ваше максимальное соединение заполнено, и ваш linux-box не может принять новое соединение.
Если у вас нет ip_conntrack, вы можете легко загрузить через
modprobe ip_conntrack
источник
Я подозреваю, что принимающая сторона просто не способна обрабатывать скорость передачи пакетов, и вот почему:
использование tcpdump на клиенте уменьшает количество отброшенных пакетов: tcpdump замедляет работу клиента, и поэтому сервер видит гораздо более низкую скорость упаковщика, с которой он все еще может частично справиться. Вы должны быть в состоянии подтвердить эту гипотезу, проверив счетчики пакетов RX / TX на клиенте и сервере
Вы упомянули, что вы увеличили размер приема / отправки 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 : максимальное количество пакетов, которые могут быть помещены в очередь, когда определенный интерфейс получает пакеты быстрее, чем ядро может их обработать.
источник