Теория про dummynet (ipfw)

Бывает возникает задача организовать нарезку канала или настроить QoS. Информации на эту тему в интернете полно, но мало где рассказывается о том, как правильно рассчитать размер очереди, параметры для RED/GRED для определенной пропускной способности канала. Это и послужило написанию данной заметки. Здесь я не буду описывать, как создаются каналы, очереди, а изложу лишь только теоретическую часть вопроса.


Пропускная способность канала.

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


Расчет размера очереди.

Как говорит ман по ipfw, размер очереди для всех создаваемых объектов в dummynet составляет 50 слотов (так же может указываться в байтах), что является нормальным для Ethernet устройств. Чтобы получить размер очереди в байтах, нужно количество слотов умножить на MTU канала, на котором вы собираетесь нарезать скорость. Кстати, понятие размер очереди также можно трактовать как буфер для пакетов. Если указать большой размер очереди, а канал будет низкоскоростным, то пока заполнится очередь, пройдет довольно длинный промежуток времени, а это очень плохо как для планировщика (если таковой используется), так и для клиента. С такой конфигурацией пакеты очень долго будут находиться в канале, вплоть до того что клиент пославший его может не дождавшись ответа из-за таймаута подумать, что пакет где-то затерялся в пути и повторить передачу. Например, пусть размер очереди будет равным 50 слотам, а ширина канала будет составлять 128Кбит/с, то время заполнения очереди составит - (1500*8*50)/(128*1000) ~ 4,7с. Если указать слишком маленький размер очереди, то это плохо отразиться на сглаживании всплесков трафика в канале. Время, за которое заполняется очередь должно быть не более 0,5с. Приведу несколько простых формул для расчета размера очереди и др. параметров.
Обозначения:

  • MTU - максимальный размер пакета в сети (байт)
  • Qlen - размер очереди (слотов)
  • Qsize - размер очереди (байт)
  • t - время заполнения очереди (сек)
  • BW - ширина канала (бит/сек)
Формула для расчета размера очереди:
  1. Qlen = (t * BW) / (MTU * 8) (слотов)
Расчет времени заполнения очереди:
  1. t = (Qlen * MTU * 8) / BW (сек)
Перевод слотов в байты:
  1. Qsize = Qlen * MTU (байт)
Пример: рассчитаем все необходимые величины для канала с заявленной провом полосой пропускания 512 Кбит/с. Условимся, что MTU для канала будет составлять 1460 байт. Как было сказано выше брать ширину канала лучше меньше примерно на 1-5% поэтому мы будем работать с полосой пропускания в 486 Кбит/с.
  1. BW = 486 * 1000 = 486000 (бит/с)
Пусть время, за которое заполняется очередь, будет равно t = 0.2 сек. Теперь у нас есть все необходимые исходные данные для расчета размера очереди:
  1. Qlen = (t * BW) / (MTU * 8)  = (0.2 * 486000) / (1460 * 8) ~ 8 (слотов)
Но такой размер очереди слишком мал - с таким значением будут плохо сглаживаться всплески трафика. Рассчитаем время заполнения очереди, например для Qlen = 12 слотов.
  1. t = (Qlen * MTU * 8) / BW = (12 * 1460 * 8) / 486000 ~ 0.29 (сек)
Как видно из расчетов время заполнения очереди t < 0.5, то есть удовлетворяет условию, причем с запасом. Поэтому можно попробовать взять еще больший размер очереди, например в 18 слотов.
  1. t = (Qlen * MTU * 8) / BW = (18 * 1460 * 8) / 486000 ~ 0.43 (сек)
С таким размером очереди тоже можно работать. Таким образом, данные расчеты лишь помогают выбрать приблизительно оптимальный размер очереди, а наиболее лучший выбирается методом проб и наблюдений.

Расчет параметров RED/GRED.

Думаю, подробно описывать работу данных алгоритмов ни к чему, потому что данной инфы в интернете полно. Скажу лишь вкратце, что RED начинает отбрасывать пакеты с линейно возрастающей вероятностью, когда перегрузка находится между указанными порогами и отбрасывать все пакеты, когда перегрузка превышает максимальный порог. А GRED действует чуть мягче - когда перегрузка находится между максимальным порогом и удвоенным максимальным порогом, то он еще с большей линейно возрастающей вероятностью отбрасывает пакеты, а при превышении и этого порога отбрасываются все пакеты. Кто хочет более глубоких познаний в этой области, то вам на официальный сайт за документацией.


Задаваемые параметры:
  • w_q - весовой фактор для расчетов средней загрузки, вещественное число в диапазоне 0..1. Наилучшим считается 0.002, поэтому его трогать не стоит.
  • min_th - минимальный порог, после которого начинают отбрасываться пакеты. В зависимости от того, что вы указали в размере очереди, задается либо в слотах, либо в байтах.
  • max_th - максимальный порог, после которого начинают отбрасываться все пакеты (RED) или с еще большей вероятностью (GRED). В зависимости от того, что вы указали в размере очереди, задается либо в слотах, либо в байтах.
  • max_p - максимальная вероятность отбрасывания пакетов, вещественное число в диапазоне 0..1. Наилучшим считается 0.1, поэтому его трогать не стоит. При превышении порога min_th пакеты отбрасываются с линейно возрастающей вероятностью от 0 до max_p. Для GRED при превышении порога max_th пакеты отбрасываются с линейно возрастающей вероятностью от max_p до 1, пока не будет достигнут порог 2*max_th.
Из вышесказанного следует, что нам нужны только параметры min_th и max_th. Рассчитываются они просто:
  • RED:
    1. min_th = (Qlen | Qsize) / 6 (слотов | байтов)
    2. max_th = Qlen | Qsize (слотов | байтов)
  • GRED:
    1. min_th = (Qlen | Qsize) / 6 (слотов | байтов)
    2. max_th = (2..5) * min_th (слотов | байтов)
Например, для вышеприведенного примера параметры для алгоритма GRED будут такими:
  1. min_th = Qlen / 6 = 18 / 6 = 3
  2. max_th (2..5)* min_th = 3 * 3 = 9
Ну вот, в принципе и все, что я хотел сказать о расчетах параметров для dummynet. Если есть, что добавить, то прошу в комменты.

Добавить комментарий

Filtered text

CAPTCHA
Этот вопрос предназначен для предотвращения автоматизированной обработки форм.
Fill in the blank.