dadv: (chuck)

Повторил старый тест на сегодняшней FreeBSD 8.2-STABLE/UFS.

На двухъядерной домашней системе создал /dev/md0 в 2G размером, смонтировал (async) в /mnt/tmp, скопировал туда /usr/src, создал там же obj и tmp и запустил:

# cd /mnt/tmp/src; time env TMPDIR=/mnt/tmp/tmp MAKEOBJDIRPREFIX=/mnt/tmp/obj make -j3 MODULES_WITH_WORLD=yes buildworld
...
real 61m8.607s
user 99m57.180s
sys 11m30.844s

Эффективность распараллеливания на два ядра более 91%.
Затем то же самое сделал без md:

real    62m21.302s
user    100m22.833s
sys     12m6.297s

Разница — 1 минута и 12.7 секунды. Как и на 7.0, морочиться с созданием RAM-диска нет смысла, FreeBSD достаточно хорошо кеширует UFS.

dadv: (Default)

В продолжение темы.

Итак, FreeBSD это конструктор, части которого требуют ручной доводки напильником, но результат получается хороший (см. ссылку выше). Тем, кого с души воротит от таких конструкторов, можно дальше не читать, а отправляться искать дистрибьютора Cisco, например.

1. Стабильность )

dadv: (chuck)

Видеозапись лекции Игоря Сысоева по настройке некоторых подсистем 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-килобайтных, уменьшая размер системных таблиц и количество промахов процессорного кеша, увеличивая таким образом общее быстродействие системы.

Profile

dadv: (Default)
Choose your future

June 2017

M T W T F S S
   1234
56 7891011
12131415161718
19202122232425
2627282930  

Syndicate

RSS Atom

Tags

Style Credit

Powered by Dreamwidth Studios