diff --git a/s4a.tex b/s4a.tex index dcc39d1..1ef1b17 100644 --- a/s4a.tex +++ b/s4a.tex @@ -3680,7 +3680,7 @@ $ journalctl /dev/sdc $ journalctl /usr/sbin/vpnc \end{Verbatim} Хм, ничего подозрительного. Но, кажется, проблема где-то во взаимодействии между -+vpnc+ и +dhclient+. Посмотрим объединенный и отсортированный по времени списов ++vpnc+ и +dhclient+. Посмотрим объединенный и отсортированный по времени список сообщений от этих процессов: \begin{Verbatim} $ journalctl /usr/sbin/vpnc /usr/sbin/dhclient @@ -3829,7 +3829,7 @@ SELinux ;-) Разумеется, такое дополнение работае Например, о том, что +journalctl+ может выводить данные в формате JSON, или в формате +/var/log/messages+, но с относительными метками времени, как в dmesg. -\section{Управление ресурсами} +\section{Управление ресурсами с помощью cgroups} Важную роль в современных компьютерных системах играют механизмы управления использованием ресурсов: когда вы запускаете на одной системе несколько @@ -3866,16 +3866,35 @@ Resource Limits}. администраторам. В свое время я -\href{http://0pointer.de/blog/projects/cgroups-vs-cgroups.html}{пояснял}, что -контрольные группы Linux (cgroups) могут работать и как механизм группировки и -отслеживания процессов, и как инструмент управления использованием ресурсов. Для -функционирования systemd необходим только первый из этих режимов, а второй -опционален. И именно этот опциональный второй режим дает вам возможность -распределять ресурсы между службами. (А сейчас очень рекомендую вам, прежде чем -продолжать чтение этой статьи, ознакомиться с -\href{https://en.wikipedia.org/wiki/Cgroups}{базовой информацией о cgroups}. -Хотя дальнейшие рассуждения и не~будут затрагивать низкоуровневые аспекты, все -же будет лучше, если у вас сформируется некоторое представление о них.) +\href{http://0pointer.de/blog/projects/cgroups-vs-cgroups.html}{пояснял}% +\footnote{Прим. перев.: В указанном документе автор рассказывает, что +контрольные группы Linux состоят из двух сущностей: \textbf{(A)} механизма +иерархической группировки и маркировки процессов, и \textbf{(B)} механизма, +позволяющего распределять ресурсы между полученными группами. Для работы (B) +необходимо (A), но не~наоборот~--- (A) может прекрасно работать без (B). Для +нормально функционирования systemd (A) \emph{необходим}, а (B) опционален (он +лишь обеспечивает работу некоторых настроек). Вы можете собрать ядро только с +необходимой для (A) опцией +CONFIG_CGROUPS=y+, отключив все связанные с (B) +опции (такие как {\tiny +CONFIG_CGROUP_FREEZER=y+, +CONFIG_CGROUP_DEVICE=y+, ++CONFIG_CGROUP_CPUACCT=y+, +CONFIG_CGROUP_MEM_RES_CTLR=y+, ++CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y+, +CONFIG_CGROUP_MEM_RES_CTLR_KMEM=y+, ++CONFIG_CGROUP_PERF=y+, +CONFIG_CGROUP_SCHED=y+, +CONFIG_BLK_CGROUP=y+, ++CONFIG_NET_CLS_CGROUP=y+, +CONFIG_NET_PRIO_CGROUP=y+}), и systemd будет +нормально работать на такой системе (за исключением того, что связанные с этими +контроллерами настройки не~будут срабатывать). Однако, если собрать ядро без ++CONFIG_CGROUPS=y+, функциональность systemd будет сильно ограничена. При этом, +автор особо подчеркивает, что все негативные эффекты влияния контрольных групп +на производительность обусловлены именно (B), в то время как (A) на +производительность практически не~влияет.}, что контрольные группы Linux +(cgroups) могут работать и как механизм группировки и отслеживания процессов, и +как инструмент управления использованием ресурсов. Для функционирования systemd +необходим только первый из этих режимов, а второй опционален. И именно этот +опциональный второй режим дает вам возможность распределять ресурсы между +службами. (А сейчас очень рекомендую вам, прежде чем продолжать чтение этой +статьи, ознакомиться с \href{https://en.wikipedia.org/wiki/Cgroups}{базовой +информацией о cgroups}. Хотя дальнейшие рассуждения и не~будут затрагивать +низкоуровневые аспекты, все же будет лучше, если у вас сформируется некоторое +представление о них.) Основными контроллерами cgroups, отвечающими за управление ресурсами, являются \href{http://www.kernel.org/doc/Documentation/scheduler/sched-design-CFS.txt}{cpu}, @@ -3886,6 +3905,227 @@ Resource Limits}. systemd предоставляет ряд высокоуровневых настроек, позволяющих использовать эти контроллеры, не~вникая в технические детали их работы. +\subsection{Процессор} + +Если в ядре включен контроллер +cpu+, systemd по умолчанию создает контрольную +группу по этому ресурсу для каждой службы. Даже без каких-либо дополнительных +настроек это дает положительных эффект: на системе под управлением systemd все +службы получают равные доли процессорного времени, независимо от количества +процессов, запущенных в рамках службы. Например, на вашем веб-сервере MySQL с +несколькими рабочими процессами получит такую же долю процессорного времени, +как и Apache, даже если тот запустил 1000 CGI-процессов. Разумеется, такое +поведение при необходимости можно легко отключить~--- см. опцию +\href{http://0pointer.de/public/systemd-man/systemd.conf.html}{DefaultControllers=} +в файле +/etc/systemd/system.conf+. + +Если \emph{равномерное} распределение процессорного времени между службами вас +не~устраивает, и вы хотите выделить определенным службам больше или меньше +времени~--- используйте опцию +\href{http://0pointer.de/public/systemd-man/systemd.exec.html}{CPUShares} в +конфигурационном файле службы. По умолчанию это значение равно 1024. Увеличивая +это число, вы даете службе больше процессорного времени, уменьшая~--- +соответственно, меньше. + +Рассмотрим небольшой практический пример. Допустим, вам нужно увеличить +для службы Apache относительную долю потребления процессора до 1500. Для этого +создаем файл <<ручных>> настроек +/etc/systemd/system/httpd.service+, который +включает в себя все те же опции, что и файл настроек по умолчанию ++/usr/lib/systemd/system/httpd.service+, отличаясь от него только значением ++CPUShares=+: +\begin{Verbatim} +.include /usr/lib/systemd/system/httpd.service + +[Service] +CPUShares=1500 +\end{Verbatim} +Первая строка обеспечивает включение в нашу конфигурацию файла с настройками по +умолчанию, сделанными разработчиками Apache или его сопровождающими в вашем +дистрибутиве (если это включение не~указать явно, данный файл будет проигнорирован). +Далее, мы указываем тот параметр, который хотим изменить. Сохраняем файл, +приказываем systemd перечитать конфигурацию, и перезапускаем Apache, чтобы +настройки вступили в силу\footnote{Прим. перев.: К сожалению, в настоящее время +systemd не~поддерживает изменение параметров контрольных групп без перезапуска +службы. Но вы можете узнать контрольную группу службы командой наподобие ++systemctl show -p ControlGroup avahi-daemon.service+, и выполнить настройки +любым удобным для вас способом, например, через запись значений в псевдофайлы +cgroupfs. Разумеется, при следующем запуске службы к ней будут применены +параметры, указанные в конфигурационном файле.}: +\begin{Verbatim} +systemctl daemon-reload +systemctl restart httpd.service +\end{Verbatim} +Готово! + +Обратите внимание, что явное указание значения +CPUShares=+ в конфигурации +службы заставит systemd создать для нее контрольную группу в иерархии контроллера ++cpu+, даже если этот контроллер не~указан в +DefaultControllers=+ (см. выше). + +\subsection{Отслеживание использования ресурсов} + +Для того, чтобы правильно распределять ресурсы между службами, неплохо бы знать +реальные потребности этих служб. Чтобы упростить для вас отслеживание +потребления ресурсов службами, мы подготовили утилиту +\href{http://www.freedesktop.org/software/systemd/man/systemd-cgtop.html}{systemd-cgtop}, +которая находит все имеющиеся в системе контрольные группы, определяет для +каждой из них количество потребляемых ресурсов (процессорное время, память и +ввод-вывод) и выводит эти данные в динамически обновляемой сводной таблице, по аналогии +с программой \href{http://linux.die.net/man/1/top}{top}. Используя вводимое +systemd распределение служб по контрольным группам, эта утилита выводит для +служб те же сведения, которые top выводит для отдельных процессов. + +К сожалению, по умолчанию +cgtop+ может раздельно отслеживать для каждой службы +только потребление процессорного времени, а сведения по использованию памяти и +ввода-вывода доступны только для всей системы в целом. Это ограничение возникает +из-за того, что в конфигурации по умолчанию контрольные группы для служб +создаются только в иерархии контроллера +cpu+, но не~+memory+ и~+blkio+. Без +создания групп в иерархии этих контроллеров невозможно отследить использование +ресурса по службам. Самый простой способ обойти это ограничение~--- приказать +systemd создавать соответствующие группы, добавив +memory+ и +blkio+ в перечень ++DefaultControllers=+ в файле +system.conf+. + +\subsection{Память} + +Используя опции +MemoryLimit=+ и +MemorySoftLimit=+, вы можете ограничивать +суммарное потребление оперативной памяти всеми процессами службы. В них +указывается предел потребления памяти в байтах\footnote{Прим. перев.: Разница +между +MemorySoftLimit=+ и +MemoryLimit=+ состоит в том, что первый предел можно +превышать, если в системе еще есть достаточное количество свободной памяти. +Второй из этих пределов превышать нельзя, независимо от наличия свободной +памяти. Подробнее см. раздел <> в +\href{http://www.kernel.org/doc/Documentation/cgroups/memory.txt}{файле +документации}.}. При этом поддерживаются суффиксы K, M, G и T, обозначающие +соответственно, килобайт, мегабайт, гигабайт и терабайт (по основанию 1024). +\begin{Verbatim} +.include /usr/lib/systemd/system/httpd.service + +[Service] +MemoryLimit=1G +\end{Verbatim} + +По аналогии с +CPUShares=+, явное указание этих опций заставит systemd создать +для службы контрольную группу в иерархии контроллера +memory+, даже если он +не~был указан в +DefaultControllers=+. + +\subsection{Ввод-вывод} + +Для контроля пропускной полосы ввода-вывода с блочных устройств, доступно +несколько настроек. Первая из них~--- +BlockIOWeight=+, задающая \emph{долю} полосы +ввода-вывода для указанной службы. Принцип похож на +CPUShares=+ (см. выше), однако +здесь величина относительной доли ограничена значениями от 10 до 1000. По +умолчанию, она равна 1000. Уменьшить долю для службы Apache можно так: +\begin{Verbatim} +.include /usr/lib/systemd/system/httpd.service + +[Service] +BlockIOWeight=500 +\end{Verbatim} + +При необходимости, вы можете задать это значение отдельно для каждого +устройства: +\begin{Verbatim} +.include /usr/lib/systemd/system/httpd.service + +[Service] +BlockIOWeight=/dev/disk/by-id/ata-SAMSUNG_MMCRE28G8MXP-0VBL1_DC06K01009SE009B5252 750 +\end{Verbatim} + +При этом, точное название устройства знать не~обязательно~--- достаточно указать +интересующий вас каталог: +\begin{Verbatim} +.include /usr/lib/systemd/system/httpd.service + +[Service] +BlockIOWeight=/home/lennart 750 +\end{Verbatim} +Если заданный вами путь не~указывает на файл устройства, systemd автоматически +определит, на каком устройстве расположен указанный файл/каталог, и выставит для +этого устройства соответствующую настройку. + +Вы можете добавить несколько таких строк, задавая долю пропускной полосы +отдельно для различных устройств, и при этом также допускается указать <<общее>> +значение (как в первом примере), которое будет использовано для всех остальных +устройств. + +В качестве альтернативы относительной доле пропускной полосы, вы также можете +ограничивать абсолютную долю, используя настройки +BlockIOReadBandwidth=+ и ++BlockIOWriteBandwidth=+. В них нужно указать устройство или любой находящийся +на нем файл/каталог, а также предельную скорость чтения/записи в байтах в +секунду: +\begin{Verbatim} +.include /usr/lib/systemd/system/httpd.service + +[Service] +BlockIOReadBandwith=/var/log 5M +\end{Verbatim} +В результате, для данной службы скорость чтения с устройства, содержащего +каталог +/var/log+, будет ограничена величиной 5 мегабайт в секунду. + +По аналогии с вышеописанными +CPUShares=+ и +MemoryLimit=+, явное указание любой +из приведенных настроек пропускной полосы заставит systemd создать для службы +контрольную группу в иерархии контроллера +blkio+. + +\subsection{Прочие параметры} + +Вышеописанные опции покрывают лишь малую толику настроек, поддерживаемых +различными контроллерами Linux croups. Мы добавили высокоуровневый интерфейс +только к тем настройкам, которые кажутся нам наиболее важным для большинства +пользователей. Из соображений удобства мы добавили механизмы, обеспечивающие +поддержку крупных единиц измерения (килобайты, мегабайты и т.д.) и +автоматическое определение блочных устройств по указанному файлу/каталогу. + +В некоторых случаях описанных высокоуровневых настроек может оказаться +недостаточно~--- допустим, вам нужно задать низкоуровневую настройку cgroups, +для которой мы (пока) не~добавили высокоуровневого аналога. На этот случай мы +предусмотрели универсальных механизм задания таких опций в конфигурационных +файлах юнитов. Рассмотрим, например, задание для службы параметра +\emph{swappiness} (относительная интенсивность использования подкачки для +процессов службы). В systemd нет высокоуровневой настройки для этого значения. +Однако вы можете задать его, используя низкоуровневую настройку ++ControlGroupAttribute=+: +\begin{Verbatim} +.include /usr/lib/systemd/system/httpd.service + +[Service] +ControlGroupAttribute=memory.swappiness 70 +\end{Verbatim} +Как обычно, явное указание настройки, относящейся к какому-либо контроллеру (в +нашем случае +memory+) приведет к автоматическому созданию группы в иерархии +данного контроллера. + +В дальнейшем, возможно, мы расширим возможности высокоуровневой настройки +различных параметров контрольных групп. Если вы часто пользуетесь какими-то из +них и полагаете, что для них можно добавить соответствующие опции~--- +не~стесняйтесь обращаться к нам. А лучше всего~--- присылайте сразу патч! + +\begin{caveat} + Обратите внимание, что использование некоторых контроллеров может сильно + сказаться на производительности системы. Это та цена, которую приходится + платить за контроль над ресурсами. Использование таких контроллеров + может ощутимо замедлить некоторые операции. В частности, весьма + нелестная в этом плане репутация закрепилась за контроллером +memory+ + (хотя, не~исключено, что эта проблема уже исправлена в свежих выпусках + ядра). +\end{caveat} + +Для углубленного изучения темы, затронутой в этой статье, вы можете обратиться к +документации по +\href{http://0pointer.de/public/systemd-man/systemd.exec.html}{поддерживаемым +настройкам юнитов}, а также по контроллерам +\href{http://www.kernel.org/doc/Documentation/scheduler/sched-design-CFS.txt}{cpu}, +\href{http://www.kernel.org/doc/Documentation/cgroups/memory.txt}{memory} и +\href{http://www.kernel.org/doc/Documentation/cgroups/blkio-controller.txt}{blkio}. + +Стоит подчеркнуть, что мы сейчас обсуждали распределение ресурсов \emph{между +службами}. В дополнение к этим современным механизмам, systemd также +поддерживает и традиционные настройки, касающиеся распределения ресурсов +\emph{между отдельными процессами}. Хотя такие настройки обычно наследуются +порожденными процессами, они, тем не~менее, все равно ограничивают ресурсы +на уровне отдельных процессов. В частности, к ним относятся +IOSchedulingClass=+, ++IOSchedulingPriority=+, +CPUSchedulingPolicy=+, +CPUSchedulingPriority=+, ++CPUAffinity=+, +LimitCPU=+ и т.п. Для их работы не~требуют контроллеры cgroups, +и они не~так сильно ухудшают производительность. Возможно, мы рассмотрим их в +последующих статьях. + \end{document} vim:ft=tex:tw=80:spell:spelllang=ru