it-swarm.com.ru

UDP Packet drop - INErrors против .RcvbufErrors

Я написал простую программу UDP Server, чтобы понять больше о возможных узких местах сети. 

Сервер UDP: Создает сокет UDP, привязывает его к указанному порту и адресу и добавляет дескриптор файла сокета в список интересов epoll. Затем его epoll ждет входящего пакета. При получении входящего пакета (EPOLLIN) он считывает пакет и просто печатает длину принятого пакета. Довольно просто, верно :) 

Клиент UDP: я использовал hping, как показано ниже:

hping3 192.168.1.2 --udp -p 9996 --flood -d 100

Когда я отправляю пакеты udp со скоростью 100 пакетов в секунду, я не вижу потери пакетов UDP. Но когда я заливаю пакеты udp (как показано в приведенной выше команде), я вижу значительную потерю пакетов. 

Test1: Когда 26356 пакетов загружаются от UDP-клиента, моя программа-пример получает ТОЛЬКО 12127 пакетов, а оставшиеся 14230 пакетов отбрасываются ядром, как показано в выводе/proc/net/snmp.

cat/proc/net/snmp | grep Udp: 
UDP: InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors
Udp: 12372 0 14230 218 14230 0

Для Test1 процент потери пакетов составляет ~ 53%. 

Я проверил, что на аппаратном уровне НЕ много потерь, используя команду ethtool -S ethX как на стороне клиента, так и на стороне сервера, в то время как на уровне приложений я вижу потерю в 53%, как сказано выше.

Следовательно, чтобы уменьшить потерю пакетов, я попробовал это: 
- Увеличил приоритет моей программы-примера с помощью команды renice
- Увеличен размер буфера приема (как на уровне системы, так и на уровне процесса) 

Увеличьте приоритет до -20:

ренис -20 2022 
2022 (идентификатор процесса) старый приоритет 0, новый приоритет -20 

Увеличьте размер принимаемого буфера до 16 МБ:

На уровне процесса:
int sockbufsize = 16777216; 
setsockopt (sockfd, SOL_SOCKET, SO_RCVBUF, (char *) и sockbufsize, (int) sizeof (sockbufsize))
На уровне ядра:
cat/proc/sys/net/core/rmem_default 
16777216 
cat/proc/sys/net/core/rmem_max 
16777216 

После этих изменений выполняется Test2.

Test2: При загрузке 1985076 пакетов от клиента UDP моя программа-пример получает 1848791 пакет, а оставшиеся 136286 пакетов отбрасываются ядром, как показано в выводе/proc/net/snmp.

cat/proc/net/snmp | grep Udp: 
UDP: InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors
Udp: 1849064 0 136286 236 0 0

Для Test2 процент потери пакетов составляет 6%. 

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

  1. Можно ли еще уменьшить потери пакетов?!? Я знаю, что я жадный здесь :) Но я просто пытаюсь выяснить, возможно ли дальнейшее снижение потери пакетов.
  2. В отличие от Test1, в Test2 InErrors не соответствует RcvbufErrors и RcvbufErrors всегда равно нулю. Может кто-нибудь объяснить причину этого, пожалуйста?!? В чем именно разница между InErrors и RcvbufErrors. Я понимаю RcvbufErrors, но НЕ InErrors.

Спасибо за вашу помощь и время!

16
Bala

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

Я написал длинное сообщение в блоге объясняя все параметры настройки сверху вниз и объясняя, что означает каждое из полей в /proc/net/snmp, чтобы вы могли понять, почему происходят эти ошибки. Посмотрите, я думаю, что это должно помочь вам снизить вашу сеть до 0.

5
Joe Damato

InErrors состоит из:

  • поврежденные пакеты (неправильные заголовки или контрольная сумма) 
  • полный размер буфера RCV

Таким образом, я предполагаю, что вы исправили проблему переполнения буфера (RcvbufErrors = 0), а остались пакеты с неправильными контрольными суммами.

0
George Atsev

Если на аппаратном уровне не происходит сбрасываний, то в основном это вопрос памяти, вы должны иметь возможность настроить параметры конфигурации ядра, чтобы достичь 0 отбрасываний (очевидно, вам нужно разумно сбалансированное оборудование для сетевого трафика, который вы получаете. ).

Я думаю, что вы отсутствуют netdev_max_backlog , что важно для входящих пакетов:

Максимальное количество пакетов, помещенных в очередь на стороне INPUT, когда интерфейс получает пакеты быстрее, чем ядро ​​может их обработать.

0
Alex