Оптимизация FreeBSD под высокие нагрузки

FreeBSD хорошо зарекомендовала себя как система для построения интранет- и интернет-серверов. Она предоставляет достаточно надёжные сетевые службы и эффективное управление памятью.” ©Wikipedia

Для того, что бы установленный Вами демоненок соответствовал приведенным выше высказываниям, был устойчивым к разнообразным атакам, а также достойно вел себя под высокими нагрузками с ним необходимо “поиграться”. А именно, выполнить ряд настроек конфигурационных файлов, произвести так называемый тюнинг ОС.

Под катом приведен пример настройки операционной системы высокопроизводительного и высоконагруженного вебсервера.

Общее

Основной тюнинг FreeBSD происходит посредством модификации ядра ОС или внесения изменений определенных sysctl’ей. Мы остановимся на втором варианте. Все параметры разделяются на две группы:

  1. Параметры применяемые только при загрузке.
  2. Параметры применяемые на лету;

Пойдем по порядку.

Параметры применяемые при загрузке

Для правки sysctl’ей которые применяются только при загрузке, нужно внести изменения в файл /boot/loader.conf, после чего выполнить перезагрузку ОС.

#Отсутствие ограничений на размер зоны.

kern.ipc.nmbclusters=0

#После исчерпания не возможно выполнить повторную передачи пакетов.

net.inet.tcp.reass.maxsegments=2048

#Для избежания лимита “PV Entry”

vm.pmap.shpgperproc=400

### Конфигурирование драйвера em ###

#Позволяет принимать за одно прерывание до 4096 пакетов

hw.em.rxd=4096

#Позволяет передавать за одно прерывание до 4096 пакетов

hw.em.txd=4096

#Минимальная задержка между генерациями прерываний в мкс для приема данных

hw.em.rx_int_delay=100

#Минимальная задержка между генерациями прерываний в мкс для передачу данных

hw.em.tx_int_delay=100

#Максимальная задержка между генерациями прерываний в мкс для приема данных

hw.em.rx_abs_int_delay=1000

#Максимальная задержка между генерациями прерываний в мкс для передачи данных

hw.em.tx_abs_int_delay=1000

dev.em.rx_processing_limit=-1

### TCP Hostcache Tuning ###

net.inet.tcp.hostcache.hashsize=4096

net.inet.tcp.hostcache.bucketlimit=100

net.inet.tcp.hostcache.cachelimit=65536

### TCP Syncache Tuning ###

net.inet.tcp.syncache.hashsize=1024

net.inet.tcp.syncache.bucketlimit=100

net.inet.tcp.syncache.cachelimit=65536

#TCP control-block Hash table tuning

net.inet.tcp.tcbhashsize=4096

### Настройка net.isr ###

#Очередь netisr

net.isr.defaultqlimit=4096

#Прибиндить каждую очередь к отдельному ядру

net.isr.bindthreads=1

#Количество потоков netist (равно количеству ядер)

net.isr.maxthreads=8

#Размер очереди исходящий пакетов

net.link.ifqmaxlen=1024

### Модули ###

#Загружаем драйвер AHCI

ahci_load=”YES”

#Асинхронное выполнение IO системных вызовов

aio_load=”YES”

Параметры применяемые “на лету”

Для изменения параметров в уже загруженной ОС необходимо выполнить следующую команду:

<strong><em>sysctl param_name=value</em></strong>

и не забыть внести значения параметра в файл /etc/sysctl.conf, в противном случае, после перезагрузки, будет применено значение по умолчанию.

#Разрешает пользователям видеть только запущенные ими процессы

security.bsd.see_other_uids=0

#Количество сокетов

kern.ipc.maxsockets=204800

#Mbuf clusters

kern.ipc.nmbclusters=262144

#Запрещает вытеснение Wired памяти в Swap

kern.ipc.shm_use_phys=1

#Размер очереди для приема новых TCP соединений

kern.ipc.somaxconn=4096

#Определяет максимальное число дескрипторов файлов

kern.maxfiles=204800

#Максимальное число файлов на один процесс

kern.maxfilesperproc=200000

#Количество файловых дескрипторов закешированых в памяти

kern.maxvnodes=256000

#не использовать трафик и прерывания

kern.random.sys.harvest.ethernet=0

#как источник энтропии для random’a

kern.random.sys.harvest.interrupt=0

#Попытаться синхронизировать диски при панике, для избежания

#fsck после перезагрузки

kern.sync_on_panic=1

#Для защиты от SMURF атак (ICMP echo request на broadcast адрес)

net.inet.icmp.bmcastecho=0

#Игнорировать пакеты icmp redirect

net.inet.icmp.drop_redirect=1

#Не отдавать по icmp маску своей подсети

net.inet.icmp.maskrepl=0

#Размер очереди IP-пакетов

#(Необходимо увеличивать если net.inet.ip.intr_queue_drops != 0)

net.inet.ip.intr_queue_maxlen=256

#Количество фрагментированных пакетов в очереди

net.inet.ip.maxfragpackets=1024

#Минимальный порт для исходящих соединений

net.inet.ip.portrange.first=1024

#Максимальный порт для исходящих соединений

net.inet.ip.portrange.last=65535

#Не использовать случайные порты для исх. соединений

net.inet.ip.portrange.randomized=0

#Не реагируем на ICMP редирект

net.inet.ip.redirect=0

#Отключение маршрутизации от источника

net.inet.ip.sourceroute=0

net.inet.ip.accept_sourceroute=0

#Не отвечать на все пакеты полученные на закрытый порт

net.inet.tcp.blackhole=2

#Отбрасывать пакеты с флагами SYN+FIN

net.inet.tcp.drop_synfin=1

#FIN_WAIT_2 state fast recycle

net.inet.tcp.fast_finwait2_recycle=1

#FIN_WAIT_2 таймаут

net.inet.tcp.finwait2_timeout=3000

#Время хранение hostcache

net.inet.tcp.hostcache.expire=1200

#Timeout for establishing syn

net.inet.tcp.keepinit=5000

#Максимально количество TIME_WAIT сокетов

net.inet.tcp.maxtcptw=65536

#Количество времени пребывания соединения в состоянии TIME_WAIT

#(в миллисекундах деленных на 2, 2 x 30000 MSL = 60 секунд)

net.inet.tcp.msl=5000

#Отключить автоподстройку receive буфера

net.inet.tcp.recvbuf_auto=0

#Размер receive буфера

net.inet.tcp.recvspace=65536

#Отключить автоподстройку send буфера

net.inet.tcp.sendbuf_auto=0

#Размер send буфера

net.inet.tcp.sendspace=131072

#Возможность перехода в “TCP SYN cookies” при переполнении syncache

net.inet.tcp.syncookies=1

#Отключаем использование TSO для сетевых карт

net.inet.tcp.tso=0

#Отбрасываются все UDP пакеты, адресованные закрытым портам

net.inet.udp.blackhole=1

#Размер UDP receive буфера

net.inet.udp.recvspace=32768

#Обрабатывать исходящие пакеты непосредственно при попытке отправки

net.isr.direct=1

#размер исходящей очереди

net.route.netisr_maxqlen=1024

#При большом количестве файлов на сервере

vfs.ufs.dirhash_maxmem=100000000

Запуск приложений

Следующим этапом загрузки ОС является настройка сети и запуск необходимых приложений в файле /etc/rc.conf.

#Задаем имя сервера

hostname=”host.domain.com”

#Настраиваем сеть

ifconfig_em0=”inet 172.16.1.5 netmask 255.255.255.0″

ifconfig_em1=”inet 10.16.1.51 netmask 255.255.255.0″

defaultrouter=”172.16.1.1″

#Запуск SSHD при загрузки

sshd_enable=”YES”

#Запрещаем SSHD выполнять запросы к DNS

sshd_flags=”-u0″

#Отключаем использование USB

usbd_enable=”NO”

#Отключаем sendmail

sendmail_enable=NONE

#Запускаем ntpd при старте ОС

ntpd_enable=”YES”

### Отключаем NFS ###

inetd_enable=”NO”

portmap_enable=”NO”

nfs_client_enable=”NO”

nfs_reserved_port_only=”NO”

nfs_server_enable=”NO”

### Небольшая защита от DDOSа ###

tcp_drop_synfin=”YES”

icmp_drop_redirect=”YES”

icmp_log_redirect=”NO”

#Запускаем систему журналирования

syslogd_enable=”YES”

#Указываем syslog сохранять только локальные сообщений

#и не выполняет DNS запросов

syslogd_flags=”-s -n”

#Включить fsck при загрузке

fsck_y_enable=”YES”

#Выполнять во время загрузки ОС

background_fsck=”NO”

### Cохраненяем корки ядра ###

dumpdir=”/home”

dumpdev=”AUTO”

#Отключить SNMPD

snmpd_enable=”NO”

### Настройка фаервола ###

firewall_enable=”YES”

firewall_script=”/etc/rc.ipfw”

И напоследок добавим в файл /etc/rc.local скрипты которые нужно выполнить при загрузке.

#Привязывание очередей прерываний сетевых карт к процессорным ядрам

#по мотивам  статьи.

/usr/local/startup/cpuset-emigb.sh

Скрипты

Скрипт инициализации фаервола /etc/rc.ipfw:

#!/bin/sh

WAN=”em0″

LAN=”em1″

OPEN_PORT=”80,443″

IPFW=`which ipfw`

RET=$?

if [ ${RET} -ne 0 ]; then

echo “IPFW not found.”

exit ${RET}

fi

${IPFW} -f flush

${IPFW} -f table 1 flush

${IPFW} add 100 allow ip from any to any via lo0

${IPFW} add 110 deny ip from any to 127.0.0.0/8

${IPFW} add 120 deny ip from 127.0.0.0/8 to any

${IPFW} add 130 allow ip from any to any via ${LAN}

${IPFW} add 140 deny all from table\(1\) to me

${IPFW} add 150 deny all from any to any frag

${IPFW} add 160 allow carp from any to any via ${WAN}

${IPFW} add 180 allow tcp from any to any via ${WAN} established

${IPFW} add 200 check-state

${IPFW} add 210 allow tcp from me to any via ${WAN} setup keep-state

${IPFW} add 220 allow udp from me to any via ${WAN} keep-state

${IPFW} add 230 allow tcp from any to me dst-port ${OPEN_PORT} via ${WAN}

${IPFW} add 240 allow icmp from any to any icmptypes 0,8 via ${WAN}

${IPFW} add 65530 deny ip from any to any

exit 0

Скрипт привязывания прерываний очередей сетевых карт к процессорным ядрам/usr/local/startup/cpuset-emigb.sh:

#!/bin/sh

cpus=`sysctl -n kern.smp.cpus`

DRIVER=`pciconf -l | egrep ‘em|igb’ | sed -E ’s/^([emigb]+).*/\1/’ | head -n 1`

case “$DRIVER” in

em)

echo $DRIVER

i=1

vmstat -ai | egrep “em[0-9]:[a-z]x” | sed -E ’s/^irq([0-9]+): (em[0-9]):([a-z]+).*/\1 \2 \3/’ |

while read irq iface queue

do

cpu=$(( $i % $cpus ))

echo “Binding ${iface} queue ${queue} (irq ${irq}) -> CPU${cpu}”

cpuset -l $cpu -x $irq

i=$(( $i + 1 ))

done

;;

igb)

echo $DRIVER

vmstat -ai | sed -E ‘/^irq.*que/!d; s/^irq([0-9]+): igb([0-9]+):que ([0-9]+).*/\1 \2 \3/’ |

while read irq iface queue

do

cpu=$(( ($iface+$queue) % $cpus ))

echo “Binding igb${iface} queue ${queue} (irq ${irq}) -> CPU${cpu}”

cpuset -l $cpu -x $irq

done

;;

esac

Источник http://100.org.ua/%D0%BE%D0%BF%D1%82%D0%B8%D0%BC%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F-freebsd-%D0%BF%D0%BE%D0%B4-%D0%B2%D1%8B%D1%81%D0%BE%D0%BA%D0%B8%D0%B5-%D0%BD%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B8/
Запись опубликована в рубрике *Unix,*Linux, *Сети, FreeBSD. Добавьте в закладки постоянную ссылку.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Я не спамер This plugin created by Alexei91