r =
s =
ss =
Bezklasowe / Linuksowe SFQ (Stochastic DRR): ImplementacjaWykorzystanie

Linuksowe SFQ (Stochastic DRR)

Implementacja

Linuksowa implementacja SFQ to połączenie pomysłów z DDRoryginalnego SFQ. Jak zostało to zaznaczone w źródłach[1], algorytm jest dzięki temu bardzo szybki i wykorzystuje bardzo mało pamięci. Nie jest jednak do końca sprawiedliwy z powodu stochastyczności, a także może generować większe opóżnienia z powodu obsługi karuzelowej (patrz Twierdzenie o DRR).

Dodatkowe ograniczenia mające na celu przyśpieszenie działania:

  • Maksymalna długość kolejki: 128 pakietów
  • Maksymalne MTU $2^{15}-1$ ($32767$)
  • Ilość kolejek: 1024 (tzn. że przy ilości połączeń powyżej 1024 mamy pewność ze przynajmniej dwa połączenia nie są odróżniane, przy 512 połączeniach)

Zmiana tych parametrów wymaga przekompilowania modułu.

Istnieje wersja sfq zwana e-sfq pozwalająca na większą kontrolę w działaniu algorytmu. Oryginalnym autorem jest Alexander Atanasov, który popełnił pierwsza wersję esfq w 2002 roku. W 2003 roku za sprawą Corey Hickey powstał patch do kernela 2.6.8, który jednak do tej pory nie został włącozny do głównej gałęzi. W 2008 roku Corey postanowił spróbować dołączyć esfq jako patch do oryginalnego sfq, lecz i to się nie udało.

Wykorzystanie

Najważniejszą rzeczą o której należy pamiętać podczas korzystania z SFQ jest to, że jest to algorytm typu work-conserving, tzn. że nie ogranicza on ruchu. Nie można go więc na przykład stosować bezpośrednio na interfejsie z podłączonym do niego modemem DSL o dużo mniejszej przepustowości. Natomiast dobrze sprawdza się na końcówkach drzewa jakiegoś klasowego algorytmu (CBQ, HTB czy H-FSC)

SFQ przyjmuje następujące opcje:

  • perturb — określa co ile sekund powinna nastąpić perturbacja kolejek (zmiana funkcji haszujących), bez podania tej opcji zmiana nie występuje co może powodowaćw pewnych okolicznosciach, że dwa połączenia na stałe będą nieodróżniane i jedno będzie mogło blokować inne; zalecana wartość to 10,
  • quantum — ile bajtów na raz wysyłane jest podczas karuzelowego przebiegu po wszystkich kolejkach (odpowiednik $Q_i$ w DRR) - standardowo ustawia sie tyle co MTU interfejsu, jest to także wartość minimalna,
  • limit — maksymalna ilość pakietów jaka może zostać zakolejkowana (rzeczywista długość kolejki),

ESFQ przyjmuje dodatkowo opcje:

Kilka zależności[2]:

  • Maksymalny czas jaki pakiet musi czekać na wysłanie (jeśli nie został odrzucony) to $\mathit{time} = \frac {\mathit{limit} \cdot \mathit{MTU}} {\mathit{rate}}$, gdzie rate to prędkość łącza.}
  • Dla pojedyńczego połączenia wysyłającego pakiety najsyzbciej jak może, opóźnienie ograniczone jest zależnością $\mathit{opoznienie} \le \frac {rate} {(\mathit{limit} \cdot \mathit{MTU}}$
  • Dla połączenia wysyłającego pojedyńczy pakiet: $\mathit{opoznienie} = \frac {\mathit{rate}} {\mathit{flows} \cdot \mathit{MTU}}$, gdzie flows to ilość równocześnie aktywnych połączeń

Przykłady

Przykład z man tc-sfq zakłądający kolejke sfq na interfejs ppp

tc qdisc add dev ppp0 root sfq perturb 10

Założenie kolejki sfq dla klasy 1:c i nadanie jej uchwytu c:

tc qdisc add dev eth0 parent 1:c handle c: sfq perturb 10 quantum 1500
Opcja quantum jest tu niepotrzebna, gdyż standardowa wielkość MTU to własnie 1500 bajtów.

W przypadku jeśli mamy doczynienia z bardzo słabym sprzętem, na którym sfq nie potrafi wysycić łącza, można sprobować zwiększać jednorazową dawkę dla kolejki (np. do 4xMTU = 6000b):

tc qdisc add dev ppp0 root sfq perturb 10 quantum 6000

Można także użyć opcji limit jeśli uważamy, że kolejka jest za długa, np. chcemy tanim kosztem zwiększyć responsywność w obrębie jednego połączenia:

tc qdisc add dev ppp0 root sfq perturb 10 quantum 6000 limit 64
Ustawi to długość kolejki na 64 pakiety zamiast standardowych 127 – niestety to ustawienie może spowodować, że nie będzie można rozwinąć maksymalnej prędkości przesyłu oferowanej przez łącze (lub klasę do której podpinamy sfq)

Jeśli mamy na wyjściu do internetu jakiś algorytm klasowy przypisujący np. wszystkie połączenia typu WWW do klasy 1:12, to w obrębie tej klasy nie można już dzielić pomiędzy klientów internetu, gdyż klasa znajduje się po NATowaniu. Można zastosować tu różne techniki jak np IFB, ale dużo prostrzym rozwiązaniem może być skorzystanie z esfq:

tc qdisc add dev eth1 parent 1:12 handle 12: sfq perturb 10 hash ctnatchg
Spowoduje to, że pakiety wychodząc przez klasę 1:12 będą sprawdzane za pomocą conntracka od którego klienta wewnątrz sieci pochodzą oraz haszowane na podstawie ctorigsrc (IP klienta). Jeśli dodatkowo przekierujemy jakiś port na routerze, np. 8080 dla klienta wewnątrz, to port ten możemy także wrzucić do klasy 1:12, gdyż esfq będzie połączenia z różnych hostów z zewnątrz dzielić według ctreplsrc (IP hosta z zewnątrz).

Przypisy
  1. [^] linux/net/sched/sch_sfq.c
  2. [^] sfq-2.6.24.1/README
Creative Commons License Content by Michał Pokrywka is licensed under a Creative Commons BY-SA 3.0
Ostatnia znacząca zmiana: 2010-04-28