В прошлой заметке мы рассматривали некоторые аспекты тюнинга роутера под Linux, предназначенного для работы в условиях высоких нагрузок: Linux под нагрузкой. Маршрутизатор, NAT-сервер Теперь же речь пойдет о шейперах.
Ограничение скорости прохождения трафика (шейпинг) является достаточно ресурсоемкой задачей. Поэтому, при наличии в сети хотябы нескольких сотен абонентов, и при наличии больших объемов проходящего трафика, вопрос оптимизации шейперов встает особенно остро.
Рассматривать будем шейпер под управлением Linux: эта ОС показала наилучшие результаты по производительности в условиях высоких нагрузок.
Шейпер — дисциплина обслуживания очереди пакетов. Дисциплина может быть с классами и без оных. С классами — значит, что трафик может быть “зашейпен” в соответствии с определенным классом.
Какой трафик каким классом шейпится – определяет фильтр.
Говоря проще, имеем два дерева: дерево фильтров и дерево классов. Фильтры раскидывают по определеным критериям трафик на классы. В классах трафик приоретизируется или шейпится в соответствии с заданными в классах параметрами.
Как любое дерево, дерево фильтров становится слишком ресурсо-затратным при достижении определенного порога.
Когда пакет от какого-то IP-адреса попадает на дерево фильтров, он начинает сравниваться с критериями каждого фильтра. При совпадении, пакет отправляется в соответствующий класс. Т.е. для каждого пришедшего пакета производится последовательно проверка на предмет соответствия критерию каждого фильтра в дереве до тех пор, пока не произойдет совпадение.
Например, для сети по 24-й маске у нас будет в среднем 128 шагов для каждого пакета при поиске нужного для него класса.
Это несущественно при небольших объемах трафика и при небольшом кол-ве абонентов. Когда же абонентов десятки тысяч, а в интернет уходят гигабиты, такой подход становится просто невозможным – сервер шейпинга банально не будет справляться с нагрузкой.
Если все дерево – это последовательность проверок на IP-адрес, то гораздо эффективнее будет задействовать хеши. Хеш — это таблица соответствий неких “значений” неким “ключам”. В нашем случае ключеом выступает IP-адрес, а значением – фильтр, направляющий пакет в свой класс.
Таким образом, по ключу (IP-адресу) мы быстро находим нужный фильтр для пакета, – в 1 шаг.
Собственно, про использование хешей статей уже написано немало – это не является “чем-то военным”. Можно обратиться к первоисточнику.
Сильно облегчить жизнь при построении шейперов может вот такой вот Fast U32 hashing filter generator – это программа на Си, написанная румынским (?) сисадмином.
На вход ей даются следующие параметры:
Подробные примеры можно посмотреть на странице проекта выше.
Строго говоря, вам не нужно особенно глубоко вникать в суть работы данной программы – в данном случае вам не придется иметь с ней дело.
Для удобства я написал небольшой скрипт, который на основе заданной конфигурации строит таблицы префиксов и классов, запускает упомянутую выше программу для построения фильтров с нужными параметрами, из всего имеющегося добра строит готовую конфигурацию шейпера и запускает его через tc –b.
Все что требуется – указать некоторые конфигурационные параметры в файле.
В папке скрипта есть следующие папки и файлы:
Вся конфигурация скрипта лежит в файле config. Для настройки надо обязательно под себя поменять следующие параметры:
Остальное менять не нужно.
В файле networks можно описать сети, для которых надо строить шейперы. Если файл пуст – шейперы будут строиться для всех абонентов.
IP-адреса абонентов выбираются из БД в MySQL.
Таблица shapers:
Таблица cl_status:
Скорее всего, проще будет адаптировать запрос выборки IP-адресов абонентов под вашу конкретную БД, чем наоборот. Для этого нужно соответствующим образом поправить запрос в 70-й строке файла shaper.php
Для работы скрипта необходимо откомпилировать прилагающийся файл prefixtree.c
Делается это командой: gcc prefixtree.c –o prefixtree
Хочу заметить, что вместе с данным скриптом прилагается слегка исправленный вариант prefixtree, адаптированный для такого использования.
После того как вы внесли соответствующие изменения в config, разобрались с select’ами в shaper.php, откомпилировали prefixtree.c, внесли (если необходимо) нужные сети в networks – можно запускать скрипт.
Запуск должен производиться из-под root, и заключается он просто в:
/usr/bin/php –q shaper.php
После этого скрипт:
В результате чего будет построен и запущен шейпер на заданном интерфейсе по заданным параметрам для заданных IP-адресов.
Если у абонента несколько IP-адресов – будет построен один класс с заданным параметром скорости и все IP-адреса абонента будут направлены в этот класс. Таким образом, если у абонента несколько IP, будет создан один “канал” заданной скорости, который будет делиться между его IP.
Результирующая конфигурация шейпера будет лежать в data/_classes – это готовый файл конфига, который можно скармливать tc с опций batch (-b).
Все этапы работы скрипта отражаются в логах – папка log.
Подобный шейпер успешно обслуживает более 5 тысяч абонентов.
Конкретные значения полос пропускания и параметры htb в файле shaper.php необходимо будет править в каждом конкретном случае.
Поскольку кода слишком много, чтобы приводить его здесь целиком, скачать скрипт можно на его домашней странице
Ограничение скорости прохождения трафика (шейпинг) является достаточно ресурсоемкой задачей. Поэтому, при наличии в сети хотябы нескольких сотен абонентов, и при наличии больших объемов проходящего трафика, вопрос оптимизации шейперов встает особенно остро.
Рассматривать будем шейпер под управлением Linux: эта ОС показала наилучшие результаты по производительности в условиях высоких нагрузок.
Короткое введение
Шейпер — дисциплина обслуживания очереди пакетов. Дисциплина может быть с классами и без оных. С классами — значит, что трафик может быть “зашейпен” в соответствии с определенным классом.
Какой трафик каким классом шейпится – определяет фильтр.
Говоря проще, имеем два дерева: дерево фильтров и дерево классов. Фильтры раскидывают по определеным критериям трафик на классы. В классах трафик приоретизируется или шейпится в соответствии с заданными в классах параметрами.
С хешами и без хешей
Как любое дерево, дерево фильтров становится слишком ресурсо-затратным при достижении определенного порога.
Когда пакет от какого-то IP-адреса попадает на дерево фильтров, он начинает сравниваться с критериями каждого фильтра. При совпадении, пакет отправляется в соответствующий класс. Т.е. для каждого пришедшего пакета производится последовательно проверка на предмет соответствия критерию каждого фильтра в дереве до тех пор, пока не произойдет совпадение.
Например, для сети по 24-й маске у нас будет в среднем 128 шагов для каждого пакета при поиске нужного для него класса.
Это несущественно при небольших объемах трафика и при небольшом кол-ве абонентов. Когда же абонентов десятки тысяч, а в интернет уходят гигабиты, такой подход становится просто невозможным – сервер шейпинга банально не будет справляться с нагрузкой.
Если все дерево – это последовательность проверок на IP-адрес, то гораздо эффективнее будет задействовать хеши. Хеш — это таблица соответствий неких “значений” неким “ключам”. В нашем случае ключеом выступает IP-адрес, а значением – фильтр, направляющий пакет в свой класс.
Таким образом, по ключу (IP-адресу) мы быстро находим нужный фильтр для пакета, – в 1 шаг.
Собственно, про использование хешей статей уже написано немало – это не является “чем-то военным”. Можно обратиться к первоисточнику.
Скрипт для построения шейпера
Сильно облегчить жизнь при построении шейперов может вот такой вот Fast U32 hashing filter generator – это программа на Си, написанная румынским (?) сисадмином.
На вход ей даются следующие параметры:
- prefix.in – список префиксов и соответствующих им классов в формате <префикс> <класс>
- u32filters.out – выходной файл, сюда будут сохраняться фильтры
- interface – имя интерфейса, на котором будет строиться шейпер
- src/dst – направление потока (входящий или исходящий)
- batch – если этот параметр указан, выходной файл будет генерироваться пригодным для запуска tc –b
Подробные примеры можно посмотреть на странице проекта выше.
Строго говоря, вам не нужно особенно глубоко вникать в суть работы данной программы – в данном случае вам не придется иметь с ней дело.
Для удобства я написал небольшой скрипт, который на основе заданной конфигурации строит таблицы префиксов и классов, запускает упомянутую выше программу для построения фильтров с нужными параметрами, из всего имеющегося добра строит готовую конфигурацию шейпера и запускает его через tc –b.
Все что требуется – указать некоторые конфигурационные параметры в файле.
Конфигурация скрипта
В папке скрипта есть следующие папки и файлы:
- data – здесь будут располагаться промежуточные результаты работы скрипта, а так же конечная конфигурация шейпера: _classes – готовый конфиг шейпера, _filters – фильтры с хешами, _prefixes – таблица соответствий префиксов классам, _speeds – соответствие классов скоростям
- lib – необходимые для работы библиотеки
- log – логирование событий при работе скрипта
- pid – здесь лежит pid процесса для предотвращения одновременного запуска нескольких копий скрипта
- config – основной файл конфигурации скрипта
- networks – список сетей, к которым необходимо строить шейперы
- prefixtree.c – исходник построителя фильтров с хешами
- shaper.php – сам скрипт шейпера
Вся конфигурация скрипта лежит в файле config. Для настройки надо обязательно под себя поменять следующие параметры:
- в начале конфига параметры подключения к БД для забора IP-адресов и параметров скорости
- DEV – интерфейс, на котором строить шейпер
- DIR – направление потока трафика по отношению к абонентам: может быть in или out (входящий и исходящий соответственно)
Остальное менять не нужно.
В файле networks можно описать сети, для которых надо строить шейперы. Если файл пуст – шейперы будут строиться для всех абонентов.
IP-адреса абонентов выбираются из БД в MySQL.
Таблица shapers:
- shaper_id – уникальный идентификатор абонента
- id – идентификатор шейпера
Таблица cl_status:
- ip – IP-адрес абонента
- shaper_id – уникальный идентификатор абонента
- status – состояние абонента (3 – вкл)
- sin – скорость входящая
- sout – скорость исходящая
Скорее всего, проще будет адаптировать запрос выборки IP-адресов абонентов под вашу конкретную БД, чем наоборот. Для этого нужно соответствующим образом поправить запрос в 70-й строке файла shaper.php
Компилирование prefixrtee.c
Для работы скрипта необходимо откомпилировать прилагающийся файл prefixtree.c
Делается это командой: gcc prefixtree.c –o prefixtree
Хочу заметить, что вместе с данным скриптом прилагается слегка исправленный вариант prefixtree, адаптированный для такого использования.
Запуск скрипта
После того как вы внесли соответствующие изменения в config, разобрались с select’ами в shaper.php, откомпилировали prefixtree.c, внесли (если необходимо) нужные сети в networks – можно запускать скрипт.
Запуск должен производиться из-под root, и заключается он просто в:
/usr/bin/php –q shaper.php
После этого скрипт:
- прочитает config
- прочитает networks
- сделает необходимую выборку из БД для каждого IP (на основе networks)
- создаст файл data/_prefixes
- создаст файл data/_speeds
- запустит prefixtree на исполнение, который создаст файл data/_filters
- создаст файл data/_classes
- запустит tc –b data/_classes
В результате чего будет построен и запущен шейпер на заданном интерфейсе по заданным параметрам для заданных IP-адресов.
Если у абонента несколько IP-адресов – будет построен один класс с заданным параметром скорости и все IP-адреса абонента будут направлены в этот класс. Таким образом, если у абонента несколько IP, будет создан один “канал” заданной скорости, который будет делиться между его IP.
Результирующая конфигурация шейпера будет лежать в data/_classes – это готовый файл конфига, который можно скармливать tc с опций batch (-b).
Логи
Все этапы работы скрипта отражаются в логах – папка log.
Статистика
Подобный шейпер успешно обслуживает более 5 тысяч абонентов.
Примечания
Конкретные значения полос пропускания и параметры htb в файле shaper.php необходимо будет править в каждом конкретном случае.
Скачать скрипт
Поскольку кода слишком много, чтобы приводить его здесь целиком, скачать скрипт можно на его домашней странице