Какво е HFSC и има ли почва у нас
Снощи нямах какво да правя, та взех и преведох текст от разни места и го събрах в едно материалче което разглежда принципа на действие на HFSC. Има примери как се прави това в Linux и *BSD.
Статията може да е скучна за доста хора, така че който го интересува да чете навътре
Има различни реализации на алгоритми за подобряване Качеството на услугата (QoS), които са известни още под името "планировчици". Повечето от тях използват клас-базирани опашки (CBQ) - трафика се разделя по класове. Всеки клас има лимит (част от общия лимит на връзката), който не може да се надвиши от сесиите, които попадат в класа. Различни планировчици са: RED, ECN, CBQ, HTB, WFQ, WRR, HFSC... "HFSC" означава "честна йерархична крива на услугата". Целта на алгоритъма е да гарантира адаптивно и гъвкаво изменение на трафика в реално време; плавно споделяне между йерархчно разположените класове. Какви са ползите от подобен тип алгоритъм:
- може да се направи филтър, който вкарва ACK пакетите в клас с по-висок приоритет. Така трансферите ще преминават с нормална скорост, дори и при натоварена връзка.
- може да се контролира забавянето на пакетите (latency) както и скоростта им на преминаване (bandwidth)
- може да се задават точни параметри на пиковите трансфери (burst), които са с малка продължителност, но използват връзката на максимум. Тези параметри включват големина на пика и плавното му намаляване след максимално определената продължителност. По този начин кратки трансфери ще преминават по-бързо (каквито са HTTP заявки и отговорите), докато големите трансфери ще се ограничават и няма да заемат целия капацитет на връзката.
- гарантиране поведение на услугата във всички крайни класове
- честно разпределение на свободния трафик към крайните класове
Планирането чрез HFSC се основава на два принципа: предаване на трафик в реално време, което гарантира сервизната крива на крайните класове и споделяне между класовете, което се стреми да разпредели свободните ресурси. Политиката на планировчика е да активира първия принцип, когато има опастност крайните класове да не могат да получат минималния им гарантиран ресурс. През останалото време е активиран втория критерий. За да се разбере принципа на действие на HFSC трябва да се вникне в няколко модела на управление на качеството на услугата.
Модел на управление качеството на услугата чрез сервизна крива
Сервизна крива - Service curve - това е графика на преминалите данни за единица време.
![]() |
Кривата има три параметъра:
- m1 - наклон на първия сегмент
- m2 - наклон на втория сегмент
- d- пресечна точка на двата сегмента по оста Х
Според подобра на параметрите могат да се направят криви с различен наклон, вдлъбнати или изпъкнали. Вдлъбнатата крива работи добре с кратки пикове, които не стигат до максимално разрешеното време - точката d. Тази крива пропуска началото на трансфера и го ограничава ако се окаже че той не е пик, а изисква голям ресурс по цялата си дължина. Изпъкналата крива потиска първоначалния трафик и дава приоритет на връзки, които преминат точката d. Естествено може да се постигне и линейна сервизна крива, когато двата наклона са еднакви: m1 = m2.
Настройването на сервизна крива дава основен инструмент за управление качеството на услугата. Все пак това не стига за честно разпределяне на свободните ресурси между крайните класове.
Модел на виртуалното време
Всеки от класовете в йерархията има параметър vt - виртуално време, който представлява броя обслужени байтове за единица време. ВТ е въведено за първи път в PFQ (Packet Fair Queueing) алгоритъма и целта на параметъра е да синхронизира дъщерните класове в йерархията в принципа за споделяне на връзката. Когато стане възможно да се изпрати пакет се претърсва всеки от класовете в йерархията за най-малка стойност на виртуалното време. Крайният клас, който съвпадне с това изискване изпраща пакет и виртуалното време на този и на всеки друг клас нагоре по йерархията (до коренния клас) се увеличава. Винаги когато един клас изпраща пакет виртуалното му време се увеличава.
Модел на управление качеството на услугата чрез разпределяне и честна сервизна крива
Не само крайните класове, а всеки клас в йерархията има собствена сервизна крива. Целта е едновременно да се задоволят сервизните криви на крайните класове и излишъка от ресурс да бъде честно разпределен. HFSC използва този модел.
Всеки краен клас има следните три параметъра:
- d - максимално допустимото време на престой за пакет на края на опашката на класа
- e - желателното време за престой
- v - виртуалното време, свързано с класа
Класовете, които не са крайни имат само v параметър. Максималните времена на престой се изчисляват така че, сервизната крива е гарантирана когато всички пакети от дадена сесия имат време по-малко от d. Времето e се използва за избор на кой от двата планиращи принципа ще се активира за следващия пакет. Ако текущия пакет е престоял по-малко от времето e - продължил е нататък по връзката за кракто време, алгоритъма преценява има излишък от ресурс и се стреми да го разпредели. Ако текущия пакет е престоял повече от желателното време e, това е сигнал за потенциално претоварване и алгоритъма активира критерия за минимален гарантиран ресурс.
Имплементация в Linux
За контролиране качеството на услугата в Linux може да се използва инструмента tc, който е част от комплекта iproute2. Този документ няма да описва действието на tc и се предполага че читателите са запознати с него. Първата стъпка е да се инсталира обслужваща дисциплина (qdisc) към мрежовия интерфейс. Може да се добави и опция за използване на клас по подразбиране, в който ще попадне некласифицирания трафик. Общ синтаксис:
tc qdisc add dev $dev root handle $ID: hfsc [default $classID]
Пример:
tc qdisc add dev eth0 root handle 1: hfsc default 10
Добавяне на класове и изграждане на йерархия, чрез връзката parrent <-> classid.
Общ синтаксис:
tc add class dev $dev parent parentID classid $ID hfsc [ [ rt SC ] [ ls SC ] | [ sc SC ] ] [ ul SC ]
SC := [ umax bytes dmax ms ] rate BPS
Крайните класове могат да имат параметър за гарантиран ресурс в реално време (rt) както и параметър за сервизната крива, когато е активиран принципа за споделяне (ls). Вътрешните класове имат само параметъра ls, който е свързан с виртуалното време. Параметъра ul показва максимално заделения трафик, който може да попадне в класа. Параметрите rt и ls могат да бъдат изпуснати и вместо тях да се ползва описание на сервизната крива (sc). Тя се описва чрез:
- rate - скорост на предаване - височина на втория сегмент на кривата
- dmax - максимално закъснение - времето където се съединяват двата сегмента
- umax - скорост на предаване - височина на първия сегмент на кривата
Примерна йерархия от класове
tc class add dev eth0 parent 1: classid 1:1 hfsc sc rate 1000kbit ul rate 1000kbit
tc class add dev eth0 parent 1:1 classid 1:10 hfsc sc rate 500kbit ul rate 1000kbit
tc class add dev eth0 parent 1:1 classid 1:20 hfsc sc rate 500kbit ul rate 1000kbit
tc class add dev eth0 parent 1:10 classid 1:11 hfsc sc umax 1500b dmax 53ms rate 400kbit ul rate 1000kbit
tc class add dev eth0 parent 1:10 classid 1:12 hfsc sc umax 1500b dmax 30ms rate 100kbit ul rate 1000kbit
Другата част, която не засяга HFSC планировчика и няма да бъде разглеждана е създаване на филтър, който да класифицира трафика.
Пример:
tc filter add dev eth0 protocol ip parent 1: u32 match ip sport 80 0xffff classid 1:10
Имплементация в *BSD
HFSC за първи път бива вградено в open source решение за контрол качеството на услугата - това е ALTQ. ALTQ се използва в комбинация с пакетния филтър pf. Този документ няма за цел да описва пакетния филтър, така че ще се концентрираме върху HFSC. Използват се следните параметри:
- bandwidth - капацитета на връзката за даден клас. Стойността за bandwidth на дъщерните класове винаги трябва да е по-малка от bandwidth на родителския клас. Стойността за подразбиране на bandwidth е 100% от възможното за родителския клас. Стойността може да се задава в проценти, mbit, kbit...
- priority - приоритет на обслужване на класовете. Тази директива е прост начин за определяне на кои класове ще могат да изпратят пакет. Допустимите стойности за priority в HFSC и CBQ са от 0 до 7, като колкото по-високо е числото, толкова по-голям е приоритета. Също така priority влиза в сила когато връзката е натоварена и има опастност да не може да се изпълни принципа за гарантиране на минимална скорост.
- qlimit - брой "клетки" във FIFO опашка, използвана за запазване на изходящите пакети. Това се налага когато капацитетът на връзката не е достатъчен. В случай на насищане може да се случи някой от класовете да не може да предава. Тогава класовете запазват пакетите в определен брой клетки от паметта по реда им на пристигане. Когато се освободи ресурс, опашката ще бъде изпразнена навън. Използването на qlimit трябва да е само в крайни случаи, тъй като FIFO опашка противоречи на идеята за адаптивност и проспособимост на HFSC алгоритъма. Все пак запазване в паметта е по-добрата алтернатива от изпускане на пакети. Стойността на qlimit по подразбиране е 50.
- realtime - минимална гарантирана скорост, с която краен клас може да предава, независимо какво става с другите класове. Стойността на realtime може да бъде от 0% до 80% от общия капацитет на връзката.
- upperlimit - капацитет, който краен клас никога не може да надвиши.
- linkshare - същото като bandwidth, но важи само за вътрешните класове по йерархията. Ако за клас е сложена стойност на bandwidth, може да не се задава стойност за linkshare
Общ синтаксис за опашките в pf.conf:
altq on $interface $scheduler bandwidth $bw [priority $pri] [qlimit $qlim] queue { $q1, $q2, $q3...}}}
- interface - мрежовия интерфейс, където се инсталира дисциплината за обслужване
- scheduler - алгоритъм на планировчика
- bandwidth - капацитет на връзката. Задава се в b, Kb, Mb за bits, kilobits, megabits за една секунда. Стойността за подразбиране е 100% от капацитета на родителския клас.
- q1, q2, q3 ... - списък с имена на класове, които се описват по-долу
Общ синтаксис за описване на опашка (клас):
queue $name [on $interface] bandwidth $bw [priority $pri] [qlimit $qlim] $scheduler ( $sched_options ) { $queue_list }
- name - име на опашката. Трябва да съвпада с някое от имената на класовете, описани в списъка { $q1, $q2, $q3...} на родителския клас. Максималната дължина на името е 15 символа
- sched_options - допълнителни настройки и опции, които контролират поведението на планировчика
- default - дефинира класа като клас в който попада всичкия некласифициран трафик. Трябва да има само една default дефиниция за всички класове, които са към един мрежов интерфейс.
- red - активира алгоритъма Random Early Detection (RED) за опашката
- ecn - активира алгоритъма Explicit Congestion Notification (ECN) за опашката
- realtime $bw - задава параметъра realtime в HFSC
- upperlimit $bw - задава параметъра upperlimit в HFSC
- linkshare $bw - задава параметъра linkshare в HFSC
Примерна йерархия от класове
altq on rl0 bandwidth 744Kb hfsc queue { ack, dns, ssh, bulk, bittor, spamd }
queue ack bandwidth 80% priority 7 qlimit 500 hfsc (realtime 50%)
queue dns bandwidth 7% priority 6 qlimit 500 hfsc (realtime 5%)
queue ssh bandwidth 10% priority 5 qlimit 500 hfsc (realtime 10%) {ssh_bulk, ssh_login}
queue ssh_login bandwidth 90% priority 5 qlimit 500 hfsc
queue ssh_bulk bandwidth 10% priority 4 qlimit 500 hfsc
queue bulk bandwidth 1% priority 4 qlimit 500 hfsc (realtime 5% default)
queue bittor bandwidth 1% priority 3 qlimit 500 hfsc (upperlimit 99%)
queue spamd bandwidth 1% priority 2 qlimit 500 hfsc (upperlimit 1%)
Използвана литература
http://www.cs.cmu.edu/~hzhang/papers/SIGCOM97.pdf
- A Hierarchical Fair Service Curve Algorithm for LinkSharing, RealTime and Priority Services
http://linux-ip.net/articles/hfsc.en/
- HFSC Scheduling with Linux
https://calomel.org/pf_hfsc.html
- Hierarchical Fair Service Curve (HFSC) of OpenBSD
http://www.openbsd.org/faq/pf/queueing.html
- PF: Packet Queueing and Prioritization

