20 января 2009

Управление динамическим распределением задач на уровне ОС

"Большие системы" для конечного пользователя означают значительные инвестиции в вычислительные ресурсы, и сразу же возникает вопрос эффективного управления этими мощностями. На этот раз оставим виртуализацию в стороне и рассмотрим динамическое управление ресурсами в пределах одной отдельно взятой операционной системы. Где это необходимо? Примеры:
  • Веб-сервер, поддерживающий несколько экземпляров одного и того же приложения;
  • Сервер, поддерживающий разные приложения (например СУБД и Apache) или HPC-приложения, каждое из которых должно работать с заданными параметрами быстродействия;
  • Сервер, поддерживающий приложения, нагружающие разные ресурсы (подсистемы) этого сервера, но требующие заданный уровень сервиса.
В замечаниях к выпуску Enterprise Linux 5 можно встретить такую фразу:

"...Cpuset обеспечивает механизм назначения узлов процессоров и памяти наборам задач, тем самым ограничивая распределение памяти и процессоров в пределах заданного cpuset. Механизм Cpuset является основным стандартом управления динамическим распределением задач в больших системах..."

Про Cpuset "в двух словах" я и хочу рассказать в этом посте. Данный механизм позволяет "на лету" распределять вычислительные ресурсы между различными задачами, ограничивая использование ОЗУ и ЦП "вычислительным доменом", которому присвоена задача. Впервые поддержка Cpuset появилась в ядре 2.6.12. Патч, включавший данный функционал, был предложен в 2005 году, привносил достаточно небольшой объем кода, дополнительно не нагружая планировщик процессов. Cpuset расширяет возможности уже существовавших в ядре Linux механизмов, позволявших задать с использованием какого ЦП (sched_setaffinity) и ОЗУ (mbind, set_mempolicy) может выполняться задача.

Поскольку управление Cpuset осуществляется при помощи виртуальной файловой системы, самый простой способ проверить, скомпилировано ли ядро вашей системы с поддержкой cpusets - это команда:

[root@server1 ~]# cat /proc/filesystems | grep cpuset
nodev cpuset
Начать работать с cpuset максимально просто:

1) Создадим и смонтируем специальную файловую систему cpuset

[root@server1 ~]# echo "cpuset /cs cpuset defaults 0 0" >> /etc/fstab
[root@server1 ~]# mkdir /cs
[root@server1 ~]# mount -a
В итоге все процессы "привязаны" к корневому и единственному существующему на данный момент "вычислительным домену". У каждого процесса есть файл /proc/PID/cpuset, просмотрев который можно увидеть, к какому cpuset он привязан. В настоящий момент для любого процесса мы увидим картину:

[root@server1 ~]# cat /proc/1/cpuset
/
Кроме того, если посмотреть на специальную файловую систему cpuset, то внутри нашей директории /cs мы обнаружим ряд файлов, среди которых:

- cpus: список ЦП в этом cpuset

[root@server1 ~]# cat /cs/cpus
0-7
- mems: список узлов ОЗУ в этом cpuset

[root@server1 ~]# cat /cs/mems
0
- tasks: список процессов, привязанных к этому cpuset

[root@server1 ~]# cat /cs/tasks | wc -l
151
2) Теперь создадим "дочерний" cpuset. Это делается при помощи создания поддиректории внутри файловой системы cpuset:

[root@server1 ~]# mkdir /cs/cs1
Внутри /cs/cs1 мы увидим те же файлы, что и внутри корня файловой системы cpuset. Далее необходимо привязать ресурсы нашему новому вычислительному домену:

[root@server1 ~]# echo 0,3,7 > /cs/cs1/cpus
[root@server1 ~]# echo 0 > /cs/cs1/mems
3) Присваиваем какую-либо задачу домену cs1:

[root@server1 ~]# echo $(pidof syslogd) > /cs/cs1/tasks
В итоге мы видим:

[root@server1 ~]# cat /proc/$(pidof syslogd)/cpuset
/cs1
и изменившуюся маску ЦП для процесса syslogd:

[root@server1 ~]# cat /proc/$(pidof syslogd)/status | grep Cpus
Cpus_allowed: 00000089
Должен заметить, что наиболее полный из доступных источников по теме - это описание /usr/share/doc/kernel-doc-*/Documentation/cpusets.txt, к которому я и отсылаю вас за дополнительной информацией.

4 комментария:

piavlo комментирует...

Можно использовать cpuset -
http://developer.novell.com/wiki/index.php/Cpuset
удобно и нету заморочек с cpuset virtual filesystem

Andrey Markelov комментирует...

Спасибо за ссылку. Наверняка кому-нибудь пригодится. Думаю в SuSe есть "из коробки"?

piavlo комментирует...

Насчет из коробки не знаю, сам использую в gentoo. Также очень удобно в OpenVZ (OS virtualization) ограничивать VMs.
Думаю с Vserver тоже будет работать.

Andrey Markelov комментирует...

На днях в Red Hat Knowledgebase появилась статья на "смежную" тему "How can I dedicate one or more CPU's on a multi-processor system for exclusive use by one or more specific applications?" http://kbase.redhat.com/faq/docs/DOC-15596