Отбрасывание пакетов UDP - 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:

renice -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.

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


person Bala    schedule 09.02.2014    source источник
comment
Я знаю, что это древний вопрос, но удалось ли вам выяснить, в чем суть проблемы? Я пытаюсь воспроизвести состояние InErrors ›RcvbufErrors.   -  person mgjk    schedule 21.05.2019


Ответы (3)


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

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

person Joe Damato    schedule 23.06.2016

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

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

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

person Alex    schedule 27.09.2014

InErrors состоит из:

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

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

person Georgi Atsev    schedule 29.05.2015