Документация по ОС FreeBSD
Воскресенье, 16.11.2025, 01:32
Главная
Регистрация
Вход
Приветствую Вас
Гость
|
RSS
Меню сайта
Главная страница
Новости в мире Unix
NEW
Каталог файлов
NEW
Установка и настройка
Ports & Packages
cvs
Безопасность
Работа с железом
X Window
Multimedia
Man pages
Net
Apache
DNS
FTP
Mail
Samba
Squid
SSH
VPN
РРР
Shell
IPFW
Tips'n'tricks
RFC
Книги по FreeBSD
Темы экзамена BSDA
Гостевая книга
Форум на bsdportal.ru
Каталог сайтов
Самый свежий софт
Каталог ссылок
Категории каталога
Apache
[58]
DNS
[25]
FTP
[27]
Mail
[74]
Samba
[24]
Squid
[46]
SSH
[23]
VPN
[35]
РРР
[20]
Net
[173]
Главная
»
Статьи
»
Сеть
»
Net
FreeBSD для обслуживания 100-200 тысяч соединений [2007]
mbuf clusters
FreeBSD хранит сетевые данные в mbuf clusters, размер каждого 2Кб, но из них используется только около 1500 байт (по размеру Ethernet пакета).
mbufs
Для каждого mbuf кластера нужен "mbuf", который имеет размер 256 байт и нужен для организации связи цепочек из mbuf кластеров. В mbuf можно поместить полезную информацию в районе 100 байт, но это не всегда используется.
Если в машине 1Гб и больше памяти, то по умолчанию будет создано 25 тыс. mbuf кластеров, что не всегда достаточно.
При ситуации исчерпания числа свободных mbuf кластеров FreeBSD попадает в состояние zonelimit и перестает отвечать на запросы по сети, в top это выглядит как "zoneli". Единственная возможность как-то повлиять на ситуацию - это зайти с локальной консоли и перезагрузить систему, уничтожить процесс находящийся в состоянии "zoneli" невозможно. Для Linux 2.6.x данная проблема тоже характерна, причем работать переставала даже консоль.
PID USERNAME THR PRI NICE SIZE RES STATE TIME WCPU COMMAND
13654 nobody 1 4 0 59912K 59484K zoneli 209:26 0.00% nginx
Для выхода из этой ситуации существует патч возвращающий приложению ошибку ENOBUFS, сигнализирующий о попадании в состояние "zoneli", после чего программа может закрыть лишние соединения. К сожалению патч пока не принят в состав FreeBSD.
Состояние задействованных mbuf кластеров можно посмотреть командой:
>netstat -m
4/1421/1425 mbufs in use (current/cache/total)
0/614/614/25600 mbuf clusters in use (current/cache/total/max)
Увеличение числа mbuf кластеров во FreeBSD 6.2 можно произвести в любой момент через параметр kern.ipc.nmbclusters:
sysctl kern.ipc.nmbclusters=65536
Для более ранних версий FreeBSD число mbuf кластеров можно было установить только на этапе загрузки:
/boot/loader.conf:
kern.ipc.nmbclusters=65536
25000 mbuf clusters = 55M
32768 mbuf clusters = 74M
65536 mbuf clusters = 144M
25000 mbuf кластеров занимают примерно 50Мб памяти, 32000 - 74 Мб, 65000 - 144Мб (рост по степени 2). 65000 - пограничное значение, превышать которое не рекомендуется, без предварительного расширения адресного пространства доступного ядру.
Увеличение памяти, доступной ядру
Увеличение адресного пространства ядра, которое на i386 платформе - 1Гб.
Для увеличения до 2Гб, в файле конфигурации ядра необходимо указать:
options KVA_PAGES=512
На платформе amd64 KVA всегда 2G, увеличить к сожалению в настоящее время нельзя.
Кроме увеличения виртуального адресного пространства можно увеличить лимит физической памяти, которую может использовать ядро (по умолчанию 320Мб). Увеличим до 1Гб:
/boot/loader.conf:
vm.kmem_size=1G
Затем выделим из него 575Мб под mbuf кластера:
sysctl -w kern.ipc.nmbclusters=262144
Установление соединения. syncache и syncookies
Примерно 1000 байт расходуется на одно соединение.
Примерно 100 байт для одной записи на незаконченное соединение в syncache.
Всего можно держать в памяти информацию об около 15000 соединениях.
Параметры syncache можно посмотреть через "sysctl net.inet.tcp.syncache" (доступен в режиме только для чтения):
# sysctl net.inet.tcp.syncache
net.inet.tcp.syncache.bucketlimit: 30
net.inet.tcp.syncache.cachelimit: 15359
net.inet.tcp.syncache.count: 29
net.inet.tcp.syncache.hashsize: 512
net.inet.tcp.syncache.rexmtlimit: 3
Изменить параметры syncache можно только на этапе загрузки ядра:
/boot/loader.conf:
net.inet.tcp.syncache.hashsize=1024
net.inet.tcp.syncache.bucketlimit=100
Когда новое соединение не помещается в переполненный syncache, FreeBSD переходит в режим "syncookies" (TCP SYN cookies). Включается возможность такого перехода через:
sysctl net.inet.tcp.syncookies=1
Заполненность syncache и статистику по syncookies можно посмотреть через команду:
netstat -s -p tcp
...
2079088720 syncache entries added
...
> 0 dropped
2058506523 completed
> 0 bucket overflow
> 0 cache overflow
...
0 cookies sent
0 cookies received
После того как соединение принято оно попадает в "listen socket queue".
Статистику можно посмотреть командой
netstat -Lan
Current listen queue sizes (qlen/incqlen/maxqlen)
Proto Listen Local Address
tcp4 43/0/4096 *.80
tcp4 0/0/128 *.22
4096 - размер очереди (максимум 65тыс.)
43 - заполненность очереди в данный момент (приложение не вытащило из очереди).
Увеличение размера очереди производится через:
sysctl kern.ipc.somaxconn=4096
После того как соединение принято для него FreeBSD создает структуры связанные с сокетами (sockets).
Увеличить максимальное число открытых сокетов во FreeBSD 6.2, во время работы, можно через:
sysctl kern.ipc.maxsockets=204800
В более ранних версиях:
/boot/loader.conf:
kern.ipc.maxsockets=204800
Посмотреть состояние можно командой:
>vmstat -z
ITEM SIZE LIMIT USED FREE REQUESTS FAILURES
...
socket: 356, 204809, 48041, 114869, 4292783585, 0
...
inpcb: 180, 204820, 63956, 121460, 4283258030, 0
tcpcb: 464, 204800, 48015, 114897, 4283258030, 0
tcb hash
Если машина обрабатывает несколько десятков тысяч соединений то tcb hash позволяет быстро определять принадлежность пришедшего пакета к определенному соединению.
По умолчанию размер tcb hash - 512 элементов.
Текущий размер можно посмотреть через sysctl (только для чтения):
sysctl net.inet.tcp.tcbhashsize
Изменить можно на этапе загрузки:
/boot/loader.conf:
net.inet.tcp.tcbhashsize=4096
Файлы
Приложения работают не с сокетами, а с файлами. По этому для каждого сокета нужна структура, которая описывает файл. Увеличить можно через:
sysctl kern.maxfiles=204800
sysctl kern.maxfilesperproc=200000
kern.maxfiles - всего файлов в системе
kern.maxfilesperproc - максимальное число файлов на один процесс.
Параметры можно менять на работающей системе, но они не отразятся на уже запущенных процессах. Поэтому в nginx были добавлены директивы позволяющие менять число открытых файлов для уже запущенных процессов (после инициирования операции переконфигурации)
nginx.conf:
worker_rlimit_nofile 200000;
events {
worker_connections 200000;
}
receive buffers
Буферы для приема данных. По умолчанию 64Kб, если нет загрузки больших объемов данных, то можно уменьшить до 8Кб (меньше вероятность переполнения при DoS атаке).
sysctl net.inet.tcp.recvspace=8192
Для nginx:
nginx.conf:
listen 80 default rcvbuf=8k;
send buffers
Буферы для отправки данных. По умолчанию 32K. Если скачиваются данные небольшого объема или недостаток mbuf кластеров, можно уменьшить:
sysctl net.inet.tcp.sendspace=16384
Для nginx:
nginx.conf:
listen 80 default sndbuf=16k;
В ситуации когда сервер записал в сокет данные, но клиент не хочет их забирать, после таймаута по закрытию соединения в ядре данные будут держаться еще несколько минут. В nginx если директива для принудительного сброса всех данных после закрытия по таймауту.
nginx.conf:
reset_timedout_connections on;
sendfile
Еще один механизм для экономии mbuf кластеров - это sendfile, он использует память буферов ядра с данными файлов одновременно для передачи этих данных в сетевую карту, без промежуточного заполнения лишних буферов.
В nginx включается:
nginx.conf:
sendfile on;
На i386 по умолчанию для систем с 1 или более Гб памяти будет выделено 6656 sendfile буферов. Этого вполне достаточно. На платформе amd64 более оптимальный вариант реализации и sfbufs буферы не нужны.
Статистика:
i386>netstat -m
...
190/510/6656 sfbufs in use (current/peak/max)
amd64>netstat -m
...
0/0/0 sfbufs in use (current/peak/max)
При переполнении sendfile буфера процесс замирает в состоянии "sfbufa", но ситуация достаточно быстро приходит в норму после увеличения размера буфера.
PID USERNAME THR PRI NICE SIZE RES STATE TIME WCPU COMMAND
13654 nobody 1 4 0 59912K 59484K sfbufa 209:26 5.00% nginx
Увеличение размера через:
/boot/loader.conf:
kern.ipc.nsfbufs=10240
TIME_WAIT
После того как соединение закрывается сокет переходит в состояние TIME_WAIT
В этом состоянии он может находится по умолчанию в течение 60 секунд.
Время можно изменить через sysctl (в миллисекундах деленных на 2, 2 x 30000 MSL = 60 секунд):
sysctl net.inet.tcp.msl=30000
Во FreeBSD 6.2 TIME_WAIT сокеты обрабатываются отдельно (нужна лишь часть информации 48 байт из 1 Кб. Ограничение вне лимита kern.ipc.maxsockets), число их регулируется параметром:
sysctl net.inet.tcp.maxtcptw=40960
Статистика:
>vmstat -z
ITEM SIZE LIMIT USED FREE REQUESTS FAILURES
...
tcptw: 48, 41028, 15941, 25087, 1045159949, 438573
TCP/IP ports
По умолчанию исходящие соединения инициируются с диапазона портов 49152-65535 (16 тыс.).
Их неплохо увеличить (1024-65535):
sysctl net.inet.ip.portrange.first=1024
sysctl net.inet.ip.portrange.last=65535
Для использования портов по порядку, вместо случайной выборки (для исключения ошибки повторного коннекта с одного порта до отработки TIME_WAIT):
sysctl net.inet.ip.portrange.randomized=0
Во FreeBSD 6.2 появилась возможность не создания состояния TIME_WAIT для соединений в рамках localhost:
sysctl net.inet.tcp.nolocaltimewait=1
Источник:
http://www.opennet.ru/base/net/tune_freebsd.txt.html
Категория:
Net
| Добавил:
oleg
(07.02.2008) | Автор:
Сысоев Игорь Владимирович
Просмотров:
1271
| Рейтинг:
4.0
/
1
|
- Оценить -
Отлично
Хорошо
Неплохо
Плохо
Ужасно
Всего комментариев:
0
Добавлять комментарии могут только зарегистрированные пользователи.
[
Регистрация
|
Вход
]
Форма входа
Друзья сайта
Google+
Copyright MyCorp © 2025