Михаил Кузьминский
ИОХ РАН, Москва
kus@free.net

История развития NQS
Основные задачи NQS
Очереди к устройствам
Пакетные очереди
Конвейерные очереди
Балансировка нагрузки
Настройка и работа с NQS
Заключение
Литература




В давние времена, когда операционных систем было действительно много, а не как сейчас - раз (Unix), два - (MVS) и обчелся (NT), существовало деление ОС на пакетные (IBM DOS/VS, например); диалоговые или системы разделения времени (скажем, знаменитая MULTICS); реального времени (DEC RT-11) и системы общего назначения, в которых указанные режимы работы интегрированы на базовом уровне и одинаково эффективно поддерживаются [1]. Классическим примером последнего типа ОС является IBM MVS. Похоже, ни одна из современных ОС не подошла столь близко к этому идеалу понятия "универсальной" ОС, как MVS. Вместе с тем большинство нынешних ОС в той или иной степени являются универсальными. Так, ОС Unix может считаться системой разделения времени, но она имеет, хотя и не очень развитые, средства пакетной обработки, которым, в первую очередь NQS, расширяющим возможности Unix, и посвящена данная статья. 

Базовые возможности пакетной обработки в Unix, если их сравнить с традиционно представляемыми в пакетных ОС, достаточно скромны. Возможность выполнить команду "в пакете" посредством указания "&" в ее конце, возможность выполнить командную процедуру через команду batch, близкие к этому возможности указания очереди в команде at - всего этого явно мало. А ведь пакетная обработка никак не утратила своего значения и сегодня: кроме пакетного выполнения задач расчетного характера достаточно, например, упомянуть обработку сложных транзакций к БД в пакетном режиме. 

Развитые базовые возможности Unix позволяют разработать программное обеспечение, специально предназначенное для обслуживание пакетных запросов. Оно широко используется в первую очередь в многопроцессорных серверах, но эффективно также, например, для распределения нагрузки между рабочими станциями в локальной сети. 

На самом деле функции подобных программных надстроек часто бывают шире и включают, в частности, поддержку контрольных точек или системы очередей, содержащих запросы к внешним устройствам, в частности, принтерам. Данную обработку запросов к внешним устройствам также, в определенном смысле, можно назвать пакетной. 

В этой области имеется достаточно широкий спектр продуктов, как типа public domain, так и коммерческих: LSF (Load Sharing Facility) от Platform Computing, PBS - новая разработка для NASA, DQS (разработка Университета шт. Флорида), IBM Load Leveler, NQS, близкая к ней NQE от Cray Research и др. Вероятно, NQS является среди них самой распространенной, поэтому на ней и остановимся. 

История развития NQS

Упрощенное "генеалогическое дерево" NQS (Network Queueing System) представлено на рисунке 1. Оно является не совсем неточным, поскольку одни версии NQS оказывали влияние на другие [2,3]. Все началось в 1985 году, когда фирма Sterling Software разработала NQS по заданию NASA. К тому времени разработчикам была известна единственная близкая по функциям система MDQS (Multiple Device Queueing System) - разработка баллистической лаборатории США. Ряд концептуальных идей MDQS был использован в NQS. 

Picture 1
Рисунок 1. 
Развитие версий NQS.

Это первое поколение NQS называлось Cosmic NQS, которая имелась в двух версиях. Cosmic NQS v.1 была куплена компанией Monsanto. Главный автор новых разработок NQS - Джон Роман - выпустил версии вплоть до Monsanto NQS 3.37 включительно. В процессе своего развития уже в Monsanto NQS были включены важные функции из других версий: Cosmic NQS v.2 и CERN NQS. Monsanto NQS поставлялась на условиях Free Software Foun-dation, а с середины 1995 г. за дальнейшее развитие этой версии отвечает Шеффилдский университет (Великобритания). Сама версия теперь называется Generic NQS. 

Кроме этой линии развития NQS имеются и другие "ветви". Для ОС SGI IRIX были разработаны коммерческие версии - 4D/NQS, а затем Sterling NQS. Собственная разработка на базе Cosmic NQS была выполнена в CERN (Швейцария), а уже на ее основе Манчестерский вычислительный центр (Великобритания) создал версию MCC NQS. Наконец, нельзя не упомянуть о Cray NQE - дорогом и высококачественном коммерческом продукте, имеющем развитые средства настройки, GUI - интерфейс и др. интересные особенности. 

Более подробно остановимся на "основной линии" развития NQS (Generic NQS). Как и большинство других программных продуктов типа public domain для ОС Unix, NQS доступна для большого числа различных версий Unix: AIX версий 3 и 4, HP-UX (версии 8, 9 и 10), IRIX (версии 4, 5, 6), Linux 1.x, OSF/1 1.3, 2 и 3.х, Solaris 2.x, FreeBSD 2.2 и др. Необходимым является поддержка интерфейсов BSD-сокетов, поскольку этот механизм используется для работы NQS с сетью. 

Основные задачи NQS

Прежде чем разобрать основные задачи, для решения которых была предназначена NQS [2] следует ввести 2 понятия: пакетный запрос и запрос к внешнему устройству (ВУ-запрос). 

Пакетный запрос - это shell-программа, содержащая команды, которые для своего выполнения не требуют прямого сервиса от определенных физических устройств. Главное - она может выполняться независимо, без вмешательства пользователя, путем вызова необходимого интерпретатора. Напротив, ВУ-запрос включает команды, требующие для своего выполнения прямого сервиса специфического внешнего устройства (например принтера). 

Собственно говоря, первейшая задача NQS - обеспечение поддержки выполнения пакетных и ВУ-запросов. NQS должна поддерживать все виды квот ресурсов, имеющихся в ОС Unix для пакетных запросов. NQS должна обеспечивать поддержку удаленной работы с очередями и маршрутизацию обоих типов запросов по сети. Стало быть, нужно иметь механизм транспортировки запросов, учитывающих сбои, в том числе и самих машин, при передаче данных. NQS должна уметь отправлять файлы stdout и stderr удаленному пользователю, приславшему запрос на выполнение. Наконец, NQS должна предоставлять возможности получения информации о статусе запроса на удаленном хосте (по сети) и обеспечивать отображение учетных номеров пользователей с одного хоста на другой с целью корректной идентификации. 

Соответственно двум типам запросов в NQS имеются два типа очередей - пакетные очереди и очереди к устройствам. Кроме этого, имеются еще конвейерные (pipe) очереди, которые служат для транспортировки пакетных и ВУ-запросов в пакетные очереди, очереди к устройствам или другие конвейерные очереди. 

Очереди к устройствам

Каждой очереди ставится в соответствие набор из одного или более устройств, каждое из которых имеет соответствующий сервер, где выполняются программы для обработки запроса. Когда устройство завершает обработку ВУ-запроса или после появления ВУ-запроса в очереди обнаруживается, что устройство свободно, все очереди, которым приписано данное устройство, сканируются на предмет наличия запросов, которые это устройство может выполнить. Как и в системе MDQS, можно указать в запросе тип формы, используемой для выполнения запроса. Это может применяться, например, для указания нужной печатной формы. Аналог этого механизма форм давно известен в языке управления заданиями ОС MVS фирмы IBM, где он используется для указания печатной формы в операторе DD, описывающем системный вывод. 

Если более одной очереди имеют ВУ-запросы, которые можно выполнить на ставшем свободным устройстве, выбирается запрос из очереди с максимальным приоритетом. Если же приоритет очередей одинаков, используется алгоритм round-robin. 

Пакетные очереди

Для пакетных очередей можно установить ряд пределов (квот) ресурсов, набор которых может быть приписан всей очереди. Кроме того, ограничения могут быть установлены в аргументах команды qsub, с помощью которой пакетный запрос направляется в очередь. Этот набор пределов для запроса фиксируется в момент его постановки в очередь. 

При обработке запроса создаются временные копии файлов stdout и stderr, которые затем отправляются (в общем случае по сети) выдавшему запрос пользователю. Устанавливаются переменные среды окружения, и выбирается нужный тип оболочки. Запрос выполняется с набором установленных ограничений на ресурсы и по окончании выполнения результаты отсылаются пользователю. 

С целью защиты от перегрузки устанавливаются предел выполнения (run limit) - максимальное число одновременно выполняемых запросов. Имеется два типа таких пределов выполнения. Один тип относится к каждой очереди и задает максимальное число одновременно выполняющихся в ней запросов. Другой тип, глобальный предел выполнения, ограничивает число всех одновременно обрабатываемых запросов во всех очередях на данном компьютере. 

Когда завершается выполнение любого пакетного запроса, просматривается весь набор пакетных очередей в порядке уменьшения приоритета очереди. Если найден готовый к выполнению запрос, проверяется, не исчерпан ли предел выполнения данной очереди. Если нет, то после проверки на исчерпание глобального предела выполнения, запрос запускается. В противном случае на предмет возможности запуска пакетного запроса проверяется следующая по приоритету очередь и т. д. 

В более поздних версиях NQS этот алгоритм был усовершенствован путем включения соответственно более сложных механизмов планирования. В качестве иллюстрации возможных проблем рассмотрим следующую простейшую ситуацию. Пусть необходимо выполнять одновременно 3 пакетных запроса, которые могут принадлежать к двум очередям, А и В. В очередь А мы посылаем более "короткие" запросы, а в очередь В - длинные, требующие много процессорного времени и других ресурсов, например оперативной памяти (ОП). Пусть оптимальной загрузке системы - наибольшей пропускной способности в смысле выполняемого в единицу времени числа пакетных запросов, отвечает одновременная обработка двух запросов в очереди А и одного - из очереди В. Если мы установим глобальный предел выполнения, равный 3, предел выполнения для очереди А, равный 2, а для очереди B - равный 1, то в хорошей ситуации будут выполняться 2 коротких запроса в очереди А и один длинный - в очереди В. Но если, например, у нас не будет длинных запросов, то компьютер будет недозагружен. 

В таких ситуациях желательно обеспечить перетекание запросов из очереди А в очередь В. Обратный процесс, вообще говоря, опасен - выполнение сразу двух запросов из очереди В, требующих больших ресурсов, может вызвать, например, большой свопинг из-за нехватки ОП. Для исправления ситуации можно установить предел выполнения для очереди А, равный 3. Тогда при отсутствии запросов в очереди B будут выполняться три запроса из А. Чтобы обеспечить хорошую нагрузку и запуск на выполнение запросов из очереди В, если не превышен глобальный предел выполнения, можно даже поднять приоритет очереди В. 

Интересно сопоставить, как такая простейшая схема выполнения может быть реализована в рамках ОС MVS, знаменитой как своими средствами пакетной обработки, реализуемыми подсистемой JES2, так и уникальными возможностями высокоуровневого планирования SRM [1,4]. Для запуска на выполнение пакетных заданий там используются специальные программы - инициаторы. Таких инициаторов может быть несколько. Каждый инициатор может запускать на выполнение ровно одно задание, принадлежащее одной из входных очередей, определяемых классом задания, и каждому инициатору ставится в соответствие несколько очередей (несколько классов заданий), из которых он может выбирать задания на выполнение. В целях нашего обсуждения (реальность, конечно же, сложнее) можно полагать, что одновременно выполняется столько же заданий, сколько работает инициаторов. Тогда мы достигнем того же, что мы уже описали для NQS, запустив 3 инициатора: 
    Init1 (класс А) 
    Init2 (класс А) 
    Init3 (классы B,A)
Наличие В перед А в списке для инициатора 3 гарантирует, что если имеются задания класса В, инициатор 3 будет запускать их до запуска заданий класса А. Конечно, на практике планирование в MVS осуществляется не столь примитивным способом, а, как правило, с использованием средств SRM, обеспечивающем динамическое планирование. Однако данный пример позволяет продемонстрировать некоторые общие подходы. Это сопоставление полезно и для системных администраторов, имеющих за плечами опыт работы с ЕС ЭВМ. 

В реальной жизни все может быть сложнее. Если вернуться к нашей ситуации с NQS, то предложенный выход может не работать, если, например, очереди В ставится в соответствие выделенная файловая система, например, использующая striping (RAID 0). Тогда после окончания работы одного из трех запросов очереди А может оказаться, что запрос из очереди B запустить нельзя - эта "быстрая" файловая система занята одним из выполняющихся запросов очереди A. Поэтому удобнее было бы, если запрос из очереди А действительно был бы передан в пустую очередь В. 

В общем случае необходимо динамическое планирование, выдающимся образцом которого является средство SRM. Аналогичных интероперабельных средств для ОС Unix, нет, поэтому, например, в Миннесотском суперкомпьютерном центре (США) для этих целей разработали свою собственную программу AQM (Automatic Queue Manager). Она взаимодействует с NQS на системном уровне. Эта программа пока несовершенна, и операторы время от времени регулируют вычислительный процесс вручную. 

В самой NQS добавленные в версии Generic NQS усовершенствования включают поддержку комплекса очередей. А именно, очереди могут объединяться в группы - "комплексы", и для всего комплекса устанавливается свой предел выполнения. Очевидно, что это позволяет осуществлять более гибкое планирование. 

Конвейерные очереди

Конвейерные (pipe) очереди отвечают за маршрутизацию и доставку запросов к другим, возможно, располагающимся на удаленных компьютерах, очередям. В конвейерные очереди могут помещаться как пакетные, так и ВУ-запросы. Для каждой конвейерной очереди определяется список "мест назначения" (destinations), которым из этой очереди доставляются запросы. Сервер, обрабатывающий запросы конвейерной очереди, называется конвейерным клиентом (pipe-клиент, рисунок 2), он может послать запрос в любое место назначения из установленного для этой конвейерной очереди списка. Запрос может быть отвергнут местом назначения, например, из-за сбоя соответствующей рабочей станции. 

Picture 2
Рисунок 2. 
Балансировка нагрузки в NQS.

Очереди места назначения могут быть определены как pipeonly. Это означает, что в них нельзя послать запрос, минуя другую конвейерную очередь, и может быть полезно, например, для борьбы с чрезмерно активными пользователями, желающими послать запрос, минуя общую конвейерную очередь. 

Балансировка нагрузки

Балансировка нагрузки - средство NQS, позволяющее распределить нагрузку от пакетных запросов, например, между рабочими станциями кластера (рисунок 2). Это средство может применяться и для решения проблем, подобных описанным ранее для пакетных очередей. Могут быть установлены различные "режимы" балансировки нагрузки. В простейшем случае, когда балансировки нагрузки нет, конвейерная очередь, имеющая несколько мест назначения, будет слать все запросы по одному адресу, пока соответствующая очередь в месте назначения не будет выведена из доступности (disabled). При установке режима outbound конвейерная очередь будет применять для посылки алгоритм round robin. Можно установить конвейерные очереди с применением для них режима inbound - конвейерная очередь места назначения отвергает запрос от пославшей его конвейерной очереди, если этот запрос нельзя выполнить сразу. 

Самым рафинированным способом является применение концепции планировщика NQS - компьютера (реально имеется в виду, конечно же, программа), задача которого - распределять задания в набор очередей на нескольких других компьютерах. Планировщик имеет общую очередь, установленную в режим outbound, и направляющую запросы в ряд конвейерных очередей на других компьютерах. Последние очереди устанавливаются в режим балансировки нагрузки inbound. Компьютер-планировщик будет направлять пакетные запросы другим компьютерам, используя информацию об их вычислительной мощности и загрузке. Характеристики вычислительной мощности компьютеров задаются при конфигурировании NQS, а текущую их нагрузку определяет NQS Load Daemon - демон, который работает на каждом компьютере"приемнике", измеряет текущую нагрузку на нем и сообщает результаты измерений нагрузки планировщику. 

Как видно, все это говорит о целесообразности применения NQS в гетерогенных компьютерных сетях. 

Настройка и работа с NQS

Конкретно системному администратору приходится сталкиваться с задачей установки параметров в настройках NQS и работать с командами, управления очередями. Могут быть также интересны некоторые простые, но полезные сведения, полученные в процессе эксплуатации системы NQS в суперкомпьютерном Центре ИОХ РАН. 

Ограничение доступных ресурсов (quota limits) позволяет системному администратору добиться рационального распределения запросов по пакетным очередям. Имеется два типа устанавливаемых ограничений - на запрос в целом и на процесс. В последнем случае имеется в виду возможность выполнения нескольких процессов в рамках одного пакетного запроса. В частности, можно устанавливать ограничения на размер core-файла, размер сегмента данных, размер виртуальной памяти, рабочего множества страниц (физической ОП), процессорное время, размеры файлов и др. 

Контроль доступа к очередям. При необходимости для ограничения возможности пользователю отправлять свои запросы в наиболее приоритетные очереди можно применять механизм контроля доступа к очередям. Для каждой очереди устанавливается один из двух режимов доступа - неограниченный и ограниченный. В первом режиме в очередь можно поставить любой запрос, а во втором - контролируются идентификаторы пользователя и группы в соответствии со списком доступа, отвечающим данной очереди. Для удаленных пользователей применяется отображение их идентификаторов в локальные. Кроме того, как уже было отмечено, очередь может иметь флаг "pipeonly", тогда она способна воспринимать только запросы, присылаемые из других конвейерных очередей. 

Shell - стратегия пакетных запросов. Обычно на вычислительной установке пользователям доступно несколько различных типов оболочки (C-shell, Korn shell и т. д.), и направляемая в пакетную очередь shell-программа может использовать любой из них. Выполнение пакетного запроса вызывает создание процесса оболочки для выполнения такой программы. Какой конкретно тип оболочки им применяется, можно указать непосредственно в команде посылки в очередь, qsub. NQS использует собственную shell-стратегию пакетных запросов для определения того, какую оболочку применять. Имеется три режима, определяющие эту стратегию выбора, - фиксированный (fixed), свободный (free) и login-режим. Режимы устанавливает системный администратор при конфигурировании NQS. 

При установке фиксированного режима применяемая оболочка, как это очевидно из названия, для всех запросов очереди - одна и та же (по умолчанию - bourne shell). Свободная стратегия, которая применяется при отсутствии явного указания для соответствующей очереди, означает выбор оболочки, указанной в строке файла /etc/passwd, описывающей данного пользователя. Этот режим максимально близок к обычному интерактивному выполнению shell-программы пользователем. Наконец, стратегия login означает просто-напросто установку для очереди умалчиваемого типа оболочки, который берется из /etc/passwd. Применение режимов fixed и login целесообразно на компьютерах, имеющих проблему ограниченного числа свободных процессов - при этом не создаются новые копии процесса-оболочки. 

Команды, изменяющие положение заданий в очередях. Типовые состояния запросов включают команды "running" - выполняется (его аналог для конвейерной очереди - "routing"); "queued" - стоит в очереди, готов перейти в состояние running или routing; "waiting" - ожидает; "arriving" - прибывает из одной конвейерной очереди в другую очередь; "holding" - задержан. Пользователь, имеющий права на выполнение всех операций с NQS (в простейшем случае root), может задерживать, освобождать и удалять отдельные запросы; пересылать отдельные запросы из очереди в очередь; "чистить" очередь - удалять из нее все запросы; пересылать все запросы из одной очереди в другую и т. д. 

Файлы и процессы NQS. Информация о некоторых файлах, используемых NQS во время своей работы, а также о процессах, создаваемых при запуске NQS, может быть полезна системным администраторам. Эти данные в документации, как правило, отсутствуют, если, конечно, не считать документацией исходные тексты NQS. Рассмотрим простейший случай - пакетную обработку на одном сервере, относящуюся, строго говоря, к NQS v.3.40. Эта версия была инсталлирована на SGI Power Challenge (ОС IRIX 6.1). 

На рисунке 3 представлено генеалогическое дерево процессов. Отметим, что NQS logdaemon предназначен для записи относящейся к работе NQS журнальной информации в файл, который указывается при конфигурировании NQS или непосредственно в момент ее запуска. Программа netdaemon отвечает за сетевое взаимодействие. Программы, загружаемые при запуске NQS (nqsdaemon, netdaemon и др.), располагаются в каталоге /usr/local/sbin, а утилиты NQS (qmgr, qsub и т.д.) - в /usr/local/bin. Конфигурационный файл nqs.config, описывающий местонахождение основных каталогов nqs, находится при этом в /usr/local/sbin. 

Picture 3
Рисунок 3. 
"Генеалогическое дерево" процессов NQS.

Собственно выполняющиеся пакетные запросы представляются процессами - потомками процессов nqsdaemon, отмеченных звездочками на рисунке 3. Последние могут вызывать, скажем, процесс с-shell, а тот запускает на выполнение файл /usr/var/spool/nqs/scripts/PID, где PID - идентификатор процесса с-shell (здесь и далее предполагается умалчиваемое расположение спула системы NQS). Такой файл образуется в момент запуска запроса на выполнение и содержит копию скрипта, отвечающего данному запросу. Эта копия, в свою очередь, создается на основе другой копии - файла, находящегося в одном из подкаталогов каталога /usr/var/spool/nqs/private/root/data. Этот файл (копия скрипта) создается в момент постановки запроса в очередь. Отметим также, что локальные копии файлов stdout и stderr для выполняемых запросов создаются в спуле в одном из подкаталогов каталога /usr/avr/spool/nqs/private/root/output. 

Об этом пришлось упомянуть, в частности потому, что в процессе эксплуатации NQS v.3.40 на указанном компьютере была обнаружена потрясающая особенность - все пакетные очереди NQS после ее рестарта напрочь "забывали", что в них перед рестартом были задания. Поскольку скрипты всех поступивших пакетных запросов в разработанной системе интерфейса NQS c электронной почтой хранились в собственных файлах пользователя вплоть до завершения выполнения, пришлось вставить информацию о том, в какую очередь пришел этот скрипт прямо в эти файлы. Это позволило автоматизировать восстановление очередей после рестарта. При пересылке запроса из очереди в очередь понадобилось изменять также и эти файлы, а заодно и вносить изменения в спул NQS. Все данные "прелести" с очисткой очередей при рестарте отсутствуют в новой версии NQS v.3.50.2. 

Заключение

Естественно, что здесь не удалось рассказать о всех интересных особенностях NQS, в частности, о возможностях сопоставлять каждой очереди набор процессоров, на которых пакетные запросы данной очереди будут выполняться. Эта особенность может быть реализована в многопроцессорных серверах, ОС которых допускает создание "процессорных наборов" (например ОС IRIX). NQS - это быстро развивающееся программное средство. Поэтому некоторые из описанных в статье особенностей могут отсутствовать в каких-то версиях, а другие - устареть. Основная цель данной статьи - дать системным администраторам, пока еще не применяющим NQS или только приступающим к ее использованию, общее представление об основных особенностях этого программного продукта и некоторых областях его применения - NQS может быть полезна в целом ряде приложений. 

Работа выполняется по гранту РФФИ 95-07-20201 

Литература

[1]. Г. Лорин, Х.М. Дейтел, "Операционные системы", - М., Финансы и статистика, 1984, с. 107. 

[2]. B.A. Kingsbury, Sterling Software preliminary draft "The Network Kueueing System", NASA, 1985. 

[3]. S. Herbert, Generic NQS documentation, Univ. of Sheffield, 1996 

[4]. OS/VS2 MVS Overview, IBM, 1983.