RSS
 

Настройка FreeBSD для multicast-to-unicast прокси

07 Mar

Речь пойдет о небольшом тюнинге FreeBSD для нашей небольшой утилиты, позволяющей multicast-потоки (IPTV) отдавать зрителям по HTTP. Если планируется отдавать IPTV для 10-20 клиентов, то никакой специфичной настройки не нужно – все будет работать “из коробки”, но в том случае, если есть необходимость отгрузить полный 1Гбит/с, к вопросу следует подойти более внимательно.

Во-первых, нужен сервер с быстрой шиной и серверными Ethernet. Процессор не важен, на него нагрузки практически нет. Хорошие результаты мы получили на сервере Supermicro с материнской платой X8SIE-F с минимальным процессором (G6950). На борту – пара Intel® 82574L Gigabit Ethernet Controllers, что нам и нужно.

Один из интерфейсов включаем для приема multicast, второй у нас будет использоваться для отгрузки HTTP-потоков. Ставим на сервер FreeBSD 8.x и делаем следующее:

1) Включаем polling на интерфейсах в /etc/rc.conf:

ifconfig_em0="inet XX.XX.XX.XX netmask 255.255.255.ZZ polling"
ifconfig_em1="inet YY.YY.YY.YY netmask 255.255.255.XX polling"

2) Разрешаем драйверу em(4) использовать увеличенные очереди сетевых адаптеров (внимание – на desktop-ориентированных адаптерах может вызывать крэш при загрузке системы!). Для этого добавляем в /boot/loader.conf строки:

hw.em.txd=4096
hw.em.rxd=4096

3) Добавляем в /etc/sysctl.conf строки:

# Turn this off on highspeed, lossless connections (LAN 1Gbit+)
net.inet.tcp.delayed_ack=0
# Disable randomizing of ports to avoid false RST
# Before usage check SA here www.bsdcan.org/2006/papers/ImprovingTCPIP.pdf
# (it's also says that port randomization auto-disables at some conn.rates, but I didn't tested it thou)
net.inet.ip.portrange.randomized=0
# For outgoing connections only. Good for seed-boxes and ftp servers.
net.inet.ip.portrange.first=1024
net.inet.ip.portrange.last=65535
# Max bumber of timewait sockets
net.inet.tcp.maxtcptw=40960
# FIN_WAIT_2 state fast recycle
net.inet.tcp.fast_finwait2_recycle=1

net.inet.tcp.sendbuf_auto=1      # Send buffer autotuning enabled by default
net.inet.tcp.sendbuf_inc=16384    # step size
net.inet.tcp.recvbuf_auto=1      # enabled
net.inet.tcp.recvbuf_inc=524288   # step size

# Extreme polling tuning
kern.polling.burst_max=1000
kern.polling.each_burst=1000
kern.polling.reg_frac=100
kern.polling.user_frac=1
kern.polling.idle_poll=0

4) Собираем ядро с опциями:

options         DEVICE_POLLING
options         HZ=2000

5) Увеличиваем в два раза размер буфера для relaying. У меня генерируется небольшой shell-скрипт для запуска relaying примерно вот такого вида:

#!/bin/sh
IF_HTTP=XX.XX.XX.XX
IF_UDP=YY.YY.YY.YY
rm -f /var/tmp/relaying.log
killall relaying-freebsd; sleep 1
/usr/local/iptv/bin/relaying-freebsd --bs=19997936   --outhttp=$IF_HTTP:4500 --inudp=233.61.ZZ.Z0:1234 --inudpif=$IF_UDP  >> /var/tmp/relaying.log &
/usr/local/iptv/bin/relaying-freebsd --bs=19997936   --outhttp=$IF_HTTP:4501 --inudp=233.61.ZZ.Z1:1234 --inudpif=$IF_UDP  >> /var/tmp/relaying.log &

Не забываем добавить вызов этого скрипта в /etc/rc.local, перезагружаемся и наши благодарные клиенты наслаждаются IPTV.

p.s. Данные с сервера, отдающего где-то ~800Мбит/с:

pxy-1# uptime
3:21PM  up 32 days,  2:59, 1 user, load averages: 1.33, 1.40, 1.08
pxy-1# ps ax | grep relaying-freebsd | grep -v grep | wc -l
75
pxy-1# netstat -m
12041/10714/22755 mbufs in use (current/cache/total)
11956/2460/14416/25600 mbuf clusters in use (current/cache/total/max)
11956/2389 mbuf+clusters out of packet secondary zone in use (current/cache)
0/72/72/12800 4k (page size) jumbo clusters in use (current/cache/total/max)
0/0/0/6400 9k jumbo clusters in use (current/cache/total/max)
0/0/0/3200 16k jumbo clusters in use (current/cache/total/max)
26922K/7886K/34808K bytes allocated to network (current/cache/total)
0/0/0 requests for mbufs denied (mbufs/clusters/mbuf+clusters)
0/0/0 requests for jumbo clusters denied (4k/9k/16k)
0/7/6656 sfbufs in use (current/peak/max)
0 requests for sfbufs denied
0 requests for sfbufs delayed
0 requests for I/O initiated by sendfile
0 calls to protocol drain routines

 

Tags:

Leave a Reply

You must be logged in to post a comment.

  1. Ashandy

    ноября 24, 2011 at 16:37

    строка ps ax | grep relaying-freebsd | grep -v grep | wc -l не отображает кол-во клиентов сморящих в даный момент иптв. а както это можно сделать?

     
    • Ashandy

      ноября 24, 2011 at 16:38

      то есть я имел ввиду что эта строка отображает кол-во запущенных процессов relaying-freebsd, но не клиентов..

       
      • 220B

        июня 12, 2012 at 10:42

        Для симантического удобства я принял нумерацию портов вида 10001-10ххх, по этому моё решение выглядит так:

        IP=10.0.254.254
        echo -e "RelayertttClient"
        netstat -n|grep tcp|egrep $IP.10|grep -i established|awk '{print $4"t"$5}'|sort
        echo Now `netstat -n|grep tcp|egrep $IP.10|grep -i ESTABLISHED -c` clients

        p.s. переменную IP поменяйте на адрес вашего релея

         
  2. martin

    июня 10, 2012 at 09:09

    netstat -n | grep "ИП сервера" | grep EST -c
    это отобразит количество смотрящих

     
    • 220B

      июня 13, 2012 at 14:03

      martin кроме работающих релеев эта команда покажет вам все прочие установленные в данный момент вашим сервером соединения, по этому это очень не точные данные будут

       
      • martin

        июня 20, 2012 at 22:08

        ну никто ж не мешает еще и грепнуть порты на которых идет вещание..

         
  3. dima

    июня 12, 2012 at 20:34

    Подскажите пожалуйста, что еще нужно прописать в /etc/sysctl.conf для оптимизации сетевых настроек. У меня процесс трансляции одного и того же канала на несколько клиентов начинает тормозить и клиенты поучают картинку с разным временем, разница до 8 секунд.

     
  4. dima

    июня 12, 2012 at 20:35

    Можно ли как-то сделать так, чтобы клиенты получали одинаковый поток без отставания, тоесть синхронизировались их после отставания. Система стоит FreeBSD 9.