dadv: (chuck)
Choose your future ([personal profile] dadv) wrote2009-05-31 03:39 pm

Тюнинг FreeBSD 7

Видеозапись лекции Игоря Сысоева по настройке некоторых подсистем FreeBSD 7 (44 минуты 30 секунд).

(Update: см. также http://www.opennet.ru/base/net/tune_freebsd.txt.html)

Квинтэссенция:

  • открытый TCP-сокет суммарно потребляет порядка 1800 байт в ядре и, выставляя sysctl kern.ipc.maxsockets=100000, мы позволяем ядру занять более 170Mb только под хранение информации об открытых сокетах;

    количество открытых в данный момент сокетов можно посмотреть в sysctl kern.ipc.numopensockets;

  • поиск сокета по входящему пакету хешированный с размером хеш-таблицы, изменяемой через /boot/loader.conf параметром net.inet.tcp.tcbhashsize; по умолчанию 512 записей, можно увеличить до 32K для ускорения поиска;
  • очередь установленных TCP-коннектов, ещё не принятых (accept) приложением, имеет размер sysctl kern.ipc.somaxconn (128 по умолчанию); netstat -Lan показывает список этих очередей, включая степень их заполненности;
  • принятый TCP-коннект порождает дескриптор открытого файла, который потребляет 128 байт (итого более 190Mb на 100000 коннектов с учетом 170Mb на сокеты);

    общее количество открытых файлов в системе ограничивает sysctl kern.maxfiles, а текущее показывает sysctl kern.openfiles;

    плюс имеется ограничение на количество открытых файлов на процесс sysctl kern.maxfilesperproc;

    плюс могут быть ещё ограничения в самом приложении (а также внутренний расход памяти приложения на каждый файл);

  • данные, приходящие из сети в сокет, попадают в ядерные буфера mbuf (256 байт) и mbuf cluster (2Kb) (связный набор буферов mbuf, в сумме хранящий все данные пакета);

    выставляя sysctl kern.ipc.nmbclusters=100000, разрешаем ядру использовать под эти буфера дополнительно более 207Mb (2048+256 байт на каждый кластер и прилагающийся с нему дополнительный служебный mbuf);

  • в один сокет может прийти до sysctl net.inet.tcp.recvspace данных, не принятых ещё приложением - они потребляют упомянутые выше буфера;

    в FreeBSD 7 есть (отключаемый) механизм автоувеличения этого параметра (sysctl net.inet.tcp.recvbuf_auto, описание см. ниже на примере net.inet.tcp.sendbuf_auto);

  • начиная с FreeBSD 7 отправляемые приложением в сеть данные потребляют mbuf и mbuf clusters размером по странице (4K для i386) и не используют двухкилобайтные nmbclusters (см. выше);

    количество четырехкилобайтных кластеров, используемых для отправки, ограничивается через sysctl kern.ipc.nmbjumbop, по умолчанию 12800; на 100000 их потребуется более 488Mb ядерной памяти (128+4096 байт на каждый);

  • исходящие данные одного сокета могут занять в ядерной памяти до sysctl net.inet.tcp.sendspace байт и при медленно принимающих клиентах и неправильных настройках этого параметра и kern.ipc.nmbjumbop буфера на отправку могут исчерпаться (медленные клиенты могут устроить DoS), причем в FreeBSD 7 по умолчанию включено автоувеличение этого буфера для быстрых клиентов (sysctl net.inet.tcp.sendbuf_auto=1), но до обрыва соединения невозможно освободить выросший буфер, если быстрый клиент вдруг прекратит приём;

    автоинкремент идет порциями по net.inet.tcp.sendbuf_inc, максимальный размер буфера задаёт net.inet.tcp.sendbuf_max;

  • закрытое сервером соединение ожидает подтверждения закрытия от клиента, потребляя меньше памяти, чем открытое;

    таких соединений может быть до sysctl net.inet.tcp.maxtcptw (часть от kern.ipc.maxsockets, поэтому такие сокеты мешают открытию новых);

    однако, если приложение не предпринимает специальных мер (ограничение linger-таймаута), то после закрытия сокета довольно длительное время буфера могут оставаться занятыми данными, для которых не было получено подтверждения приёма от клиента;

  • начиная с версии 7.2/amd64 размер ядерной памяти по умолчанию равен четверти физической памяти, но не более 3.6Gb (ранее предел был чуть более 1.5Gb);

    этот размер можно увеличить до двух размеров физической памяти в /boot/loader.conf параметром vm.kmem_size, например: vm.kmem_size=3G

  • максимальный размер файлового кеша ограничивается лимитом на количество кешируемых файлов sysctl kern.maxvnodes (не более 100000 по умолчанию) и при большом объеме памяти и недостаточном значении kern.maxvnodes память может не использоваться эффективно под кеш, если файлы мелкие и их очень много;
  • пакеты, приходящие через драйвер сетевой карты, могут обрабатываться сразу при sysctl net.isr.direct=1, либо сначала укладываться в очередь при нулевом значении этого параметра;

    размер очереди задаётся через sysctl net.inet.ip.intr_queue_maxlen (можно поставить и 2048, и 4096); при использовании очереди и её переполнении пакет выкидывается;

  • top -S показывает потребление процессора системными тредами и при net.isr.direct=0 можно увидеть отдельно процент процессорного времени, затрачиваемый на обработку пакетов сетевым стеком уже без участия драйвера сетевой карты - при включенной очереди вся обработка выполняется одним тредом и не распараллеливается; (информация устарела - начиная с 8.0-RELEASE, обработка очереди по умолчанию распараллеливается на все ядра системы и степенью параллелизма можно управлять через loader.conf)

    распараллеливание можно получить, отключив очередь и принимая трафик несколькими сетевыми картами; (информация устарела - см. выше)

    файрволы (пакетные фильтры) мешают параллельной обработке пакетов своими блокировками на этапе проверки правил;

  • установка sysctl kern.ipc.shm_use_phys=1 при использовании приложений, активно потребляющих SYSV Shared Memory (СУБД), экономит ядерную память и запрещает вытеснение такой разделяемой памяти в своп;
  • использование версии 7.2 позволяет использовать сегменты разделяемой памяти SYSV размером более 2Gb и автоматически (прозрачно для приложений) использовать 4-мегабайтные страницы вместо 4-килобайтных, уменьшая размер системных таблиц и количество промахов процессорного кеша, увеличивая таким образом общее быстродействие системы.

рулес (-)

[identity profile] petr999.livejournal.com 2009-05-31 12:08 pm (UTC)(link)
-

[identity profile] logger.livejournal.com 2009-05-31 12:26 pm (UTC)(link)
Хотя многое уже известно, но все равно хороший FAQ.

[identity profile] l2tp.livejournal.com 2009-06-01 07:52 am (UTC)(link)
Спасибо. Очень вовремя нашлось :)

*А если немного обнаглеть*

[identity profile] l2tp.livejournal.com 2009-06-01 08:27 am (UTC)(link)
... и спросить - есть ли записи выступлений в текстовом виде? Видео на полях комментировать для себя неудобно

[identity profile] sa-drug.livejournal.com 2009-06-02 02:41 pm (UTC)(link)
А у меня давно зрел вопрос.
Я читал про Ваши эксперименты с генерируемым исходящего потоком трафика в RU.UNIX.BSD и результах которые вы достигли. Ну в общем и занимаюсь тем же, не знаю мне кажется мне удалось добиться несколько больших результов:
На интерфейсе:
packets errs bytes packets errs bytes colls
1259248 0 75554880 0 0 0 0
1258310 0 75498600 0 0 0 0
1256251 0 75375060 0 0 0 0
1257109 0 75426480 0 0 0 0
1258555 0 75513360 0 0 0 0
1256815 0 75408900 0 0 0 0

Ну и собственно вопрос:
74 processes: 5 running, 53 sleeping, 16 waiting
CPU states: 0.0% user, 0.0% nice, 10.7% system, 0.2% interrupt, 89.1% idle
Mem: 19M Active, 165M Inact, 275M Wired, 12K Cache, 214M Buf, 3457M Free
Swap: 2048M Total, 2048M Free

PID USERNAME PRI NICE SIZE RES STATE C TIME WCPU COMMAND
12 root 171 ki31 0K 16K CPU2 2 255.4H 100.00% idle: cpu2
13 root 171 ki31 0K 16K RUN 1 253.3H 100.00% idle: cpu1
14 root 171 ki31 0K 16K CPU0 0 252.9H 100.00% idle: cpu0
11 root 171 ki31 0K 16K CPU3 3 177.9H 67.09% idle: cpu3
27 root -68 - 0K 16K - 3 75.0H 35.50% em2 taskq
15 root -44 - 0K 16K WAIT 3 18.9H 2.29% swi1: net

Откуда берется 2.29% swi1: net ? Это я так понимаю как раз и есть случай "файрволы (пакетные фильтры) мешают параллельной обработке пакетов своими блокировками на этапе проверки правил;".

P.S> Сумбурно получилось - пишу сюда потому, что не получается подписаться на RU.UNIX.BSD.

[identity profile] denis-sotchenko.livejournal.com 2011-06-08 08:51 am (UTC)(link)
"степенью параллелизма можно управлять через loader.conf"
Можно поподробнее?