Почему мой tc на базе Linux Prio не улучшает задержки в сети? - PullRequest
4 голосов
/ 21 сентября 2010

Я создаю встроенное Linux-приложение в реальном времени, которое имеет различный сетевой трафик. Из множества трафика два соединения являются критичными по времени. Один из них является входными данными, а другой - для выходных данных. Моему приложению нужен этот трафик, чтобы иметь приоритет над другим, не критичным ко времени трафиком.

Я забочусь о двух вещах:

  1. Минимизируйте количество отброшенных пакетов из-за перегрузки на этих двух соединениях.
  2. Минимизируйте задержку через устройство (вход-выход) в этих двух соединениях.

Я (немного!) Разбираюсь в управлении трафиком Linux и понимаю, что это в первую очередь относится к исходящему трафику, поскольку удаленное устройство отвечает за приоритет данных, которые оно отправляет мне. Я настроил свое приложение как процесс в режиме реального времени и решил все вопросы, связанные с приоритетом его запуска.

Теперь я приступаю к настройке tc. Для моего тестового примера вот что я использую:

tc qdisc add dev eth0 root handle 1: prio bands 3 priomap 2 2 2 2 2 2 2 0 2 2 2 2 2 2 2 2
tc qdisc add dev eth0 parent 1:1 handle 10: pfifo
tc qdisc add dev eth0 parent 1:2 handle 20: pfifo
tc qdisc add dev eth0 parent 1:3 handle 30: pfifo

По сути, я говорю: отправьте весь трафик с приоритетом 7 в полосе 0, а весь другой трафик в полосе 2. Как только у меня будет работать этот простой тест, я лучше справлюсь с другим трафиком.

Сначала давайте проверим мои ожидания: Я ожидаю, что любой трафик с приоритетом 7 всегда должен выходить перед трафиком с любым другим приоритетом. Это должно сделать задержку на таком трафике относительно незатронутой другим трафиком на коробке, нет? Мой MTU установлен на 1500, и я получаю около 10 МБ / с через интерфейс. Максимальная дополнительная задержка в полосе 0, вызванная трафиком в полосе 2, составляет один пакет (<= 1500 байт) или 150 мкс (1500 байт / 10 МБайт / с = 150 мкс). </p>

Вот моя тестовая установка:

Два Linux Boxes. На Box 1 работает TCP-сервер, который отображает входные данные. Блок 2 подключается к блоку 1, отправляет пакеты по TCP и измеряет задержку (время, отправленное на полученное время).

Я использую ту же настройку tc для коробочных коробок Linux.

В приложениях (как серверных, так и клиентских) я установил SO_PRIORITY для сокета следующим образом:

int so_priority = 7;
setsockopt(m_socket.native(), SOL_SOCKET, SO_PRIORITY, &so_priority, sizeof(so_priority));

Я использую tc, чтобы убедиться, что мой трафик переходит в полосу 0, а весь остальной трафик - в полосу 2:

tc -s qdisc ls dev eth0

Вот в чем проблема: когда нет другого трафика, я вижу задержки в диапазоне 500 мс. Когда у меня есть другой трафик (например, задание scp, копирующее файл размером 100 МБ), задержки увеличиваются до 10+ мс. Что действительно странно, так это то, что ни одна из работ, которые я делал, не имела никакого влияния. На самом деле, если я поменяю местами (поэтому весь мой трафик идет по полосе 2 с более низким приоритетом, а другой трафик по полосе 1), я не вижу никакой разницы в задержке.

Чего я ожидал, так это того, что при наличии другого трафика в сети увеличилось время ожидания примерно на 150 мкс, а не на 10 мс! Кстати, я проверил, что загрузка блока другими процессами (с приоритетом не в реальном времени) не влияет ни на задержку, ни на трафик на других интерфейсах.

Еще одно замечание: если я уроню mtu до 500 байт, задержка уменьшится примерно до 5 мс. Тем не менее, это на порядок хуже, чем в незагруженном корпусе. Кроме того - почему изменение mtu так сильно на него влияет, но использование tc для настройки очередей с приоритетом не имеет значения ???

Почему тк не помогает мне? Что мне не хватает?

Спасибо!

Eric

Ответы [ 3 ]

0 голосов
/ 01 ноября 2010

Средство prio просто отправит пакет с наивысшим приоритетом, доступный в то время, когда оно отправляет пакеты (обычно, как только предыдущий пакет был отправлен, если нет пакетов, ожидающих выхода).

Ваш тест основан на том, что пакеты были помещены в очередь соответствующими процессами программы на каждой машине, а полученные пакеты были получены из порта на каждой машине.

Любые задержки планирования, которые влияют на время, которое процесс получает на любой машине, могут повлиять на способность процесса помещать сообщение в очередь или получать и обрабатывать сообщение из очереди.Похоже, что вы загрузили хотя бы одну из машин, чтобы проверить это, но мой опыт показывает, что загрузка машины определенно повлияет на измеренную задержку, как эта (порядка миллисекунд, а не микросекунд), поэтому, возможно, стоит повторить это с обеими загруженными машинами.с высокоприоритетными задачами.

Другая вещь, которую нужно проверить, - это отметка времени, которую вы используете для измерения задержки - это время, когда фактически отраженное сообщение получено на клиентском компьютере, или время, которое ваша программа обрабатывает его.Если последнее, то вы измеряете не только задержку в сети, но и время между полученным сообщением и тем, как ваша программа получает частичку процессора и до того момента, когда вы проверяете время - см. http://wiki.wireshark.org/Timestamps.

Кроме того, я не думаю, что вы сможете получить гарантированный отклик на микро втором уровне без механизма, подобного ОС в реальном времени.С другой стороны, если ваше приложение похоже на VoIP, то у вас будет нормально примерно до 200 миллисекунд.

0 голосов
/ 01 апреля 2014

Вы пытались перехватить пакеты и проверить, изменилось ли значение TOS заголовка IP?

вам необходим Linux 2.6.39 или выше, чтобы использовать SO_PRIORITY.

вместо этого вы должны изменить IP_TOS.

вы должны установить:

int iptos_precedence = 0xc0;
if (setsockopt(sock_fd, IPPROTO_IP, IP_TOS, &iptos_precedence, sizeof(iptos_precedence)) < 0) {
           //print errno (or something like that)
}
0 голосов
/ 21 сентября 2010

Вы ничего не сказали об остальной части вашей сети, но я предполагаю, что вы попали в очередь на вышестоящем маршрутизаторе, который обычно имеет длинные очереди для оптимизации пропускной способности. Лучший способ исправить это - передать приоритетную очередь в формирователь с полосой пропускания чуть ниже полосы пропускания восходящего потока. Таким образом, ваши пакеты с массовым приоритетом будут помещаться в очередь в вашем ящике, а не на внешнем маршрутизаторе, что позволяет вашим высокоприоритетным пакетам переходить в начало очереди, как вы ожидаете.

...