Jump to content
Калькуляторы

что не так с шейпером?

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

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

шейпер на основе htb+sfq не даёт желаемого результата, ибо скорость качалки понижается, но недостаточно, и к тому же недостаточно быстро.

 

возможности использовать esfq - нету.

 

#!/bin/sh
insmod imq
ip link set imq0 up
iptables -t mangle -F
iptables -t mangle -A PREROUTING -p tcp -i ppp0 -j IMQ --todev 0

TC=tc
DEVB=imq0

$TC qdisc del dev $DEVB root
$TC qdisc add dev $DEVB root handle 1: htb default 30

$TC class add dev $DEVB parent 1:  classid 1:1  htb rate 1000kbit  ceil  2000kbit burst 15k
$TC class add dev $DEVB parent 1:1 classid 1:10 htb rate 1kbit  ceil  2000kbit burst 15k
$TC class add dev $DEVB parent 1:1 classid 1:20 htb rate 1kbit  ceil  2000kbit burst 15k
$TC class add dev $DEVB parent 1:1 classid 1:30 htb rate 1kbit  ceil  2000kbit burst 15k

$TC qdisc add dev $DEVB parent 1:10  red min 1600 max 3210 burst 2 limit 32100 avpkt 1000
$TC qdisc add dev $DEVB parent 1:20  sfq perturb 10
$TC qdisc add dev $DEVB parent 1:30  sfq perturb 10

$TC filter add dev $DEVB protocol ip parent 1:0 prio 1 u32 match tcp sport 80 0xffff flowid 1:10

 

 

как можно зашейпить трафик так, чтобы в случае обращения ко всякого рода видеосервисам канал почти весь отдавался http, а не качалке?

Share this post


Link to post
Share on other sites

В классах раставьте prio, для качалки 2-3, для http 0

Просто rate - недостаточно.

И вместо red лучше bfifo

 

#!/bin/sh

insmod imq

ip link set imq0 up

iptables -t mangle -F

iptables -t mangle -A PREROUTING -p tcp -i ppp0 -j IMQ --todev 0

 

TC=tc
DEVB=imq0

$TC qdisc del dev $DEVB root
$TC qdisc add dev $DEVB root handle 1: htb default 30

$TC class add dev $DEVB parent 1:  classid 1:1  htb rate 1000kbit  ceil  2000kbit burst 15k
$TC class add dev $DEVB parent 1:1 classid 1:10 htb rate 1kbit  ceil  2000kbit burst 15k prio 0
$TC class add dev $DEVB parent 1:1 classid 1:20 htb rate 1kbit  ceil  2000kbit burst 15k prio 2
$TC class add dev $DEVB parent 1:1 classid 1:30 htb rate 1kbit  ceil  2000kbit burst 15k prio 2

$TC qdisc add dev $DEVB parent 1:10  bfifo limit 1000000
$TC qdisc add dev $DEVB parent 1:20  sfq perturb 10
$TC qdisc add dev $DEVB parent 1:30  sfq perturb 10

$TC filter add dev $DEVB protocol ip parent 1:0 prio 1 u32 match tcp sport 80 0xffff flowid 1:10

Edited by disappointed

Share this post


Link to post
Share on other sites

И ещё

$TC class add dev $DEVB parent 1: classid 1:1 htb rate 1000kbit ceil 2000kbit burst 15k

правильнее

$TC class add dev $DEVB parent 1: classid 1:1 htb rate 2000kbit

+ Важно! Оставить не менее 10% от полосы свободной.

Если тариф 2метра, ставить не более 1800Кбит на 1:1

Edited by disappointed

Share this post


Link to post
Share on other sites

добавил приоритеты, изменил дисциплины, оставил часть полосы - всё равно с работающими торрентами не посмотришь шибко видео ((

Share this post


Link to post
Share on other sites

увидев этот топик задумался о своём шейпере, т.к. тоже есть жалобы на просмотр онлайн-видео: локальный шейпер на 30МБит/сек каждому + шейпер анлимов в зависимости от тарифа

 

локальный:

/sbin/tc class add dev eth2 parent 1:2 classid 1:$lD htb rate ${dL}Mbit ceil ${dL}Mbit burst 15k prio 3
/sbin/tc qdisc add dev eth2 parent 1:$lD handle $lD sfq perturb 10
/sbin/tc filter add dev eth2 parent 1:0 protocol ip prio 200 handle $lD fw classid 1:$lD

dL=30

lD - маркер для каждого ip индивидуально

 

шейпер анлимов:

/sbin/tc class add dev eth2 parent 1:2 classid 1:$uD htb rate ${Usp}Kbit ceil ${Usp}Kbit burst 15k prio 3
/sbin/tc qdisc add dev eth2 parent 1:$uD handle $uD sfq perturb 10
/sbin/tc filter add dev eth2 parent 1:0 protocol ip prio 200 handle $uD fw classid 1:$uD

Usp - скорость безлимита в килобитах

uD - индивидуальный маркер анлимщика, генерируется статически из ip-адреса

 

"prio 3" здесь грабля для инета? Спасибо тем кто подскажет (;

 

юзеров около 25 человек, канал в инет в 2-3 раза шире пиковой нагрузки

Edited by yKpon

Share this post


Link to post
Share on other sites
добавил приоритеты, изменил дисциплины, оставил часть полосы - всё равно с работающими торрентами не посмотришь шибко видео ((

http://stat.oborona.net/temp/tc-viewer

 

./tc-viewer imq0

 

Визуально видно перераспределение?

Share this post


Link to post
Share on other sites
увидев этот топик задумался о своём шейпере, т.к. тоже есть жалобы на просмотр онлайн-видео: локальный шейпер на 30МБит/сек каждому + шейпер анлимов в зависимости от тарифа

 

локальный:

/sbin/tc class add dev eth2 parent 1:2 classid 1:$lD htb rate ${dL}Mbit ceil ${dL}Mbit burst 15k prio 3
/sbin/tc qdisc add dev eth2 parent 1:$lD handle $lD sfq perturb 10
/sbin/tc filter add dev eth2 parent 1:0 protocol ip prio 200 handle $lD fw classid 1:$lD

dL=30

lD - маркер для каждого ip индивидуально

 

шейпер анлимов:

/sbin/tc class add dev eth2 parent 1:2 classid 1:$uD htb rate ${Usp}Kbit ceil ${Usp}Kbit burst 15k prio 3
/sbin/tc qdisc add dev eth2 parent 1:$uD handle $uD sfq perturb 10
/sbin/tc filter add dev eth2 parent 1:0 protocol ip prio 200 handle $uD fw classid 1:$uD

Usp - скорость безлимита в килобитах

uD - индивидуальный маркер анлимщика, генерируется статически из ip-адреса

 

"prio 3" здесь грабля для инета? Спасибо тем кто подскажет (;

 

юзеров около 25 человек, канал в инет в 2-3 раза шире пиковой нагрузки

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

Share this post


Link to post
Share on other sites

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

можно одним глазом глянуть как он работает ?

Share this post


Link to post
Share on other sites

весь инет трафик перенаправляется на imq0;

хттп подсчитывается ulog-acctd;

мы знаем какая скорость отдана под канал хттп и время, в течении которого собирается статика: рассчитываем порог время*скорость-несколько%;

если собранная статика превышает рассчитанный порог (те загрузка канала для хттп высока), то значит скорости для хттп не хватает - накидываем скорости;

если ниже порога - скорости выделено с излишком - начинаем постепенно урезать;

ночью с 1-8 всё отдаём торрентам;

скрипт крутится на ембедед железке - вся статика собирается в память (ramfs), поэтому чтоб память неожиданно не кончилась каждые 500 проходов файл очищаем;

 

скрипт, которые всё это делает

#!/opt/bin/bash

insmod imq
insmod ipt_IMQ
ip link set imq0 up
iptables -t mangle -F

iptables -t mangle -A POSTROUTING -p tcp -d 172.16.0.0/16 -s \! 172.16.0.0/16 -j IMQ --todev 0


# сколько раз производилось чтения статики
let count_update=0
# таймаут между проверками
let timeout="20"
# минимальная гарантированная скорость (kbit)
let min_speed="200"
# максимальная гарантированная скорость (kbit)
let max_speed="1900"
# current speed (kbit)
let cur_speed="$min_speed"
# шаг изменения скорости при увеличении скорости (kbit)
let step_speed_up="700"
# шаг изменения скорости при уменьшении скорости (kbit)
let step_speed_down="150"
# процент отклонения
let accurate="30"
# число прежде полученых бит
let bytes_prev="$min_speed*($timeout-2) - (($min_speed*($timeout-2))/100*$accurate)"
# сколько получено за последний раз
let diff_bytes="0"


function comp()
{
echo
curb=`awk -f ./1.awk /opt/var/log/ulog-acctd/account.log`
t=`echo $curb | wc -w`
# если строка пустая
if [ "$t" -eq 0 ]
then
  echo "   comp: awk script return empty string!"
  return -1
fi
# если в строке несколько чисел
if [ "$t" -gt 1 ]
then
  echo "   comp: awk script return more than 1 line!"
  return -1
fi

# пересчитываем в килобиты
let curb="$curb*8/1024"
# thres - расчитанный необходимый порог для изменения скорости
let thres="$cur_speed*($timeout-2) - (($cur_speed*($timeout-2))/100*$accurate)"
# diff_bytes - сколько получено с последнего раза
let diff_bytes="$curb-$bytes_prev"
if [ "$diff_bytes" -ge "$thres" ]
then
  # если превысили заданный раннее высчитанный порог - необходимо увеличить скорость
  echo "   comp: cur_speed: $cur_speed kbit, diff_bytes: $diff_bytes kbit; curb: $curb kbit; bytes_prev: $bytes_prev kbit; thres: $thres; need increase speed"
  return 1
else
  # если не превысили заданный ранне высчитанный порог - необходимо уменьшить скорость
  echo "   comp: cur_speed: $cur_speed kbit, diff_bytes: $diff_bytes kbit; curb: $curb kbit; bytes_prev: $bytes_prev kbit; thres: $thres; need decrease speed"
  return 0
fi
}

function update_shaper()
{
#return 0
TC=tc
DEVB=imq0

let t="$max_speed-$cur_speed"
`
$TC qdisc del dev $DEVB root
$TC qdisc add dev $DEVB root handle 1: htb default 30

$TC class add dev $DEVB parent 1:  classid 1:1  htb rate ${max_speed}kbit burst 10k
$TC class add dev $DEVB parent 1:1 classid 1:10 htb rate ${cur_speed}kbit burst 30k prio 0
$TC class add dev $DEVB parent 1:1 classid 1:20 htb rate 10kbit ceil 200kbit burst 20k prio 0
$TC class add dev $DEVB parent 1:1 classid 1:30 htb rate 100kbit ceil ${t}kbit burst 20k prio 6

$TC qdisc add dev $DEVB parent 1:10  sfq perturb 10
$TC qdisc add dev $DEVB parent 1:20  sfq perturb 10
$TC qdisc add dev $DEVB parent 1:30  sfq perturb 10

# http
$TC filter add dev $DEVB protocol ip prio 0 parent 1:0 u32 match ip sport 80 0xffff flowid 1:10
$TC filter add dev $DEVB protocol ip prio 0 parent 1:0 u32 match ip dport 80 0xffff flowid 1:10
# ssh
$TC filter add dev $DEVB protocol ip prio 0 parent 1:0 u32 match ip sport 22 0xffff flowid 1:20
$TC filter add dev $DEVB protocol ip prio 0 parent 1:0 u32 match ip dport 22 0xffff flowid 1:20
`
# даём несколько секунда на восстановление скорости после изменения настроек шейпера
sleep 2
}

update_shaper


while [ 1 ]
do
t=`date +%H`
let t="$t"
if [ "$t" -ge "1" ] && [ "$t" -le "8" ]
then
  tc qdisc del dev imq0 root
  let t="7*3600"
  echo " main: night mode: shaper will delete! sleep: $t sec"
  sleep $t
fi

comp
ret=$?
bytes_prev=$curb

# если канал таки загружен
if [ "$ret" -eq 1 ]
then
  # увеличиваем шаг
  let cur_speed="$cur_speed+$step_speed_up"
  # новая скорость не должна быть больше max_speed
  if [ "$cur_speed" -gt "$max_speed" ]
  then
   cur_speed=$max_speed
  fi
  # перестраиваем шейпер
  echo "main: increase speed: new cur_speed: $cur_speed"
  update_shaper

  # если канал таки не загружен
elif [ "$ret" -eq "0" ]
  then
   if [ "$cur_speed" -ne "$min_speed" ]
   then
    # скорость понижаем гораздо медленее чем повышаем
    let cur_speed="$cur_speed-$step_speed_down"
    # новая скорость не должна быть меньше min_speed
    if [ "$cur_speed" -lt "$min_speed" ]
    then
     cur_speed=$min_speed
    fi
    update_shaper
    echo "main: decrease speed: new cur_speed: $cur_speed"
   else
    echo  "main: decrease speed (without update_shaper): new cur_speed: $cur_speed"
   fi

   # если функция сравнения не смогла обработать данные
elif [ "$ret" -eq "-1" ]
  then
   echo "main: ERROR: invalid argument passed in comapre function!"
fi
let count_update="$count_update+1"
# каждые 500 обновлений очищаем файл
if [ "$count_update" -eq "500" ]
then
  if [ -e /opt/var/run/ulog-acctd.pid ];
  then
   echo "main: stop aulog-acctd; remove log file"
   kill -STOP `cat /opt/var/run/ulog-acctd.pid`;
   rm /opt/var/log/ulog-acctd/account.log
   rm /opt/var/log/ulog-acctd/debug.log
   rm /opt/var/log/ulog-acctd/dump*
   rm /opt/var/log/ulog-acctd/qwe
   echo "main: create new account.log"
   touch /opt/var/log/ulog-acctd/account.log
   echo "main: continue execute ulog-acctd"
   kill -CONT `cat /opt/var/run/ulog-acctd.pid`;
   let count_update="0"
   let bytes_prev="0"
  fi
fi
sleep $timeout

done

 

и

 

#!/usr/bin/awk -f
{
t=t+$3
}
END {
print t}

 

работает нормальн )); торренты качают на максимуме пока нету нагрузки на хттп; как только появляется нагрузка - скорости накидывается почти мегабит [чтоб видео не тормозило], снижение скорости идёт гораздо медленнее - вероятность возобновления нагрузки на хттп довольно высока :)

Edited by loginrl103

Share this post


Link to post
Share on other sites
добавил приоритеты, изменил дисциплины, оставил часть полосы - всё равно с работающими торрентами не посмотришь шибко видео ((

http://stat.oborona.net/temp/tc-viewer

 

./tc-viewer imq0

 

Визуально видно перераспределение?

пока не пробовал; на днях буду

Share this post


Link to post
Share on other sites
работает нормальн )); торренты качают на максимуме пока нету нагрузки на хттп; как только появляется нагрузка - скорости накидывается почти мегабит [чтоб видео не тормозило], снижение скорости идёт гораздо медленнее - вероятность возобновления нагрузки на хттп довольно высока :)

очеень интересно

когда то у меня тоже была идея написать скрипт для динамического шейпинга - чтобы максимально ефективно грузить внешние каналы - что то в этом роде .... но апотом сбился - если класов не много и абонентов тоже - тогда смысл есть но если много - то это дёргание ни к чему хорошему по моему не приведёт - могу ошибаться

 

Share this post


Link to post
Share on other sites

так этот велосипед онли фо хоум )) в прошивке минимальное число классификаторов и дисциплин - через них не удалось сделать что надо)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this