четверг, 2 декабря 2010 г.

Тюнинг FreeBSD 7-8 (sysctl, loader.conf)

Здесь я приведу некоторые опции по тюнингу FreeBSD и описание к ним.
Предупреждение: Бездумное копирование опций не всегда приводит к приросту производительности!!!

/etc/sysctl.conf

######   Формат записей " параметр=значение # значение по умолчанию "
NETWORK
Запрет ответа при обращении на закрытые порты. 
По стандарту, если на закрытый порт сервера приходит SYN-пакет, машина должна ответить RST-пакетом.
Это упрощает сканирование портов, а также дает достаточное количество информации (в виде ответов от сканируемого сервера) для определения версии ОС.
"Черные дыры" заставляют FreeBSD быть предельно лаконичной, не отсылая ничего в ответ на запросы к закрытым портам.

net.inet.tcp.blackhole=2 # 0
net.inet.udp.blackhole=1 # 0
Увеличение размера очереди.
Защита очереди от SYN атак

kern.ipc.somaxconn=4096 # 128
Чтобы сервер не стал жертвой DoS-атаки, можно включить механизм syncookies, который служит для защиты сервера от SYN-флуда. 
Когда новое соединение не помещается в переполненный syncache, FreeBSD переходит в режим "syncookies" (TCP SYN cookies).

При серьезной атаке может не менее серьезно выручить.

net.inet.tcp.syncookies=1 # 1
Запрет ответа на широковещательный ECHO
Современная система не должна отвечать на широковещательные пинги, но и по сей день существуют сети, которые могут стать источником DoS-атаки.
Чтобы не попасть в их список, выставляем:

net.inet.icmp.bmcastecho=0 # 0
Дропать все пакеты с флагами SYN+FIN.
Если не нужна поддержка смешного протокола T/TCP (TCP for Transactions), то пакеты с флагами SYN+FIN можно смело отбрасывать как неликвидные :).
Протокол редко где используется, а потому это имеет смысл

net.inet.tcp.drop_synfin=1 
Запрет ридеректов

net.inet.icmp.drop_redirect=1 # 1
net.inet.icmp.log_redirect=1 # 1
net.inet.ip.redirect=0 # 1
#net.inet6.ip6.redirect=0 #ipv6 disable in kernel
Очистка таблицы ARP через .... секунд

net.link.ether.inet.max_age=1200 # 1200
Запрет на "прощупывание" внутренней сети

net.inet.ip.sourceroute=0 # 0
net.inet.ip.accept_sourceroute=0 # 0
Запрет запроса маски адреса, 
запрет широковещательного запроса временного штампа (timestamp)

net.inet.icmp.maskrepl=0 # 0
Максимальное количество пакетов ICMP <<Недостижимо>> (icmp type 3), а также количество отсылок TCP RST пакетов в секунду.

net.inet.icmp.icmplim=100 # 200

Увеличение размера TCP-буферов, для оптимизации при большом потоке данных HTTP FTP.
Но стоит помнить, что слишком объемные буферы быстро приведут к исчерпанию памяти при большом количестве подключений. Для веб-сервера, который принимает много коротких запросов и отправляет большие объемы данных, размер выходного буфера рекомендуется увеличить в ущерб входного.

net.inet.tcp.sendspace=32768 # 32768
net.inet.tcp.recvspace=65536 # 65536
Выставляет maximum segment lifetime.
Определяет максимальное время жизни сегмента (Maximum Segment Life - MSL)
После того как соединение закрывается сокет переходит в состояние TIME_WAIT
Это максимальное количество времени ожидания ACK в ответ на SYN-ACK или FIN-ACK в миллисекундах
В этом состоянии он может находится по умолчанию в течение 60 секунд.
Время можно изменить через sysctl (в миллисекундах деленных на 2, 2 x 30000 MSL = 60 секунд)

net.inet.tcp.msl=7500 # 30000
Во FreeBSD 6.2 TIME_WAIT сокеты обрабатываются отдельно (нужна лишь
часть информации 48 байт из 1 Кб. Ограничение вне лимита kern.ipc.maxsockets)

net.inet.tcp.maxtcptw=40960 # 40960
По умолчанию исходящие соединения инициируются с диапазона портов 49152-65535 (16 тыс.). Во FreeBSD 8.1 - порты 10000 - 65535
Их неплохо увеличить (1024-65535):

net.inet.ip.portrange.first=1024 # 10000
net.inet.ip.portrange.last=65535
Не менять ttl при транзите пакетов

net.inet.ip.stealth=0 # 0
Включение пуллинга
kern.polling.enable=0 # 0
Pooling

kern.polling.each_burst=5 # 5
kern.polling.burst_max=1000 # 150
Установка значения ttl под Windows

net.inet.ip.ttl=128 # 64
Максимальаня длина приёмной очереди, при переполнении которой стек дропает входящие пакеты

net.inet.ip.intr_queue_maxlen=4096 # 50
Увеличить максимальное число открытых сокетов

sysctl kern.ipc.maxsockets=204800 # 25600
Если машина обрабатывает несколько десятков тысяч соединений, то tcb hash позволяет быстро
определять принадлежность пришедшего пакета к определенному соединению.

net.inet.tcp.tcbhashsize=4096 # 4096
Для использования портов по порядку, вместо случайной выборки (для исключения ошибки повторного коннекта с одного порта до отработки TIME_WAIT):

net.inet.ip.portrange.randomized=0 # 1
Во FreeBSD 6.2 появилась возможность не создавать состояние TIME_WAIT для соединений в рамках localhost:

net.inet.tcp.nolocaltimewait=1 # 0
DummyNET - шейпинг на IPFW
net.inet.ip.dummynet.io_fast - если трафик помещается в заданную полосу, не пропускать его через очередь и отдельный поток. Если нет необходимости эмулировать задержки и потери в канале - очень сильно сохраняет ресурсы. При использовании этой опции практически отпадает необходимость в распараллеливании dummynet
net.inet.ip.dummynet.io_fast=1
 

net.inet.ip.intr_queue_maxlen, net.route.netisr_maxqlen - фактически - размеры входящей и исходящей очередей. При большой нагрузке в режиме маршрутизации есть смысл увеличивать эти значения. Непоместившийся пакет выбрасывается. Это условно спасет при кратковременных перегрузках (часть пакетов пролетит с большой задержкой), но совершенно не спасет при хроничеких.

net.isr.direct - обрабатывать исходящие пакеты непосредственно при попытке отправки (в т.ч. прохождение ipfw на выходе). Т.е. не откладывать в очередь, которую в отдельном потоке разгребает netisr. Есть смысл включать, если количество ядер меньше или равно количеству сетевых карточек. Влияет на скорость ОТПРАВКИ пакетов. Для серверов это хорошо, для роутеров - не очень. Если нагрузка на сетевые карты неравномерная, или когда есть хотя бы одно хронически недогруженое ядро - выключать. При включеном net.inet.ip.fastforwarding будет еще 1 спецэффект.

net.isr.direct_arp - обрабатывать исходящие ARP пакеты непосредственно при попытке отправки. Есть смысл держать включенным в большинстве случаев (разумного варианта, когда стоит отправлять такие запросы в очередь я придумать не могу). Добавлено для того, чтобы обработкой ARP система могла заниматься с бОльшим приоритетом даже при net.isr.direct=0

net.isr.maxthreads - собственно, количество потоков, разгребающих очередь пакетов. Есть смысл ставить меньшим количества ядер в системе. Нужно прикинуть, сколько ресурсов съедается на обработке прерываний от сетевух и не только, сколько в пике потребляет прочий софт (БД, httpd, прочие демоны) и на оставшееся распределить роутинг. Если, к примеру, сетевухи потребляют по 80% с 2х ядер и софт еще до 100% одного ядра, а всего ядер 4, то остается 140% гарантированного времени. Т.е. полтора ядра ;) Тут можно смело ставить роутинг в 2 потока. Если нагрузки по софту кратковременные, а на роутинг с трудом хватает - можно даже попробовать 3.

net.inet.ip.fastforwarding - обрабатывать входящие пакеты непосредственно в момент приема (в т.ч. прохождение ipfw на входе, до попадания в очередь netisr). Есть смысл включать, если количество ядер меньше или равно количеству сетевых карточек, так же как и net.isr.direct. Влияет на скорость ПРИЕМА пакетов. Обработка пакета происходит прямо в обработчике прерывания. Следует учесть, что не все сетевухи и не все драйвера нормально умеют складировать новые пакеты в очередь, пока обрабатывается текущий. При включеном net.inet.ip.fastforwarding будет еще 1 спецэффект - маршрутизация пакета и прохождение ipfw (оба раза) будут происходить в том же обработчике прерывания. Фактически, на время обработки входящего пакета сетевая карта будет заблокирована. Это неплохо смотрится при преобладающем входящем трафике и на однопроцессорных машинах.

Файловая система
Запрет возможности монтирования файловых систем непривилегированными пользователями.

vfs.usermount=0 # 0


Ресурсы системы  
Увеличение числа mbuf кластеров
Можно увеличить до 262144
(в loader.conf - vm.kmem_size=1G, в ядре options KVA_PAGES=512)

kern.ipc.nmbclusters=65536 # 25600

Приложения работают не с сокетами, а с файлами. По этому для каждого
сокета нужна структура, которая описывает файл.
kern.maxfiles - всего файлов в системе
kern.maxfilesperproc - максимальное число файлов на один процесс.

kern.maxfiles=204800
kern.maxfilesperproc=200000

Можно динамически изменить параметры shared memory

sysctl -a | grep shm
Вычисляется следующим образом:

SHMMAX = SHMALL * PAGE_SIZE + 1
Где PAGE_SIZE равно 4096 Б для i386

SHMALL = k * RAM * 1024 / PAGE_SIZE
Где RAM – физическая оперативная память в МБ; k – коэффициент, равный 0.5; PAGE_SIZE – размер одной страницы в КБ, PAGE_SIZE = 4 КБ для i386.
Например, для машины с памятью 512 МБ,

SHMALL = 0.5 * 512 * 1024 / 4 = 65536.
В случае, если предполагается, что приложение будет работать на специально выделенном для этого сервере, и кроме него никаких других серьезных сервисов запущено не будет, то коэффициент k, можно увеличивать до 0.75, это 3/4 от физической оперативной памяти. Рекомендую также посмотреть утилиту  ipcs.
Например для сервера PostgreSQL можно выставить следующие значения:

kern.ipc.shmall=65536
kern.ipc.shmmax=536870912
kern.ipc.semmap=256
/boot/loader.conf Увеличить лимита физической памяти, которую может использовать ядро (по умолчанию 320Мб). Увеличим до 1Гб:

vm.kmem_size=1G
для amd64 оказалось недостаточно указать vm.kmem_size_max=1G в /boot/loader.conf, (параметр был просто игнорирован) по-этому это надо сделать в файле конфигурации ядра:

options VM_KMEM_SIZE=1073741824
options VM_KMEM_SIZE_MAX=1073741824
В /boot/loader.conf для обеих платформ нужно добавить vm.kmem_size_max=1G Увеличение syncache и syncookies( на этапе загрузки).

net.inet.tcp.syncache.hashsize=1024
net.inet.tcp.syncache.bucketlimit=100
Задаем какой буфер использовать для сетевых карточек (должен быть реально)

## Для карточек Intel с драйвером em
hw.em.rxd=4096
hw.em.txd=4096
## Для новых карточек Intel с драйвером igb
hw.igb.rxd=4096
hw.igb.txd=4096
Увеличение количества семафоров

kern.ipc.semmnu=256
kern.ipc.semmns=32000
kern.ipc.shmmni=4096
Опции ядра Увеличение адресного пространства ядра, которое на i386 платформе - 1Гб. Для увеличения до 2Гб. На платформе amd64 KVA всегда 2G.

options KVA_PAGES=512
Данная опция в FreeBSD 8.x предназначена для ускорения маршрутизации. При больших потоках трафика проц вгоняется в полку, поэтому настоятельно рекомендую вырубать ее нафиг, чтоб не наблюдать , как ваш роутер уходит в нирвану...

#options                FLOWTABLE               # per-cpu routing cache
   Опции ядра можно посмотреть дополнительно здесь Данная заметка будет еще пополняться...  Ссылки: Сервер на стероидах: FreeBSD, nginx, MySQL, PostgreSQL, PHP и многое другое   Update 07.05.2011

3 комментария:

  1. net.inet.tcp.tcbhashsize исправь на 4096
    в оригинале так написано...

    ОтветитьУдалить
  2. kern.ipc.shmmni какой делать в итогде !? как глянуть сколько занято семафоров

    ОтветитьУдалить