FreeBSD оптимизация сервера. Высокая сетевая и файловая нагрузка


Автор Охальников Олег

Часто в сети возникают темы "Отваливается сеть" или "Сеть зависает" и так далее. Отдельные энтузиасты находят решение в виде скриптов реагирующих на событие отсутствие ping и перезапускают сетевую подсистему :). В данной статье расскажу как оптимизировать FreeBSD сервер для работы с высокими нагрузками, например 200 и более одновременных сетевых подключений, при которых данные непрерывно льются, частным (тестовым) примером может послужить transmission-daemon, с десяток закачек - раздач которого создадут в системе огромное количество активных подключений (у меня порядка 230 на момент написания статьи).
Изначально FreeBSD настроена с усредненными значениями, которые в тех или иных ситуациях легко изменить с помощью sysctl. FreeBSD хранит сетевые данные в mbuf clusters, вывод текущего состояния можно легко посмотреть с помощью команды netstat -m:

# netstat -m
...
18050/4062/22112/25600 mbuf clusters in use (current/cache/total/max)
...
Не вдаваясь в особые подробности, максимальное значение буфера 25600, текущее 18050, чем больше сетевая активность, тем больше первая цифра, когда она превысит 25600 - сетевой интерфейс впадет в состояние zonelimit и перестанет отвечать на запросы по сети.


Меняем значение mbuf clusters на максимальное

sysctl -w kern.ipc.nmbclusters=65536
(Пока мне не удалось превысить данное значение.) Смотрим

# netstat -m
...
18050/4062/22112/65536 mbuf clusters in use (current/cache/total/max)
Значение сохранится до перезагрузки, добавляем kern.ipc.nmbclusters=65536 в файл /etc/sysctl.conf, ниже привожу содержание своего файла написанного для оптимизации дисковой и сетевой подсистем. Делайте все с осторожностью и с пониманием дела. Еще отмечу, что увеличения значений mbuf clusters включения кэширования и т.д. занимают бОльший объём памяти, для современных ПК это не проблема, но для старых... в общем проконтролируйте данный показатель после изменений:

vfs.vmiodirenable=1
kern.ipc.somaxconn=8192
kern.maxfiles=65536
kern.maxfilesperproc=32768
net.inet.tcp.rfc1323=1
net.inet.tcp.delayed_ack=0
kern.ipc.maxsockbuf=2097152
kern.ipc.maxsockets=204800
net.inet.tcp.sendspace=16384
net.inet.tcp.recvspace=65535
net.inet.udp.maxdgram=57344
net.local.stream.recvspace=65535
net.local.stream.sendspace=65535
kern.ipc.nmbclusters=65536
net.inet.ip.portrange.first=1024
net.inet.ip.portrange.last=65535
net.inet.ip.portrange.randomized=0
net.inet.tcp.nolocaltimewait=1
vfs.vmiodirenable - Значением переменной vfs.vmiodirenable может быть установлено в 0 (выключено) или 1 (включено); по умолчанию 1. Эта переменная отвечает за метод кэширования каталогов. Размер большинства каталогов невелик. Они могут поместиться в одном фрагменте (обычно 1K), и могут занимать ещё меньше места (обычно 512 байт) в кэше буфера. При отключении этой переменной (при установке значения 0) буфер прокэширует только заданное число каталогов даже если у вас много памяти. При включении (при установке значения 1) эта переменная sysctl позволит использовать страничное кэширование VM, делая доступным для кэширования каталогов весь объём памяти. Однако, минимальный объём памяти, используемой для кэширования каталогов стал равен объёму страницы (обычно 4 K) вместо 512 байт. Мы рекомендуем оставлять эту опцию включенной, если ваш компьютер исполняет программы, манипулирующие значительным количеством файлов. Примером таких программ могут быть кэширующие прокси-серверы, большие почтовые серверы и серверы новостей. Обычно включение этой опции не понижает производительности, однако лучше поэкспериментировать, чтобы узнать оптимальное значение для вашей машины.

kern.ipc.somaxconn - После того как соединение принято оно попадает в "listen socket queue". Собственно устанавливаем размер очереди kern.ipc.somaxconn=8192.

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

net.inet.tcp.rfc1323 (rfc3042 и rfc3390) - Переключатели времени исполнения. Включают различные функции TCP , описанные в RFC и достаточно безопасные. Если эти функции включены (1), некоторыедругие очень - очень старые системы не смогут установить соединение, либо соединение окажется очень медленным.

net.inet.tcp.delayed_ack - Производительность samba и squid можно увеличить, изменив значение переменной net.inet.tcp.delayed_ack на 0 и запретив таким образом отправку ответных ACK-сообщений вместе с данными. В случае интерактивных протоколов, таких как POP, IMAP, SMTP, SSH и FTP, это изменение приведет к заполнению сети лишними пакетами, содержащими лишь ACK-сообщения, и снижению производительности.

kern.ipc.maxsockbuf - максимальный размер TCP буфера.

kern.ipc.maxsockets - Увеличить максимальное число открытых сокетов во время работы.

net.inet.tcp.sendspace - send buffers Буферы для отправки данных. По умолчанию 32K. Если скачиваются данные небольшого объема или недостаток mbuf кластеров можно уменьшить до 16k.

net.inet.tcp.recvspace - receive buffers Буферы для приема данных. По умолчанию 64Kб, если нет загрузки больших объемов данных, то можно уменьшить до 8Кб (меньше вероятность переполнения при DoS атаке).

net.inet.udp.maxdgram - Maximum outgoing UDP datagram size

net.local.stream.recvspace - не помню точно, но что то для оптимизации SAMBA. Впрочем, легко получить описание параметра прямо в консоли:
$ sysctl -d net.local.stream.recvspace
net.local.stream.recvspace: Default stream receive space.

net.local.stream.sendspace - не помню точно, но что то для оптимизации SAMBA.
$ sysctl -d net.local.stream.sendspace
net.local.stream.sendspace: Default stream send space.

kern.ipc.nmbclusters - Увеличение числа mbuf кластеров во FreeBSD последних версий можно произвести в любой момент через данный параметр.

TCP/IP ports По умолчанию исходящие соединения инициируются с диапазона портов 49152-65535 (16 тыс.). Их можно увеличить (1024-65535):
net.inet.ip.portrange.first=1024
net.inet.ip.portrange.last=65535

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

Включаем возможность не создания состояния TIME_WAIT для соединений в рамках localhost: net.inet.tcp.nolocaltimewait=1

После изменений в /etc/sysctl.conf:

# /etc/rc.d/sysctl restart
или перезагрузка.


В начале статьи я упоминал о том, что увеличение значений буферов приведет к увеличению потребления оперативной памяти. Привожу текущие значения после нескольких дней работы с вышеуказанными настройками:
Кол-во активных подключений - 188
Используется памяти на всё - 260 Мб из 1Гб.

Для просмотра значений всех переменных sysctl в системе, введите команду:

$ sysctl -a |less
Тема достаточно обширная, приведенная конфигурация лишь плод собственных экспериментов и не претендует на что то рекомендуемое. Просто читайте, оптимизируйте систему под требуемые задачи. Вот несколько ссылок очень полезных по этой теме: Sysctl , на OpenNet , пример конфигов . Так же рекомендую к прочтению $ man tuning

http://unixa.ru

Обновлено: 12.03.2015