Системное администрирование ОС Solaris 10

Управление пулами ресурсов. Проекты. Зоны и контейнеры

Разбить на страницы
Показывать лекцию целиком

В Solaris применяется весьма серьезная и многоуровневая схема управления ресурсами. Именно поэтому Solaris имеет репутацию самой масштабируемой системы. В этой лекции мы обсудим базовые примитивы управления ресурсами и практику этого управления.

Процессы, задачи и проекты

Прежде всего, надо признаться, что в Solaris процессы группируются в задачи, а задачи, в свою очередь, в проекты (рис. 6.1). В проекте может быть одна задача, и задача может состоять из единственного процесса. Проект является единицей назначения ресурсов (которые будут обсуждаться ниже, в разделе "Пулы ресурсов"), и поэтому количество задач в проекте и общее количество проектов определяется реальной необходимостью распределения разнородных ресурсов между процессами.

(рис 6.1) Процессы, задачи (task) и проекты (project

После установки в системе уже определены несколько проектов. По умолчанию они перечислены в файле /etc/project и сразу после установки системы он выглядит так:

# cat /etc/project
system:0::::
user.root:1::::
noproject:2::::
default:3::::
group.staff:10::::

Некоторые пользователи уже отнесены к определенному проекту; в нашем случае этой чести удостоены только пользователь root (запись user.root) и все, для кого группа staff (group.staff) является главной. Все остальные при входе в систему ассоциируются только с проектом default. Для проекта могут быть назначены какие-либо специфические ресурсы, но это не обязательно.

Концепция проектов придумана для управления большими группами процессов, и объединять процессы в такие группы можно по разным признакам.

При входе в систему любого пользователя создается задача (состоящая как минимум из командного процессора), ей назначается проект, и все задачи, порождаемые в рамках этой сессии, относятся к к этому проекту. Порядок назначения проекта при входе пользователя в систему таков:

  • просматривается файл /etc/user_attr (он содержит атрибуты пользователей), и если этот пользователь в нем присутствует, то проектом по умолчанию для данного пользователя назначается проект, объявленный для него в этом файле в параметре project ;
  • просматривается файл /etc/project, и если в нем указан проект для user.username, то проектом по умолчанию для данного пользователя назначается этот проект;
  • просматривается файл /etc/project, и если в нем объявлен проект для group.groupname, то система назначает этот проект данному пользователю проектом по умолчанию, если эта указанная группа является главной для данного пользователя;
  • если в файле /etc/project есть проект с именем default, то он назначается проектом по умолчанию для всех пользователей.
  • Если в файле /etc/project есть какой-либо проект, в поле "пользователи" которого указан данный пользователь, это означает, что данному пользователю разрешается присоединяться к данному проекту (например, с помощью указания имени этого проекта программе newtask ):

    newtask -p user.brad bash

    Можно посмотреть, процессы каких проектов запущены в системе, и оценить суммарную загрузку по процессам каждого проекта.

    # prstat -J
    PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/NLWP
    1669 filip 161M 42M cpu0 59 0 0:03:05 4,7% rhythmbox/9
    1757 filip 239M 104M run 59 0 0:17:57 1,3% firefox-bin/7
    691 filip 216M 193M sleep 59 0 0:15:57 1,2% Xorg/1
    1828 filip 279M 143M sleep 59 0 0:04:01 1,0% soffice.bin/6
    2063 root 7424K 3552K cpu1 59 0 0:00:00 0,5% prstat/1
    992 filip 124M 26M sleep 49 0 0:00:21 0,2% gnome-terminal/2
    903 filip 76M 17M sleep 59 0 0:00:33 0,1% metacity/1
    925 filip 135M 16M sleep 59 0 0:00:50 0,0% wnck-applet/1
    777 noaccess 78M 53M sleep 59 0 0:00:59 0,0% java/24
    937 filip 138M 19M sleep 59 0 0:00:31 0,0% mixer_applet2/1
    434 root 6868K 5196K sleep 59 0 0:00:48 0,0% hald-addon-acpi/1
    1019 mysql 52M 17M sleep 59 0 0:00:24 0,0% mysqld/10
    911 filip 163M 49M sleep 49 0 0:00:16 0,0% nautilus/1
    892 filip 73M 12M sleep 59 0 0:00:06 0,0% iiim-panel/1
    789 filip 2992K 1544K sleep 59 0 0:00:00 0,0% dbus-daemon/1
    PROJID NPROC SWAP RSS MEMORY TIME CPU PROJECT
    3 46 586M 852M 56% 0:49:07 8,6% default
    1 3 3252K 9500K 0,6% 0:00:00 0,5% user.root
    0 44 27M 121M 7,9% 0:02:11 0,1% system
    Total: 93 processes, 296 lwps, load averages: 0,22, 0,15, 0,09

    Естественно, что список проектов может быть размещен не только в файле /etc/project, но и в других источниках – каталогах NIS, LDAP или иных. Главное – корректно указать источник для поиска описаний проектов в /etc/nsswitch.conf.

    Записи файла /etc/project имеют следующий синтаксис:

    projname:projid:comment:user-list:group-list:attributes

    где

  • projname – имя проекта;
  • projid – уникальный идентификатор проекта;
  • comment – описание проекта;
  • user-list – список пользователей, использующих данный проект;
  • group-list – список групп пользователей, использующих данный проект;
  • attributes – параметры, определяющие возможность использования ресурсов.
  • Все поля, кроме projname и projid, являются необязательными:

    system:0::::
    user.root:1::::
    noproject:2::::
    default:3::::
    group.staff:10::::
    user.brad:150:A project for user brad:brad::project.max-lwps=(priv,20,deny)

    Задачи создаются при следующих действиях/командах:

  • login
  • cron
  • su
  • newtask
  • setproject
  • С помощью команд id и ps можно определить, с какими проектами пользователь связан:

    id -p
    uid=0(root) gid=0(root) projid=1(user.root)
    ps -o user,pid,uid,projid
    USER PID UID PROJID
    root 1242 0 1
    root 2935 0 1

    Создадим новый проект foopro c идентификатором 150 для пользователя brad:

    # projadd -U brad -p 150 foopro

    Добавим описание проекта foopro:

    # projmod -c "A project for user brad" foopro
    # cat /etc/project
    system:0::::
    user.root:1::::
    noproject:2::::
    default:3::::
    group.staff:10::::
    foopro:150:A project for user brad:brad::
    # su - brad
    Sun Microsystems Inc. SunOS 5.11 snv_79a January 2008
    $ projects
    default foopro

    Однако этой операцией мы лишь разрешили пользователю brad присоединяться к проекту foopro. Если же мы хотим, чтобы проект foopro был проектом по умолчанию для пользователя brad, надо либо изменить соответственно строку описания пользователя brad в /etc/user.attr, либо переименовать проект foopro в user.brad. В примере ниже мы также наложили ограничение на максимальное количество одновременно запускаемых пользователем потоков исполнения. В ограничении priv означает тип ограничения (priviliged, может быть изменено только администратором), а deny (запретить) – действие, которое следует выполнить при превышении заданного лимита.

    system:0::::
    user.root:1::::
    noproject:2::::
    default:3::::
    group.staff:10::::
    user.brad:150:A project for user brad:brad::project.max-lwps=(
    priv,20,deny)

    Пулы ресурсов

    Пул ресурсов следует отличать от пула ZFS – это совершенно разные понятия. Ресурсами в пуле могут быть процессоры и память. В Solaris 10 до Solaris 10 update 4 (он же – Solaris 10 08/07) включительно в качестве ресурсов в пул можно было включать допускались только процессоры, в Solaris Express (по крайней мере в версии SXDE 09/07 и SXDE 01/08) допустимо включать и оперативную память.

    Применять пулы для управления ресурсами удобно в ряде случаев, а именно:

  • для разделения системы на пользовательскую и системную часть и назначение для них ресурсов по-отдельности;
  • для разделения ресурсов сервера между несколькими критически важными задачами, когда следует гарантировать некий минимальный объем ресурсов для каждой из них;
  • для работы приложений реального времени;
  • для выделения конкретным пользователям гарантированные ресурсы;
  • Для того, чтобы назначить пул ресурсов проекту, следует установить соответствующий атрибут project.pool в файле /etc/project либо выполнить команду:

    # projmod -s -K project.pool=pool_name project_name

    Каждый проект может быть ассоциирован только с одним пулом.

    Для настройки пулов применяется статическая таблица параметров /etc/pooladm.conf. По умолчанию в Solaris функциональность пулов выключена, и этого файла нет. При включении механизма пулов этот файл допустимо создать с параметрами, установленными "по умолчанию". Если при старте операционная система обнаруживает этот файл, то она автоматически включает механизм пулов. Таблица параметров в этом файле хранится в формате XML и не предназначена для редактирования. Для изменения параметров следует применять команду poolcfg.

    Вы можете использовать различные таблицы параметров для разного времени суток, выполняя скрипты, содержащие poolcfg с помощью cron(1M).

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

    Прежде всего, для управления ресурсами посредством формирования пулов надо разрешить системе использовать класс планирования FSS по умолчанию (fair share scheduling – долевое распределение ресурсов).

    Для этого следует дать команду

    dispadmin -d FSS

    Теперь следует позаботиться о создании нового пула ресурсов и его настройке. Для разрешения функциональности пулов ресурсов следует использовать команду pooladm, а для создания пула и изменения его настроек – команду poolcfg.

    Создадим новый пул ресурсов, состоящий из одного-единственного процессора (этот пример проверен на компьютере с двухъядерным процессором AMD, и каждое ядро система видит как отдельный процессор):

    pooladm -e # разрешить пулы ресурсов в системе
    pooladm # показать определенные на данный момент пулы ресурсов
    system default
    string system.comment
    int system.version 1
    boolean system.bind-default true
    string system.poold.objectives wt-load
    pool pool_default
    int pool.sys_id 0
    boolean pool.active true
    boolean pool.default true
    int pool.importance 1
    string pool.comment
    pset pset_default
    pset pset_default
    int pset.sys_id -1
    boolean pset.default true
    uint pset.min 1
    uint pset.max 65536
    string pset.units population
    uint pset.load 162
    uint pset.size 2
    string pset.comment
    cpu
    int cpu.sys_id 1
    string cpu.comment
    string cpu.status on-line
    cpu
    int cpu.sys_id 0
    string cpu.comment
    string cpu.status on-line

    Теперь cоздадим статическую таблицу /etc/pooladm.conf с параметрами по умолчанию и посмотрим на эти параметры:

    # pooladm -s
    cat /etc/pooladm.conf
    <?xml version="1.0"?>
    <!DOCTYPE system PUBLIC "-//Sun Microsystems Inc//DTD Resource
    Management All//EN" "file:///usr/share/lib/xml/dtd/rm_pool.dtd.1">
    <!--
    Configuration for pools facility. Do NOT edit this file by hand - use
    poolcfg(1) or libpool(3POOL) instead.
    -->
    <system ref_id="dummy" name="default" comment="" version="1"
    bind-default="true">
    <property name="system.poold.objectives" type="string">wt-load</property>
    <pool name="pool_default" active="true" default="true" importance="1"
    comment="" res="pset_-1" ref_id="pool_0">
    <property name="pool.sys_id" type="int">0</property>
    </pool>
    <res_comp type="pset" sys_id="-1" name="pset_default" default="true"
    min="1" max="65536" units="population" comment="" ref_id="pset_-1">
    <property name="pset.load" type="uint">160</property>
    <property name="pset.size" type="uint">2</property>
    <comp type="cpu" sys_id="1" comment="" ref_id="cpu_1">
    <property name="cpu.status" type="string">on-line</property>
    </comp>
    <comp type="cpu" sys_id="0" comment="" ref_id="cpu_0">
    <property name="cpu.status" type="string">on-line</property>
    </comp>
    </res_comp>
    </system>

    Этот файл содержит те же самые настройки, что мы видели ранее, дав команду pooladm без параметров. Однако pooladm без параметров выводит только настройки по умолчанию, и для получения полной информации о существующих в системе пулах ресурсов следует использовать команду poolcfg -c info.

    Определим новый пул test, в который входит одна процессорная группа small, состоящая из одного процессора.

    Для этого вначале определим процессорную группу:

    poolcfg -c 'create pset small ( uint pset.min = 1 ; uint pset.max = 2)'

    теперь создадим пул:

    poolcfg -c 'create pool test'

    и свяжем процессорную группу с этим пулом:

    poolcfg -c 'associate pool test (pset small)'

    Теперь укажем, что пул test должен использовать планировщик задач по схеме долевого распределения:

    poolcfg -c 'modify pool test (string pool.scheduler = "FSS")'

    Что получилось?

    poolcfg -c info
    system default
    string system.comment
    int system.version 1
    boolean system.bind-default true
    string system.poold.objectives wt-load
    pool pool_default
    int pool.sys_id 0
    boolean pool.active true
    boolean pool.default true
    int pool.importance 1
    string pool.comment
    pset pset_default
    pool test
    boolean pool.active true
    boolean pool.default false
    string pool.scheduler FSS
    int pool.importance 1
    string pool.comment
    pset small
    pset pset_default
    int pset.sys_id -1
    boolean pset.default true
    uint pset.min 1
    uint pset.max 65536
    string pset.units population
    uint pset.load 160
    uint pset.size 2
    string pset.comment
    cpu
    int cpu.sys_id 1
    string cpu.comment
    string cpu.status on-line
    cpu
    int cpu.sys_id 0
    string cpu.comment
    string cpu.status on-line
    pset small
    int pset.sys_id -2
    boolean pset.default false
    uint pset.min 1
    uint pset.max 2
    string pset.units population
    uint pset.load 0
    uint pset.size 0
    string pset.comment

    Теперь назначим в пул test один процессор (таким образом, мы выделим пулу small один процессор, а второй останется в пуле pset_default ). Каждый процессор может относиться только к одному пулу ресурсов:

    poolcfg -dc "transfer to pset small (cpu 1)"

    Проверяем:

    # poolcfg -c info
    system default
    string system.comment
    int system.version 1
    boolean system.bind-default true
    string system.poold.objectives wt-load
    pool pool_default
    int pool.sys_id 0
    boolean pool.active true
    boolean pool.default true
    int pool.importance 1
    string pool.comment
    pset pset_default
    pool test
    boolean pool.active true
    boolean pool.default false
    string pool.scheduler FSS
    int pool.importance 1
    string pool.comment
    pset small
    pset pset_default
    int pset.sys_id -1
    boolean pset.default true
    uint pset.min 1
    uint pset.max 65536
    string pset.units population
    uint pset.load 160
    uint pset.size 1
    string pset.comment
    cpu
    int cpu.sys_id 0
    string cpu.comment
    string cpu.status on-line
    pset small
    int pset.sys_id -2
    boolean pset.default false
    uint pset.min 1
    uint pset.max 2
    string pset.units population
    uint pset.load 0
    uint pset.size 1
    string pset.comment
    cpu
    int cpu.sys_id 1
    string cpu.comment
    string cpu.status on-line

    Для записи динамически существующей в запущенной системе конфигурации пулов ресурсов в файл настроек надо выполнить команду

    pooladm -s имя_файла

    а для проверки корректности описания конфигурации пулов ресурсов команду

    pooladm -n имя_файла

    Если имя_файла не указано, подразумевается файл /etc/pooladm.conf

    Для активации уже записанных в файле настроек выполняется команда

    pooladm -c имя_файла

    Зоны и контейнеры

    Концепция управления ресурсами и распределения ресурсов между различными наборами приложений развивалась от проектов к зонам. Зоны – это логическое продолжение проектов. По сути дела, если проект – это совокупность процессов, которым могут выделяться некие ресурсы (в том числе и в монопольное распоряжение), то зона – это виртуальная копия системы, в которой запущен определенный набор служб. В отличие от проектов, зоны предоставляют высокий уровень изоляции приложений друг от друга: приложения из одной зоны никак не могут взаимодействовать с приложениями из другой зоны, за исключением обмена данными через сеть.

    Зона имеет свое файловое пространство, свой каталог /etc со своими настройками и, следовательно, свой список пользователей, своего администратора root, свой набор служб и так далее. Фактически, зона – это почти виртуальная машина, но значительное отличие зоны от VM – то, что все зоны используют одно и то же ядро.

    Зоны бывают двух типов: глобальная зона (она всегда одна – это тот экземпляр системы, который загружается при старте) и неглобальные зоны (это все остальные зоны).

    Смысл зон в том, что:

  • зона гарантирует идеальную изоляцию приложений – процессы одной зоны не влияют на процессы в других зонах;
  • зона обеспечивает изолированную среду не только для приложений, но и для системных служб внутри себя – в каждой зоне есть свои файлы настроек
  • Solaris позволяет настроить изолированную среду внутри зоны так, чтобы запускать в ней "неродные" приложения – исполняемые файлы Linux или приложения, ранее установленные в Solaris 8 (даже если это приложения были написаны третьими фирмами и содержат специфические несвязанные с Solaris компоненты).
  • Зону можно создать и настроить ее свойства командой zonecfg, управлять ею следует с помощью zoneadm.

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

    Файловая система неглобальной зоны может быть совершенно независимой от глобальной зоны (такие зоны называются зонами без унаследованных каталогов – whole root zone), а может содержать "унаследованные" каталоги, т.е. смонтированные из глобальной зоны в режиме "только для чтения". По умолчанию, каталоги /usr, /lib, /platform и /sbin являются унаследованными. Чем больше каталогов унаследует новая неглобальная зона, тем меньше места занимает ее собственная файловая система и тем меньше файлов в нее будет копироваться из глобальной зоны при создании.

    Клонирование зон на ZFS

    Быстрое клонирование зон может быть необходимо при создании большого количества зон одинаковой конфигурации. Для этой операции удобнее помещать клонируемую зону и все ее клоны в каталогах, расположенных в файловой системе ZFS, так как это значительно сэкономит время при копировании файлов. Клонирование зоны на UFS может занимать от 15 до 45 минут и более (в зависимости от количества установленных пакетов и производительности оборудования), а клонирование зоны на ZFS занимает около 8 секунд.

    Для успешного клонирования надо вначале настроить зону, которую вы будете клонировать:

    # zonecfg -z master
    master: No such zone configured
    Use 'create' to begin configuring a new zone.
    zonecfg:master> create
    zonecfg:master> set zonepath=/test/opt
    zonecfg:master> verify
    zonecfg:master> commit

    Теперь посмотрим на список зон в системе:

    # zoneadm list -vc
    ID NAME STATUS PATH BRAND IP
    0 global running / native shared
    - master configured /test/opt native shared

    Теперь выполним установку системы в зоне (фактически, копирование установленных пакетов из глобальной зоны в неглобальную):

    # zoneadm -z master install
    /test/opt must not be group readable.
    /test/opt must not be group executable.
    /test/opt must not be world readable.
    /test/opt must not be world executable.
    could not verify zonepath /test/opt because of the above errors.
    zoneadm: zone master failed to verify

    Ага! Ошибка в правах доступа к каталогу зоны. Исправляем:

    # ls -ld /test/opt
    drwxr-xr-x 2 root root 2 февр. 10 10:33 /test/opt
    # chmod go-rx /test/opt
    # ls -ld /test/opt
    drwx------ 2 root root 2 февр. 10 10:33 /test/opt

    Порядок. Устанавливаем зону:

    # zoneadm -z master install
    A ZFS file system has been created for this zone.
    Preparing to install zone <master>.
    Creating list of files to copy from the global zone.
    Copying <11008> files to the zone.
    Initializing zone product registry.
    Determining zone package initialization order.
    Preparing to initialize <1256> packages on the zone.
    Initialized <1256> packages on zone.
    Zone <master> is initialized.
    Inst allation of these packages generated errors: <openofficeorgdesktop-
    integratn>
    Installation of <1> packages was skipped.
    Installation of these packages generated warnings: <WebStackTooling>
    The file </test/opt/master/root/var/sadm/system/logs/install_log>
    contains a log of the zone installation.

    Теперь выполняем клонирование, для чего вначале создаем зону и настраиваем ее параметры:

    zonecfg -z clone create -t master

    Обратите внимание на то, что при клонировании мы указывам название зоны-образца (после ключа t ). Это делается потому, что без указания образца нам бы потребовалось сразу настроить обязательный параметр "место расположения зоны" ( zonepath ), а в командной строке при создании зоны этого не сделать. Теперь укажем этот параметр в следующей команде:

    zonecfg -z clone set zonepath=/test/opt/clone

    И клонируем зону:

    zoneadm -z clone clone master

    Обратите внимание: в командах zoneadm и zonecfg после ключа z всегда указывается та зона, которую мы в данный момент настраиваем или которой управляем.

    Настройка производительности системы

    Какая аппаратура быстрее?

    Естественно, для разных задач подходят разные компьютеры. Например, компьютеры с процессором Alpha обычно быстрее своих Intel-собратьев выполняют расчеты с числами с плавающей запятой. Это значит, что вычисления, связанные с расчетами координат, решением уравнений или моделированием молекул быстрее выполнит компьютер с процессором Alpha.

    В настоящее время процессоры Alpha широко используются в высокопроизводительных серверах от Hewlett-Packard и других, еще более специализированных системах, таких, как суперкомпьютеры Cray и Fujitsu.

    Если же речь идет о целочисленных вычислениях, пусть и достаточно громоздких, например, рендеринге, преобразовании графических объектов, 3D-визуализации, где координаты могут быть заданы только целыми числами, процессоры Intel отлично справятся с ними.

    Сейчас мы говорили о процессорах Alpha и Intel, но на деле разговор касается двух разных архитектур – RISC и CISC. Процессоры Intel традиционно тяготеют к последней, в то время как процессоры SPARC – к первой. ОС Solaris выпускается в версиях для обеих архитектур, хотя изначально компания Sun не выпускала версию Solaris для Intel, а многочисленные пользователи этой системы во всем мире до сих пор утверждают, что версия для SPARC более производительна и надежна. Это, в частности, связано с тем, что механизмы обеспечения многозадачности тесно связаны с используемой аппаратурой, и версия Solaris под Intel "подогнана" под архитектуру процессоров Intel и архитектуру аппаратных средств, разработанных для них.

    Впрочем, оставим эти утверждения на совести пользователей: если для версии Solaris 8 и более старых они еще были справедливы, то Solaris 10 на серверах с процессорами AMD и Intel решает задачи ничуть не хуже, чем на SPARC от Sun Microsystems.

    В заключение разговора о предпочтительности той или иной аппаратуры следует сказать, что:

  • для работы Solaris под серьезной нагрузкой, такой, как СУБД Oracle с тысячами клиентов и важностью высокой скорости реагирования, система на базе процессоров RISC, скорее всего, окажется более результативной;
  • независимо от используемой аппаратной платформы конфигурация компьютера должна быть хорошо согласована: быстрый процессор должен работать с быстрой оперативной памятью, а дисковая подсистема (контроллеры и диски) обязаны успевать без задержек отрабатывать команды чтения и записи. Недостаточный объем кэша любого уровня, как кэша процессора на кристалле, так и кэша дискового контроллера может привести к значительному снижению производительности.
  • Сравнение производительности систем разных платформ
    Процессор, частота SPECint2000 (base) SPECfp2000 (base) Система
    Alpha 21264C, 1.01 GHz 561 585 Compaq AlphaServer GS160
    Alpha 21264C, 1 GHz 621 776 Compaq AlphaServer ES45
    Alpha 21264B, 833 MHz 518 621 Compaq AlphaServer ES40
    Itanium, 800 MHz 379 701 HP rx4610
    Itanium, 800 MHz 358 655 HP i2000
    UltraSPARC III, 1.05 GHz 537 701 Sun Blade 2050
    UltraSPARC III, 900 MHz 470 629 Sun Blade 1000
    UltraSPARC III, 750 MHz 363 312 Sun Blade 1000
    Power4, 1.3 GHz 790 1098 IBM eServer 690
    Alpha 21364 EV-78+, 1.3 GHz 904 1279
    AMD Opteron 256, 3 GHz 1942 2260
    IBM Power5, 1,9 GHz 1398 2585
    Intel Pentium 965, 3,73 GHz 1870 2232
    Sun UnlraSPARC IV+, 1,8 GHz 1300 1800

    Оценка ситуации: программы надзора за системой

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

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

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

    Для оценки загрузки процессора и состояния памяти (достаточно ли оперативной памяти, не перегружена ли дисковая подсистема свопингом и т.п.) следует использовать программы top и sar. Конкретные примеры применения этих программ даны ниже, в разделе "эффективное использование памяти и свопинга". Программа top (в Solaris удобнее использовать prstat – местный аналог top ) выводит информацию о наиболее активных процессах, которые сильнее всего занимают процессор:

    top
    last pid: 501; load averages: 0.08, 0.34, 0.40 19:12:00
    59 processes: 58 sleeping, 1 on cpu
    CPU states: 96.2% idle, 0.8% user, 1.0% kernel, 2.0% iowait, 0.0% swap
    Memory: 128M real, 3596K free, 132M swap in use, 466M swap free
    PID USERNAME LWP PRI NICE SIZE RES STATE TIME CPU COMMAND
    345 root 1 59 0 24M 9972K sleep 0:11 1.14% Xsun
    470 root 4 49 0 128M 71M sleep 0:52 1.01% soffice.bin
    501 root 1 59 0 2228K 1336K cpu 0:00 0.55% top
    461 root 1 59 0 15M 3184K sleep 0:00 0.37% dtterm
    467 root 1 49 0 4708K 832K sleep 0:00 0.03% bash
    435 root 1 49 0 16M 1760K sleep 0:00 0.01% dtfile
    434 root 5 59 0 22M 6304K sleep 0:01 0.00% dtwm
    427 root 1 49 0 18M 0K sleep 0:00 0.00% dtsession
    436 root 1 59 0 14M 3292K sleep 0:00 0.00% sdtperfmeter
    265 root 26 59 0 5480K 1456K sleep 0:00 0.00% htt_server
    460 root 1 59 0 3064K 1372K sleep 0:00 0.00% dtexec
    315 root 1 59 0 6900K 1324K sleep 0:00 0.00% dtlogin
    411 root 1 59 0 3784K 1300K sleep 0:00 0.00% sdt_shell
    183 root 3 59 0 5832K 1188K sleep 0:00 0.00% automountd
    95 root 13 59 0 5660K 1100K sleep 0:00 0.00% syslogd

    Программа sar подобна vmstat и выдает статистику по работе системы, ее можно запустить для выдачи определенных параметров одномоментно или для периодического вывода сведений, например, для десятикратных измерений значений стандартного набора параметров с периодом 5 секунд:

    sar 5 10
    SunOS sunny 5.9 Generic_112234-03 i86pc 07/03/2004
    19:12:34 %usr %sys %wio %idle
    19:12:39 0 1 0 99
    19:12:44 0 0 0 100
    19:12:49 0 1 0 99
    19:12:54 4 1 0 95
    19:12:59 0 0 0 100
    19:13:04 0 1 0 99
    19:13:09 5 1 0 94
    19:13:14 1 24 66 8
    19:13:19 2 35 38 25
    19:13:24 3 20 17 60

    Решение проблем: изменение размеров разделов диска

    Если необходимо увеличить размер конкретного раздела, то есть два пути: физически изменить размер раздела или создать метаустройство, которое физически будет состоять из нескольких разделов на одном или нескольких дисках, но система будет его считать одним логическим разделом. Второй путь напоминает создание Volume Set в системах Windows NT и более новых.

    Отметим, что при использовании файловой системы ZFS в Solaris задачи расширения объема файловой системы решаются проще – добавлением нового устройства или раздела в пул; после этого все файловые системы, размещенные в этом пуле, могут пользоваться появившимся пространством. Ниже описанные процедуры более актуальны для использования более старой файловой системы UFS.

    Чтобы физически изменить размер раздела, надо, чтобы на диске вслед за этим разделом было свободное пространство, еще не отданное ни одному разделу. Если там есть какой-то другой раздел, то его придется удалить, предварительно сохранив нужные данные, которые в нем находятся. После этого потребуется выполнить резервное копирование всех данных увеличиваемого раздела в какой-то каталог другого раздела, удалить старый раздел, создать на его месте новый, больший, с помощью команды newfs, и затем восстановить файлы из резервной копии. Этот метод рекомендован для использования в любых системах UNIX. Однако, он требует значительных затрат времени и дискового (или ленточного, в зависимости от того, где вы создаете резервную копию) пространства.

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

    Синтаксис команды growfs:

    /usr/sbin/growfs [-M точка_монтирования] [параметры_newfs] [rawdevice]

    Аргументы команды growfs обозначают:

  • точка_монтирования – точка монтирования файловой системы, которую требуется расширить. При этом на время расширения произойдет блокировка файловой системы функцией lockfs() ;
  • параметры_newfs – те же параметры, которые может принимать программа newfs при создании новой файловой системы, см. описание newfs.;
  • rawdevice – имя файла прямого доступа для метаустройства в каталоге /dev/md/rdsk.
  • Команда growfs увеличивает размер файловой системы до размера указанного раздела.

    Увеличение размера раздела выполняется посредством добавления нового раздела к метаустройству и последущего запуска growfs. При увеличении размера зеркала (т.е. уже существующего метаустройства с реализованным зеркалированием, или, иначе говоря, с RAID уровня 1) следует вначале увеличить каждую из частей зеркала с помощью metaattach, как показано ниже, а затем – всю файловую систему с помощью growfs.

    Особым случаем является расширение журналируемого метаустройства (trans metadevice), которое состоит из двух устройств – главного и журналирующего. Увеличивается только размер главного устройства, а затем growfs "напускается" на само журналируемое метаустройство. Вообще говоря, можно увеличить и размер журналирующего устройства, но это не обязательно.

    Програма growfs на время модификации файловой системы блокирует запись в нее. Можно сократить время блокировки файловой системы, выполняя ее увеличение по частям. Например, мы хотим увеличить файловую систему размером 2 Гбайта до размера 8 Гбайт. Можно это делать поэтапно, добавляя по 16 Мбайт за этап, дав ключ s для явного указания размера общего размера новой файловой системы на каждом этапе. Число, следующее за ключом s, интерпретируется как общее число секторов новой файловой системы на каждом этапе и должно быть кратно размеру цилиндра в секторах. Иначе говоря, файловая система должна содержать целое число цилиндров.

    Подробнее об ограничениях, связанных с размером разделов, рассказано в руководстве по newfs и growfs.

    Представим себе, что требуется увеличить размер раздела /dev/dsk/c1t0d0s3, на котором расположена файловая система /export. Для этого нам потребуется вначале преобразовать этот раздел в метаустройство, поскольку добавлять дополнительное пространство можно только к метаустройству. Допустим, добавлять к существующему мы будем пока еще пустой, не содержащий файловой системы раздел /dev/dsk/c2t0d0s3:

    metainit -f d8 2 1 c1t0d0s3 1 c2t0d0s3

    Эта команда вызывает объединение разделов /dev/dsk/c1t0d0s3 и /dev/dsk/c2t0d0s3 в новое метаустройство d8. Теперь изменяем /etc/vfstab так, чтобы файловая система /export монтировалась на метаустройство d8:

    #device device mount FS fsck mount mount
    #to mount to fsck point type pass at boot options
    /dev/md/dsk/d8 /dev/md/dsk/d8 /export ufs 2 yes -

    Демонтируем /export и снова монтируем его (при монтировании будет использовано новое устройство из /etc/vfstab ):

    umount /export
    mount /export

    Запускаем growfs для расширения файловой системы на новый раздел:

    growfs -M /export /dev/md/rdsk/d8

    Ключ M нужен программе growfs для того, чтобы можно было увеличить размер смонтированной файловой системы. В процессе изменения размера запись в файловую систему блокируется программой growfs.

    Файл /etc/lvm/md.tab содержит таблицу метаустройств, которая служит файлом настроек для запуска программы metainit при старте системы.

    Ограничения при работе с growfs

    С помощью growfs можно расширять только файловые системы UFS (не важно, смонтированные или несмонтированные). Единожды расширенная файловая система не может быть уменьшена. Расширение файловой системы невозможно, если:

  • на задействованном в ней устройстве находится файл учета запущенной системы acct, или
  • включена система безопасности на уровне C2 и файл журналирования находится на расширяемом устройстве, или
  • на ней находится локальный файл свопинга, или
  • эта файловая система монтируется в каталог /usr или корневой каталог или является активным разделом свопинга.
  • Увеличение производительности дисковой подсистемы

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

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

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

    Приложение может вызвать функцию fsync() для принудительного сбрасывания данных из файлового кэша на диск. Кроме этого, к такому же результату приводит закрытие файла, используемого процессом. При завершении процесса все связанные с ним файлы закрываются, что вызывает немедленную запись всех еще не записанных в эти файлы данных из кэша на диск. Поэтому при одновременном завершении большого количества процессов дисковая активность может резко возрасти. Такое явление наблюдается, например, при завершении работы демона squid, кэширующего http-запросы.

    Вторая причина дисковой активности, свопинг или пейджинг, зависит от того, как объем памяти в системе соответствует реальным потребностям приложений. Настройку системы с целью оптимизации свопинга мы рассмотрим ниже в разделе "эффективное использование памяти и свопинга", а сейчас обратимся к оптимизации операций записи и чтения данных.

    Снижение частоты синхронизации файлового кэша с диском

    При частых и объемных операциях с файлами файловый кэш быстро заполняет значительный объем памяти. В системах Solaris до версии 8 он даже конкурировал с процессами за оперативную память. Процесс fsflush регулярно (по умолчанию – раз в 30 секунд) "сбрасывает" на диск содержимое кэша, обеспечивая таким образом синхронизацию кэша и файловой системы. Если количество открытых файлов велико, эта синхронизация может приводить и к потерям времени, и к чересчур высокой загрузке дисковой подсистемы.

    Демон fsflush руководствуется значением двух переменных, autoup и tune_t_fsflushr, – значение им можно присвоить в файле /etc/system.

    Для систем с большим объемом памяти установленное по умолчанию значение в 30 с делает процесс fsflush чересчур дорогостоящим. Для того. чтобы поубавить аппетит fsflush, время цикла синхронизации следует увеличить, изменив в бОльшую сторону значение autoup. Поскольку fsflush оказывает влияние на всю систему, лучше всего, чтобы он работал в течение более коротких промежутков времени. Для этого значение tune_t_fsflushr (время, отведенное fsflush на синхронизацию) должно быть меньше: отведя демону меньшее число секунд, вы заставите его выполнять в пять раз меньшее по объему сканирование.

    Приостановка записи (write throttle) в файловой системе UFS

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

    Переменная ядра ufs:ufs_WRITES отвечает за включение механизма write throttling (приостановки записи в файл). Если эта переменная равна 1, то приостановка записи разрешена. По умолчанию это именно так.

    Приостановка означает, что когда объем данных, ожидающих записи в один файл, превышает верхний предел ufs:ufs_HW, запись в этот файл блокируется до момента, пока объем данных в буфере не снизится до ufs:ufs_HW. Соответственно, пока запись в файл блокирована, пополнение буфера не осуществляется, зато данные из буфера записываются на диск, за счет чего буфер освобождается.

    Настройка этих параметров ядра может понадобиться, если количество приостановок постоянно растет. Это можно заметить, изучив с помощью отладчика счетчик ядра ufs_throttles. Его значение увеличивается на единицу при каждой приостановке записи, и постоянное увеличение этого значения говорит о том, что пределы ufs:ufs_HWufs:ufs_HW следует увеличить.

    Такое увеличение вполне допустимо и даже полезно при использовании метаустройств с расщеплением (striping metadevices), когда данные одного файла поблочно пишутся на несколько устройств одновременно (первый блок – на первый диск, следующий – на второй и т.д.), так как совокупная пропускная способность метаустройства выше, чем у одного физического диска. То же относится и к массивам RAID. Значения ufs:ufs_HWufs:ufs_HW не должны быть слишком близкими и не должны очень сильно отличаться. Если они слишком близки, то приостановки записи будут случаться слишком часто: едва объем буфера окажется у нижнего предела и запись будет разрешена, как сразу буфер и превысит верхний предел и запись приостановится. Большая разница между значениями приведет к тому, что запись в файл будет заблокирована при превышении верхнего предела и после этого пройдет значительное время до разблокировки записи, так как буфер не может быть мгновенно "сброшен" на диск и до достижения нижнего предела придется ждать относительно долго.

    Рекомендуется нижний предел устанавливать равным 1/32 объема оперативной памяти, а верхний – 1/16 этого объема.

    Приостановка записи производится на пофайловой основе, т.е. блокировка записи в один файл, буфер которого заполнен более чем ufs:ufs_HW байтами, не влияет на запись в другие файлы.

    Кэш поиска имен каталогов (DNLC)

    Чтобы не искать номер индексного дескриптора по имени файла каждый раз, когда к файлу происходит обращение, система кэширует имена файлов и каталогов вместе с номерами их виртуальных индексных дескрипторов. Этот специальный кэш называется кэш поиска имен каталогов (directory name lookup cache – DNLC).

    При открытии файла DNLC вычисляет соответствующий индексный дескриптор по имени этого файла. Если имя уже находится в кэше, то оно будет найдено очень быстро, поскольку не происходит сканирования каталогов на диске. Каждая запись DNLC в прежнем имела фиксированный размер, поэтому пространство для имени файла не могло превышать 30 символов, а более длинные имена файлов не кэшировались. Начиная с Solaris 7 это ограничение снято. Если в каталоге несколько тысяч записей, поиск номера индексного дескриптора конкретного файла среди них отнимет много времени. Если в системе открыто много файлов, а количество файлов в рабочих каталогах велико, то высокая частота успешных обращений к DNLC очень важна.

    Кэш имен каталогов не нуждается в настройке, хотя его размер зависит от значения maxusers. По умолчанию он определяется как (17xmaxusers)+90 (в Solaris 2.5.1) или 4x(maxusers + max_nprocs)+320 (в Solaris 2.6 и выше). Другие параметры, на которые тоже оказывает влияние maxusers, обсуждены в лекции 1.

    Команда

    vmstat –s

    показывает частоту успешных попаданий в DNLC с момента начала работы системы.

    Если частота промахов велика (попаданий обычно не должно быть меньше 90%), следует подумать об увеличении размера DNLC. Проверим этот показатель работы системы командой

    vmstat -s |grep 'name lookups'
    422920 total name lookups (cache hits 99%)

    Количество запросов к DNLC в секунду можно получить из поля namei/s в выводе команды sar –a:

    sar -a 1 5
    SunOS sunny 5.9 Generic_112234-03 i86pc 07/03/2004
    19:26:50 iget/s namei/s dirbk/s
    19:26:51 0 1 0
    19:26:52 0 0 0
    19:26:53 0 0 0
    19:26:54 0 4 0
    19:26:55 0 0 0

    Как видно, система не очень-то загружена запросами к файлам и отдыхает. А теперь запустим операцию, которая точно требует многократного обращения к DNLC:

    find / -name "top" 
    [1] 577
    sar -a 1 5
    SunOS sunny 5.9 Generic_112234-03 i86pc 07/03/2004
    19:27:14 iget/s namei/s dirbk/s
    19:27:15 1675 2592 1922
    19:27:16 1220 2365 1474
    19:27:17 968 1882 1172
    19:27:18 1057 2107 1292
    19:27:19 1231 2211 1443
    vmstat -s |grep 'name lookups'
    503370 total name lookups (cache hits 86%)

    При интенсивных файловых операциях и доступе ко многим каталогам одновременно эффективность кэша имен каталогов снижается, но по-прежнему остается достаточно высокой.

    Индексные дескрипторы

    При создании файловой системы для индексных дескрипторов выделяется отдельное пространство на разделе. Индексные дескрипторы хранят свойства файла, в том числе теневые индексные дескрипторы – расширенные права доступа. Количество индексных дескрипторов – это неизменяемая величина. Отсутствие свободных индексных дескрипторов в файловой системе приводит к невозможности записывать файлы в те каталоги, которые расположены в этой файловой системе. Количество свободных индексных дескрипторов можно определить, проанализировав вывод команды df –e:

    df -e
    Filesystem ifree
    /proc 862
    /dev/dsk/c0t0d0s0 294838
    fd 0
    /dev/dsk/c0t0d0s4 246965
    swap 9796
    /dev/dsk/c1t0d0s0 3256077

    Количество одновременно записываемых блоков

    Так как размер кластера файловой системы, как правило, составляет 8 Кб, драйвер файловой системы при записи собирает данные в блоки по 8Кб для большей эффективности использования дискового пространства. При записи сравнительно больших файлов драйвер файловой системы группирует вместе несколько блоков для того, чтобы вместо серии мелких операций ввода-вывода выполнить одну, большую по объему операцию. Количество группируемых блоков равно параметру файловой системы maxcontig. В версиях, предшествующих Solaris 8, этот параметр по умолчанию был равен семи, и, таким образом, операция ввода-вывода происходила одновременно с семью последовательными блоками, и позволяла одновременно записать порцию данных размером 56 KB. Такое значение по умолчанию связано с ограничениями конструкции в раннем оборудовании Sun: системы, основанные на архитектуре sun4, не способны передавать за одну операцию более 64 KB. В архитектурах sun4c, sun4m, sun4d и sun4u таких ограничений нет. В Solaris 8 значение по умолчанию изменилось и составляет 16 блоков (128 Kb).

    Изменение параметра maxcontig может серьезно повлиять на производительность файловой системы, при работе с которой преобладают последовательные операции по записи средних и больших (более нескольких десятков килобайт) файлов на диск. Если при доступе к файловой системе большинство операций ввода-вывода совершается с данными малого размера, то изменение maxcontig не принесет большой пользы.

    Размер кластера файловой системы задается с помощью ключа –С blocks команды newfs при создании файловой системы. Для существующей файловой системы его можно изменить с помощью ключа –a команды tunefs.

    Настройка maxcontig дает наилучший результат, если ее выполнить при создании файловой системы, так как это фактически определит размер кластера файловой системы. При выполнении настройки уже используемой файловой системы столь же впечатляющего результата не будет: при такой настройке блоки, которые уже были записаны, не будут перекомпонованы.

    Настройка параметров файловой системы

    Чтобы оценить загрузку файловых систем, имеет смысл запустить команду

    iostat -x 5

    в тот момент, когда интенсивность ввода-вывода будет наиболее близка к обычному (или пиковому, в зависимости от того, как вы хотите настроить файловую системы) уровню:

    ...
    device r/s w/s kr/s kw/s wait actv svc_t %w %b
    cmdk0 17.6 2.9 138.4 53.1 1.1 0.2 60.1 3 13
    fd0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0
    sd0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0
    nfs1 0.0 0.0 0.0 0.0 0.0 0.0 9.3 0 0
    extended device statistics
    device r/s w/s kr/s kw/s wait actv svc_t %w %b
    cmdk0 307.7 0.2 766.1 2.0 0.0 0.9 2.9 0 89
    fd0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0
    sd0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0
    nfs1 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0
    extended device statistics
    device r/s w/s kr/s kw/s wait actv svc_t %w %b
    cmdk0 253.4 0.7 768.0 6.0 0.0 0.9 3.6 0 88
    fd0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0
    sd0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0
    nfs1 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0
    ...

    Средние значения загрузки можно получить из колонок kr/s и kw/s, в более ранних версиях системы для получения таких значений приходилось делить содержимое колонок "K/r" и "K/w" на "r/s" и "w/s" соответственно для получения средних показателей "прочитано килобайт в секунду" и "записано килобайт в секунду".

    Для получения информации о распределении файлов по размеру можно использовать команду:

    quot -c file_system

    Например, вот каково распределение в моей тестовой системе:

    quot -c /export/home
    ...
    1128 1 165156
    1136 1 166292
    1160 1 167452
    1176 1 168628
    1184 1 169812
    1192 1 171004
    1224 1 172228
    1232 1 173460
    1240 1 174700
    1264 1 175964
    1360 1 177324
    1376 1 178700
    1440 1 180140
    1488 1 181628
    1536 1 183164
    1608 1 184772
    1648 1 186420
    1704 1 188124
    1768 1 189892
    1792 1 191684
    1832 1 193516
    2047 40 437396
    ...

    Первая колонка вывода – это размер файла в блоках, вторая – число файлов такого размера, третья – общее число блоков, занятых файлами такого размера и меньшими.

    Эффективное использование памяти и свопинга

    Вопрос об установке в систему дополнительной оперативной памяти представляет собой классический вопрос выбора между ценой и производительностью. Если цена важнее производительности, то при нехватке памяти увеличивают размер раздела свопинга, если важнее производительность, увеличивают объем оперативной памяти. Если же нет возможности сделать ни то, ни другое, новые процессы не смогут быть запущены при нехватке виртуальной памяти (ее можно заметить по сообщениям "Not enough space" или "WARNING: /tmp: File system full, swap space limit exceeded").

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

    Индикаторами нехватки памяти в системе являются активность сканирования страниц на предмет пометки для выгрузки и активная работа устройства, на котором расположен swap-раздел.

    В обоих случаях высокая активность может быть временной или постоянной. В любом случае, имеет смысл уяснить ее причину.

    Частота сканирования страниц

    Повышенная частота сканирования страниц ( scan rate ) – главный показатель того, что в системе перестало хватать оперативной памяти. Для просмотра значения scan rate используйте команды

    sar –g

    или

    vmstat

    При анализе частоты сканирования с помощью vmstat имеет смысл запустить эту программу с параметром 60 для получения статистики каждые 60 секунд:

    vmstat 60
    kthr memory page disk faults cpu
    r b w swap free re mf pi po fr de sr cd f0 s0 -- in sy cs us sy id
    0 0 0 482100 7288 23 63 126 31 46 8 54 28 0 0 0 333 1519 327 5 11 84
    0 1 0 470816 2060 0 26 1 51 103 0 123 240 0 0 0 960 969 649 4 92 4
    ...

    Первую строку (суммарную статистику) можно игнорировать. Если показатель page/sr остается выше 200 страниц в секунду в течение длительного времени, это говорит о вероятной нехватке оперативной памяти в системе.

    Постоянно низкое значение частоты сканирования страниц говорит о том, что системе хватает памяти. С другой стороны, высокое значение может быть вызвано активностью процесса (или нескольких процессов одновременно), читающих данные с диска или получающих их через сеть – эти данные не только кэшируются операционной системой, но и занимают место в памяти процессов, поэтому запросто могут вызвать активный пейджинг. Такоим образом, не следует слепо полагаться на обсуждаемые рекомендации и считать 200 страниц в секунду абсолютной догмой индикации нехватки памяти: действуйте по ситуации, смотрите, какие процессы в действительности запущены и насколько они требовательны к памяти.

    Активность свопинга

    Если устройство, на котором находится область свопинга, загружено вводом-выводом, это говорит о нехватке памяти. Можно оценить дисковую активность с помощью программы iostat.

    Для Solaris 2.6 и выше следует использовать команду

    iostat -xPnce

    для получения информации об активночти передачи данных в/из конкретных разделов дисков, в Solaris 2.5.1 доступна команда

    iostat -xc

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

    Можно также использовать

    sar –d

    или

    vmstat

    Длинная очередь страниц для выгрузки свидетельствует о необходимости нарастить оперативную память в системе.

    Использование памяти процессами

    В системах Solaris, начиная с версии 2.6, есть возможность выяснить, какие программы сколько памяти занимают (и подробнее – размеры сегментов данных, кода и т.п.) с помощью программы pmap. Для получения детальной информации дайте команду

    /usr/proc/bin/pmap –x PID

    Информация о размере процесса в памяти также содержится в колонке RSS вывода программ top и ps (используйте ps –ly ).

    В пакете SunPro есть отладчик dbx, который помогает находить источник утечки памяти в программе; для такой работы следует компилировать программу компилятором SunPro с ключом –g.

    Статистику использования разделяемой памяти вы получите по команде

    ipcs -mb

    Эти программы следует использовать для определения размера процессов и основных потребителей памяти в системе.

    Размер пространства свопинга

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

    Для управления пространством свопинга (получения информации о нем, добавления и удаления разделов свопинга) применяется программа swap. Для получения информации о текущем состоянии пространства свопинга используйте swap –l.

    Для выяснения общего объема виртуальной памяти, который включает объем оперативной памяти и пространства свопнига вместе, следует запустить swap –s или sar –r.

    Если своп-раздел смонтирован в /tmp как файловая система типа tmpfs, команда

    df -k /tmp

    покажет общий объем свободной виртуальной памяти, включая оперативную память.

    Алгоритм пейджинга

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

    Параметры ядра и пейджинг

  • physmem: общее количество страниц в оперативной памяти.
  • lotsfree: сканер страниц начинает работать, когда количество свободной оперативной памяти становится меньше lotsfree. Значение по умолчанию – physmem/64, но может быть изменено в /etc/system. Сканер страниц по умолчанию запускается в режиме пейджинга. Частота сканирования ( scan rate, столбик sr в выводе vmstat ) устанавливается равной параметру slowscan, который по умолчанию равен fastscan/10.
  • minfree: пока объем свободной памяти находится между lotsfree и minfree, частота сканирования страниц растет линейно от slowscan к fastscan по мере уменьшения свободной памяти (рис. 6.2). Значение minfree по умолчанию – desfree/2, значение fastscan по умолчанию – physmem/4. Если свободной памяти становится меньше, чем desfree (что по умолчанию равно lotsfree/2 ), сканер страниц начинает запускаться 100 раз в секунду.

    Каждый свой запуск сканер страниц проверяет desscan страниц. Этот параметр изменяется динамически вместе с частотой сканирования.

  • maxpgio: этот параметр (в зависимости от конкретной аппаратуры – 40 или 60) по умолчанию ограничивает частоту ввода-вывода на устройство пейджинга. Для современных дисков с частотой вращения больше 7200 оборотов в минуту можно установить значение maxpgio в сто раз больше количества жестких дисков, задействованных в свопинге.
  • throttlefree: когда свободной оперативной памяти становится меньше throttlefree (по умолчанию этот параметр равен minfree ), запросы процессов на выделение им новых страниц памяти переводятся в состояние ожидания, до тех пор, пока не появится свободных страниц.
  • cachefree: имеет значение в для систем Solaris 7 (или систем 2.5.1 и 2.6 с установленными самыми свежими обновлениями); если в этих системах параметр priority_paging установлен равным 1 (т.е. priority paging включен), то пока свободной памяти больше, чем lotsfree, освобождаются только страницы файлового кэша в памяти, а страницы процессов не затрагиваются. Значение по умолчанию – удвоенное lotsfree. Системы Solaris более поздних версий, начиная с 8, имеют другой алгоритм освобождения оперативной памяти, и в них НЕ следует включать priority paging и устанавливать значение cachefree.
  • (рис 6.2) Зависимость частоты запуска сканера страниц от объема свободной памяти

    В системах Solaris до версии 7 включительно сканер страниц работает так: для выбранных сканером страниц обнуляется флаг "используемости" страницы, выбор страниц происходит со скоростью, которую можно посмотреть с помощью vmstat или sar –g (scan rate). После обработки handspreadpages страниц, сканер проверяет, установлен ли флаг "используемости". Фактически, сканер состоит из двух процессов, один из которых идет по памяти и очищает флаги встреченных страниц, а второй следует за ним на некотором расстоянии и проверяет, не было ли новых обращений к этой странице (не установился ли снова этот флаг). Если флаг не установлен снова (обращений к странице за то время, пока сканер отмечал handspreadpages страниц, не произошло), то страница отправляется в своп. Параметр handspreadpages по умолчанию равен physmem/4.

    В системах Solaris 8 и более новых алгоритм освобождения памяти иной (он называется cyclical page cache ). Он рассчитан на то, что при нехватке памяти выгружаются прежде всего страницы файлового кэша, и только затем – страницы процессов. Этот алгоритм разработан для тех же целей, что и priority paging в Solaris 7. Новый алгоритм использует два списка свободных страниц. Один – для помещения в него страниц файлового кэша, которые освобождаются, другой – для помещения в него прочих освобождающихся страниц (разделяемой памяти, процессов и т.п.). При таком подходе файловый кэш не соперничает ни с кем, кроме самого себя, за место в памяти.

    В результате этих изменений, в системах Solaris, начиная с версии 8, vmstat сообщает иные цифры, чем в той же ситуации в более старых системах, а именно:

  • скорость возврата страниц выше;
  • весь файловый кэш показывается как свободная память;
  • скорость сканирования страниц ( scan rate ) низкая (даже близка к нулю), за исключением ситуаций, когда в системе действительно сильно не хватает памяти приложениям.
  • Для получения отдельного отчета по пейджингу страниц приложений ( executables ), данных ( anonymous ) и файловой системы используйте команду.

    vmstat -p

    Свопинг

    Если системе в течение некоторого времени (обычно – 30 секунд подряд) не хватает памяти (объем свободной оперативной памяти падает ниже desfree ), то начинается свопинг процессов. Планировщик задач выгружает те процессы, которые не претендовали на процессорное время в течение более чем maxslp секунд. По умолчанию maxslp равно 20. Этот режим свопинга называется мягким.

    Если дело дошло до того, что памяти меньше, чем desfree, и, кроме того, два и более процессов выстроились в очередь к процессору, а активность пейджинга превышает maxpgio, начинается жесткий свопинг. Это означает, что ядро выгружает модули и страницы кэша, а затем начинает последовательно выгружать процессы до тех пор, пока объем свободной памяти не станет больше desfree.

    Не выгружаются процессы:

  • классов планирования SYS и RT ;
  • запускаемые в данный момент или остановленные по сигналу (например, при отладке);
  • завершающие работу;
  • находящиеся в состоянии зомби;
  • системные потоки;
  • процессы, которые блокируют другие, более высокоприоритетные потоки.
  • Ввод-вывод без кэша

    Значительный объем чтения и записи данных может вызвать нехватку памяти из-за стремления системы кэшировать весь ввод-вывод. При действительно существенных объемах ввода-вывода можно отменить кэширование и производить ввод-вывод напрямую.

    Для этого можно использовать функцию directio() или параметр forcedirectio при монтировании файловой системы командой mount.

    Файловая система VxFS включает ввод-вывод в обход кэша всегда, когда объем операции ввода-вывода превышает значение параметра discovered_direct_iosz (см. man vxtunefs ) (по умолчанию – 256KB).

    Если в вашей системе преобладают множественные операции ввода-вывода небольших объемов данных и даже VxFS не помогает освободить память от большого количества кэшируемых данных, попробуйте уменьшить до приемлемого размера значение discovered_direct_iosz.

    Страницы:

    В Solaris применяется весьма серьезная и многоуровневая схема управления ресурсами. Именно поэтому Solaris имеет репутацию самой масштабируемой системы. В этой лекции мы обсудим базовые примитивы управления ресурсами и практику этого управления.

    Процессы, задачи и проекты

    Прежде всего, надо признаться, что в Solaris процессы группируются в задачи, а задачи, в свою очередь, в проекты (рис. 6.1). В проекте может быть одна задача, и задача может состоять из единственного процесса. Проект является единицей назначения ресурсов (которые будут обсуждаться ниже, в разделе "Пулы ресурсов"), и поэтому количество задач в проекте и общее количество проектов определяется реальной необходимостью распределения разнородных ресурсов между процессами.

    (рис 6.1) Процессы, задачи (task) и проекты (project

    После установки в системе уже определены несколько проектов. По умолчанию они перечислены в файле /etc/project и сразу после установки системы он выглядит так:

    # cat /etc/project
    system:0::::
    user.root:1::::
    noproject:2::::
    default:3::::
    group.staff:10::::

    Некоторые пользователи уже отнесены к определенному проекту; в нашем случае этой чести удостоены только пользователь root (запись user.root) и все, для кого группа staff (group.staff) является главной. Все остальные при входе в систему ассоциируются только с проектом default. Для проекта могут быть назначены какие-либо специфические ресурсы, но это не обязательно.

    Концепция проектов придумана для управления большими группами процессов, и объединять процессы в такие группы можно по разным признакам.

    При входе в систему любого пользователя создается задача (состоящая как минимум из командного процессора), ей назначается проект, и все задачи, порождаемые в рамках этой сессии, относятся к к этому проекту. Порядок назначения проекта при входе пользователя в систему таков:

  • просматривается файл /etc/user_attr (он содержит атрибуты пользователей), и если этот пользователь в нем присутствует, то проектом по умолчанию для данного пользователя назначается проект, объявленный для него в этом файле в параметре project ;
  • просматривается файл /etc/project, и если в нем указан проект для user.username, то проектом по умолчанию для данного пользователя назначается этот проект;
  • просматривается файл /etc/project, и если в нем объявлен проект для group.groupname, то система назначает этот проект данному пользователю проектом по умолчанию, если эта указанная группа является главной для данного пользователя;
  • если в файле /etc/project есть проект с именем default, то он назначается проектом по умолчанию для всех пользователей.
  • Если в файле /etc/project есть какой-либо проект, в поле "пользователи" которого указан данный пользователь, это означает, что данному пользователю разрешается присоединяться к данному проекту (например, с помощью указания имени этого проекта программе newtask ):

    newtask -p user.brad bash

    Можно посмотреть, процессы каких проектов запущены в системе, и оценить суммарную загрузку по процессам каждого проекта.

    # prstat -J
    PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/NLWP
    1669 filip 161M 42M cpu0 59 0 0:03:05 4,7% rhythmbox/9
    1757 filip 239M 104M run 59 0 0:17:57 1,3% firefox-bin/7
    691 filip 216M 193M sleep 59 0 0:15:57 1,2% Xorg/1
    1828 filip 279M 143M sleep 59 0 0:04:01 1,0% soffice.bin/6
    2063 root 7424K 3552K cpu1 59 0 0:00:00 0,5% prstat/1
    992 filip 124M 26M sleep 49 0 0:00:21 0,2% gnome-terminal/2
    903 filip 76M 17M sleep 59 0 0:00:33 0,1% metacity/1
    925 filip 135M 16M sleep 59 0 0:00:50 0,0% wnck-applet/1
    777 noaccess 78M 53M sleep 59 0 0:00:59 0,0% java/24
    937 filip 138M 19M sleep 59 0 0:00:31 0,0% mixer_applet2/1
    434 root 6868K 5196K sleep 59 0 0:00:48 0,0% hald-addon-acpi/1
    1019 mysql 52M 17M sleep 59 0 0:00:24 0,0% mysqld/10
    911 filip 163M 49M sleep 49 0 0:00:16 0,0% nautilus/1
    892 filip 73M 12M sleep 59 0 0:00:06 0,0% iiim-panel/1
    789 filip 2992K 1544K sleep 59 0 0:00:00 0,0% dbus-daemon/1
    PROJID NPROC SWAP RSS MEMORY TIME CPU PROJECT
    3 46 586M 852M 56% 0:49:07 8,6% default
    1 3 3252K 9500K 0,6% 0:00:00 0,5% user.root
    0 44 27M 121M 7,9% 0:02:11 0,1% system
    Total: 93 processes, 296 lwps, load averages: 0,22, 0,15, 0,09

    Естественно, что список проектов может быть размещен не только в файле /etc/project, но и в других источниках – каталогах NIS, LDAP или иных. Главное – корректно указать источник для поиска описаний проектов в /etc/nsswitch.conf.

    Записи файла /etc/project имеют следующий синтаксис:

    projname:projid:comment:user-list:group-list:attributes

    где

  • projname – имя проекта;
  • projid – уникальный идентификатор проекта;
  • comment – описание проекта;
  • user-list – список пользователей, использующих данный проект;
  • group-list – список групп пользователей, использующих данный проект;
  • attributes – параметры, определяющие возможность использования ресурсов.
  • Все поля, кроме projname и projid, являются необязательными:

    system:0::::
    user.root:1::::
    noproject:2::::
    default:3::::
    group.staff:10::::
    user.brad:150:A project for user brad:brad::project.max-lwps=(priv,20,deny)

    Задачи создаются при следующих действиях/командах:

  • login
  • cron
  • su
  • newtask
  • setproject
  • С помощью команд id и ps можно определить, с какими проектами пользователь связан:

    id -p
    uid=0(root) gid=0(root) projid=1(user.root)
    ps -o user,pid,uid,projid
    USER PID UID PROJID
    root 1242 0 1
    root 2935 0 1

    Создадим новый проект foopro c идентификатором 150 для пользователя brad:

    # projadd -U brad -p 150 foopro

    Добавим описание проекта foopro:

    # projmod -c "A project for user brad" foopro
    # cat /etc/project
    system:0::::
    user.root:1::::
    noproject:2::::
    default:3::::
    group.staff:10::::
    foopro:150:A project for user brad:brad::
    # su - brad
    Sun Microsystems Inc. SunOS 5.11 snv_79a January 2008
    $ projects
    default foopro

    Однако этой операцией мы лишь разрешили пользователю brad присоединяться к проекту foopro. Если же мы хотим, чтобы проект foopro был проектом по умолчанию для пользователя brad, надо либо изменить соответственно строку описания пользователя brad в /etc/user.attr, либо переименовать проект foopro в user.brad. В примере ниже мы также наложили ограничение на максимальное количество одновременно запускаемых пользователем потоков исполнения. В ограничении priv означает тип ограничения (priviliged, может быть изменено только администратором), а deny (запретить) – действие, которое следует выполнить при превышении заданного лимита.

    system:0::::
    user.root:1::::
    noproject:2::::
    default:3::::
    group.staff:10::::
    user.brad:150:A project for user brad:brad::project.max-lwps=(
    priv,20,deny)

    Пулы ресурсов

    Пул ресурсов следует отличать от пула ZFS – это совершенно разные понятия. Ресурсами в пуле могут быть процессоры и память. В Solaris 10 до Solaris 10 update 4 (он же – Solaris 10 08/07) включительно в качестве ресурсов в пул можно было включать допускались только процессоры, в Solaris Express (по крайней мере в версии SXDE 09/07 и SXDE 01/08) допустимо включать и оперативную память.

    Применять пулы для управления ресурсами удобно в ряде случаев, а именно:

  • для разделения системы на пользовательскую и системную часть и назначение для них ресурсов по-отдельности;
  • для разделения ресурсов сервера между несколькими критически важными задачами, когда следует гарантировать некий минимальный объем ресурсов для каждой из них;
  • для работы приложений реального времени;
  • для выделения конкретным пользователям гарантированные ресурсы;
  • Для того, чтобы назначить пул ресурсов проекту, следует установить соответствующий атрибут project.pool в файле /etc/project либо выполнить команду:

    # projmod -s -K project.pool=pool_name project_name

    Каждый проект может быть ассоциирован только с одним пулом.

    Для настройки пулов применяется статическая таблица параметров /etc/pooladm.conf. По умолчанию в Solaris функциональность пулов выключена, и этого файла нет. При включении механизма пулов этот файл допустимо создать с параметрами, установленными "по умолчанию". Если при старте операционная система обнаруживает этот файл, то она автоматически включает механизм пулов. Таблица параметров в этом файле хранится в формате XML и не предназначена для редактирования. Для изменения параметров следует применять команду poolcfg.

    Вы можете использовать различные таблицы параметров для разного времени суток, выполняя скрипты, содержащие poolcfg с помощью cron(1M).

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

    Прежде всего, для управления ресурсами посредством формирования пулов надо разрешить системе использовать класс планирования FSS по умолчанию (fair share scheduling – долевое распределение ресурсов).

    Для этого следует дать команду

    dispadmin -d FSS

    Теперь следует позаботиться о создании нового пула ресурсов и его настройке. Для разрешения функциональности пулов ресурсов следует использовать команду pooladm, а для создания пула и изменения его настроек – команду poolcfg.

    Создадим новый пул ресурсов, состоящий из одного-единственного процессора (этот пример проверен на компьютере с двухъядерным процессором AMD, и каждое ядро система видит как отдельный процессор):

    pooladm -e # разрешить пулы ресурсов в системе
    pooladm # показать определенные на данный момент пулы ресурсов
    system default
    string system.comment
    int system.version 1
    boolean system.bind-default true
    string system.poold.objectives wt-load
    pool pool_default
    int pool.sys_id 0
    boolean pool.active true
    boolean pool.default true
    int pool.importance 1
    string pool.comment
    pset pset_default
    pset pset_default
    int pset.sys_id -1
    boolean pset.default true
    uint pset.min 1
    uint pset.max 65536
    string pset.units population
    uint pset.load 162
    uint pset.size 2
    string pset.comment
    cpu
    int cpu.sys_id 1
    string cpu.comment
    string cpu.status on-line
    cpu
    int cpu.sys_id 0
    string cpu.comment
    string cpu.status on-line

    Теперь cоздадим статическую таблицу /etc/pooladm.conf с параметрами по умолчанию и посмотрим на эти параметры:

    # pooladm -s
    cat /etc/pooladm.conf
    <?xml version="1.0"?>
    <!DOCTYPE system PUBLIC "-//Sun Microsystems Inc//DTD Resource
    Management All//EN" "file:///usr/share/lib/xml/dtd/rm_pool.dtd.1">
    <!--
    Configuration for pools facility. Do NOT edit this file by hand - use
    poolcfg(1) or libpool(3POOL) instead.
    -->
    <system ref_id="dummy" name="default" comment="" version="1"
    bind-default="true">
    <property name="system.poold.objectives" type="string">wt-load</property>
    <pool name="pool_default" active="true" default="true" importance="1"
    comment="" res="pset_-1" ref_id="pool_0">
    <property name="pool.sys_id" type="int">0</property>
    </pool>
    <res_comp type="pset" sys_id="-1" name="pset_default" default="true"
    min="1" max="65536" units="population" comment="" ref_id="pset_-1">
    <property name="pset.load" type="uint">160</property>
    <property name="pset.size" type="uint">2</property>
    <comp type="cpu" sys_id="1" comment="" ref_id="cpu_1">
    <property name="cpu.status" type="string">on-line</property>
    </comp>
    <comp type="cpu" sys_id="0" comment="" ref_id="cpu_0">
    <property name="cpu.status" type="string">on-line</property>
    </comp>
    </res_comp>
    </system>

    Этот файл содержит те же самые настройки, что мы видели ранее, дав команду pooladm без параметров. Однако pooladm без параметров выводит только настройки по умолчанию, и для получения полной информации о существующих в системе пулах ресурсов следует использовать команду poolcfg -c info.

    Определим новый пул test, в который входит одна процессорная группа small, состоящая из одного процессора.

    Для этого вначале определим процессорную группу:

    poolcfg -c 'create pset small ( uint pset.min = 1 ; uint pset.max = 2)'

    теперь создадим пул:

    poolcfg -c 'create pool test'

    и свяжем процессорную группу с этим пулом:

    poolcfg -c 'associate pool test (pset small)'

    Теперь укажем, что пул test должен использовать планировщик задач по схеме долевого распределения:

    poolcfg -c 'modify pool test (string pool.scheduler = "FSS")'

    Что получилось?

    poolcfg -c info
    system default
    string system.comment
    int system.version 1
    boolean system.bind-default true
    string system.poold.objectives wt-load
    pool pool_default
    int pool.sys_id 0
    boolean pool.active true
    boolean pool.default true
    int pool.importance 1
    string pool.comment
    pset pset_default
    pool test
    boolean pool.active true
    boolean pool.default false
    string pool.scheduler FSS
    int pool.importance 1
    string pool.comment
    pset small
    pset pset_default
    int pset.sys_id -1
    boolean pset.default true
    uint pset.min 1
    uint pset.max 65536
    string pset.units population
    uint pset.load 160
    uint pset.size 2
    string pset.comment
    cpu
    int cpu.sys_id 1
    string cpu.comment
    string cpu.status on-line
    cpu
    int cpu.sys_id 0
    string cpu.comment
    string cpu.status on-line
    pset small
    int pset.sys_id -2
    boolean pset.default false
    uint pset.min 1
    uint pset.max 2
    string pset.units population
    uint pset.load 0
    uint pset.size 0
    string pset.comment

    Теперь назначим в пул test один процессор (таким образом, мы выделим пулу small один процессор, а второй останется в пуле pset_default ). Каждый процессор может относиться только к одному пулу ресурсов:

    poolcfg -dc "transfer to pset small (cpu 1)"

    Проверяем:

    # poolcfg -c info
    system default
    string system.comment
    int system.version 1
    boolean system.bind-default true
    string system.poold.objectives wt-load
    pool pool_default
    int pool.sys_id 0
    boolean pool.active true
    boolean pool.default true
    int pool.importance 1
    string pool.comment
    pset pset_default
    pool test
    boolean pool.active true
    boolean pool.default false
    string pool.scheduler FSS
    int pool.importance 1
    string pool.comment
    pset small
    pset pset_default
    int pset.sys_id -1
    boolean pset.default true
    uint pset.min 1
    uint pset.max 65536
    string pset.units population
    uint pset.load 160
    uint pset.size 1
    string pset.comment
    cpu
    int cpu.sys_id 0
    string cpu.comment
    string cpu.status on-line
    pset small
    int pset.sys_id -2
    boolean pset.default false
    uint pset.min 1
    uint pset.max 2
    string pset.units population
    uint pset.load 0
    uint pset.size 1
    string pset.comment
    cpu
    int cpu.sys_id 1
    string cpu.comment
    string cpu.status on-line

    Для записи динамически существующей в запущенной системе конфигурации пулов ресурсов в файл настроек надо выполнить команду

    pooladm -s имя_файла

    а для проверки корректности описания конфигурации пулов ресурсов команду

    pooladm -n имя_файла

    Если имя_файла не указано, подразумевается файл /etc/pooladm.conf

    Для активации уже записанных в файле настроек выполняется команда

    pooladm -c имя_файла

    Зоны и контейнеры

    Концепция управления ресурсами и распределения ресурсов между различными наборами приложений развивалась от проектов к зонам. Зоны – это логическое продолжение проектов. По сути дела, если проект – это совокупность процессов, которым могут выделяться некие ресурсы (в том числе и в монопольное распоряжение), то зона – это виртуальная копия системы, в которой запущен определенный набор служб. В отличие от проектов, зоны предоставляют высокий уровень изоляции приложений друг от друга: приложения из одной зоны никак не могут взаимодействовать с приложениями из другой зоны, за исключением обмена данными через сеть.

    Зона имеет свое файловое пространство, свой каталог /etc со своими настройками и, следовательно, свой список пользователей, своего администратора root, свой набор служб и так далее. Фактически, зона – это почти виртуальная машина, но значительное отличие зоны от VM – то, что все зоны используют одно и то же ядро.

    Зоны бывают двух типов: глобальная зона (она всегда одна – это тот экземпляр системы, который загружается при старте) и неглобальные зоны (это все остальные зоны).

    Смысл зон в том, что:

  • зона гарантирует идеальную изоляцию приложений – процессы одной зоны не влияют на процессы в других зонах;
  • зона обеспечивает изолированную среду не только для приложений, но и для системных служб внутри себя – в каждой зоне есть свои файлы настроек
  • Solaris позволяет настроить изолированную среду внутри зоны так, чтобы запускать в ней "неродные" приложения – исполняемые файлы Linux или приложения, ранее установленные в Solaris 8 (даже если это приложения были написаны третьими фирмами и содержат специфические несвязанные с Solaris компоненты).
  • Зону можно создать и настроить ее свойства командой zonecfg, управлять ею следует с помощью zoneadm.

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

    Файловая система неглобальной зоны может быть совершенно независимой от глобальной зоны (такие зоны называются зонами без унаследованных каталогов – whole root zone), а может содержать "унаследованные" каталоги, т.е. смонтированные из глобальной зоны в режиме "только для чтения". По умолчанию, каталоги /usr, /lib, /platform и /sbin являются унаследованными. Чем больше каталогов унаследует новая неглобальная зона, тем меньше места занимает ее собственная файловая система и тем меньше файлов в нее будет копироваться из глобальной зоны при создании.

    Клонирование зон на ZFS

    Быстрое клонирование зон может быть необходимо при создании большого количества зон одинаковой конфигурации. Для этой операции удобнее помещать клонируемую зону и все ее клоны в каталогах, расположенных в файловой системе ZFS, так как это значительно сэкономит время при копировании файлов. Клонирование зоны на UFS может занимать от 15 до 45 минут и более (в зависимости от количества установленных пакетов и производительности оборудования), а клонирование зоны на ZFS занимает около 8 секунд.

    Для успешного клонирования надо вначале настроить зону, которую вы будете клонировать:

    # zonecfg -z master
    master: No such zone configured
    Use 'create' to begin configuring a new zone.
    zonecfg:master> create
    zonecfg:master> set zonepath=/test/opt
    zonecfg:master> verify
    zonecfg:master> commit

    Теперь посмотрим на список зон в системе:

    # zoneadm list -vc
    ID NAME STATUS PATH BRAND IP
    0 global running / native shared
    - master configured /test/opt native shared

    Теперь выполним установку системы в зоне (фактически, копирование установленных пакетов из глобальной зоны в неглобальную):

    # zoneadm -z master install
    /test/opt must not be group readable.
    /test/opt must not be group executable.
    /test/opt must not be world readable.
    /test/opt must not be world executable.
    could not verify zonepath /test/opt because of the above errors.
    zoneadm: zone master failed to verify

    Ага! Ошибка в правах доступа к каталогу зоны. Исправляем:

    # ls -ld /test/opt
    drwxr-xr-x 2 root root 2 февр. 10 10:33 /test/opt
    # chmod go-rx /test/opt
    # ls -ld /test/opt
    drwx------ 2 root root 2 февр. 10 10:33 /test/opt

    Порядок. Устанавливаем зону:

    # zoneadm -z master install
    A ZFS file system has been created for this zone.
    Preparing to install zone <master>.
    Creating list of files to copy from the global zone.
    Copying <11008> files to the zone.
    Initializing zone product registry.
    Determining zone package initialization order.
    Preparing to initialize <1256> packages on the zone.
    Initialized <1256> packages on zone.
    Zone <master> is initialized.
    Inst allation of these packages generated errors: <openofficeorgdesktop-
    integratn>
    Installation of <1> packages was skipped.
    Installation of these packages generated warnings: <WebStackTooling>
    The file </test/opt/master/root/var/sadm/system/logs/install_log>
    contains a log of the zone installation.

    Теперь выполняем клонирование, для чего вначале создаем зону и настраиваем ее параметры:

    zonecfg -z clone create -t master

    Обратите внимание на то, что при клонировании мы указывам название зоны-образца (после ключа t ). Это делается потому, что без указания образца нам бы потребовалось сразу настроить обязательный параметр "место расположения зоны" ( zonepath ), а в командной строке при создании зоны этого не сделать. Теперь укажем этот параметр в следующей команде:

    zonecfg -z clone set zonepath=/test/opt/clone

    И клонируем зону:

    zoneadm -z clone clone master

    Обратите внимание: в командах zoneadm и zonecfg после ключа z всегда указывается та зона, которую мы в данный момент настраиваем или которой управляем.

    Настройка производительности системы

    Какая аппаратура быстрее?

    Естественно, для разных задач подходят разные компьютеры. Например, компьютеры с процессором Alpha обычно быстрее своих Intel-собратьев выполняют расчеты с числами с плавающей запятой. Это значит, что вычисления, связанные с расчетами координат, решением уравнений или моделированием молекул быстрее выполнит компьютер с процессором Alpha.

    В настоящее время процессоры Alpha широко используются в высокопроизводительных серверах от Hewlett-Packard и других, еще более специализированных системах, таких, как суперкомпьютеры Cray и Fujitsu.

    Если же речь идет о целочисленных вычислениях, пусть и достаточно громоздких, например, рендеринге, преобразовании графических объектов, 3D-визуализации, где координаты могут быть заданы только целыми числами, процессоры Intel отлично справятся с ними.

    Сейчас мы говорили о процессорах Alpha и Intel, но на деле разговор касается двух разных архитектур – RISC и CISC. Процессоры Intel традиционно тяготеют к последней, в то время как процессоры SPARC – к первой. ОС Solaris выпускается в версиях для обеих архитектур, хотя изначально компания Sun не выпускала версию Solaris для Intel, а многочисленные пользователи этой системы во всем мире до сих пор утверждают, что версия для SPARC более производительна и надежна. Это, в частности, связано с тем, что механизмы обеспечения многозадачности тесно связаны с используемой аппаратурой, и версия Solaris под Intel "подогнана" под архитектуру процессоров Intel и архитектуру аппаратных средств, разработанных для них.

    Впрочем, оставим эти утверждения на совести пользователей: если для версии Solaris 8 и более старых они еще были справедливы, то Solaris 10 на серверах с процессорами AMD и Intel решает задачи ничуть не хуже, чем на SPARC от Sun Microsystems.

    В заключение разговора о предпочтительности той или иной аппаратуры следует сказать, что:

  • для работы Solaris под серьезной нагрузкой, такой, как СУБД Oracle с тысячами клиентов и важностью высокой скорости реагирования, система на базе процессоров RISC, скорее всего, окажется более результативной;
  • независимо от используемой аппаратной платформы конфигурация компьютера должна быть хорошо согласована: быстрый процессор должен работать с быстрой оперативной памятью, а дисковая подсистема (контроллеры и диски) обязаны успевать без задержек отрабатывать команды чтения и записи. Недостаточный объем кэша любого уровня, как кэша процессора на кристалле, так и кэша дискового контроллера может привести к значительному снижению производительности.
  • Сравнение производительности систем разных платформ
    Процессор, частота SPECint2000 (base) SPECfp2000 (base) Система
    Alpha 21264C, 1.01 GHz 561 585 Compaq AlphaServer GS160
    Alpha 21264C, 1 GHz 621 776 Compaq AlphaServer ES45
    Alpha 21264B, 833 MHz 518 621 Compaq AlphaServer ES40
    Itanium, 800 MHz 379 701 HP rx4610
    Itanium, 800 MHz 358 655 HP i2000
    UltraSPARC III, 1.05 GHz 537 701 Sun Blade 2050
    UltraSPARC III, 900 MHz 470 629 Sun Blade 1000
    UltraSPARC III, 750 MHz 363 312 Sun Blade 1000
    Power4, 1.3 GHz 790 1098 IBM eServer 690
    Alpha 21364 EV-78+, 1.3 GHz 904 1279
    AMD Opteron 256, 3 GHz 1942 2260
    IBM Power5, 1,9 GHz 1398 2585
    Intel Pentium 965, 3,73 GHz 1870 2232
    Sun UnlraSPARC IV+, 1,8 GHz 1300 1800

    Оценка ситуации: программы надзора за системой

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

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

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

    Для оценки загрузки процессора и состояния памяти (достаточно ли оперативной памяти, не перегружена ли дисковая подсистема свопингом и т.п.) следует использовать программы top и sar. Конкретные примеры применения этих программ даны ниже, в разделе "эффективное использование памяти и свопинга". Программа top (в Solaris удобнее использовать prstat – местный аналог top ) выводит информацию о наиболее активных процессах, которые сильнее всего занимают процессор:

    top
    last pid: 501; load averages: 0.08, 0.34, 0.40 19:12:00
    59 processes: 58 sleeping, 1 on cpu
    CPU states: 96.2% idle, 0.8% user, 1.0% kernel, 2.0% iowait, 0.0% swap
    Memory: 128M real, 3596K free, 132M swap in use, 466M swap free
    PID USERNAME LWP PRI NICE SIZE RES STATE TIME CPU COMMAND
    345 root 1 59 0 24M 9972K sleep 0:11 1.14% Xsun
    470 root 4 49 0 128M 71M sleep 0:52 1.01% soffice.bin
    501 root 1 59 0 2228K 1336K cpu 0:00 0.55% top
    461 root 1 59 0 15M 3184K sleep 0:00 0.37% dtterm
    467 root 1 49 0 4708K 832K sleep 0:00 0.03% bash
    435 root 1 49 0 16M 1760K sleep 0:00 0.01% dtfile
    434 root 5 59 0 22M 6304K sleep 0:01 0.00% dtwm
    427 root 1 49 0 18M 0K sleep 0:00 0.00% dtsession
    436 root 1 59 0 14M 3292K sleep 0:00 0.00% sdtperfmeter
    265 root 26 59 0 5480K 1456K sleep 0:00 0.00% htt_server
    460 root 1 59 0 3064K 1372K sleep 0:00 0.00% dtexec
    315 root 1 59 0 6900K 1324K sleep 0:00 0.00% dtlogin
    411 root 1 59 0 3784K 1300K sleep 0:00 0.00% sdt_shell
    183 root 3 59 0 5832K 1188K sleep 0:00 0.00% automountd
    95 root 13 59 0 5660K 1100K sleep 0:00 0.00% syslogd

    Программа sar подобна vmstat и выдает статистику по работе системы, ее можно запустить для выдачи определенных параметров одномоментно или для периодического вывода сведений, например, для десятикратных измерений значений стандартного набора параметров с периодом 5 секунд:

    sar 5 10
    SunOS sunny 5.9 Generic_112234-03 i86pc 07/03/2004
    19:12:34 %usr %sys %wio %idle
    19:12:39 0 1 0 99
    19:12:44 0 0 0 100
    19:12:49 0 1 0 99
    19:12:54 4 1 0 95
    19:12:59 0 0 0 100
    19:13:04 0 1 0 99
    19:13:09 5 1 0 94
    19:13:14 1 24 66 8
    19:13:19 2 35 38 25
    19:13:24 3 20 17 60

    Решение проблем: изменение размеров разделов диска

    Если необходимо увеличить размер конкретного раздела, то есть два пути: физически изменить размер раздела или создать метаустройство, которое физически будет состоять из нескольких разделов на одном или нескольких дисках, но система будет его считать одним логическим разделом. Второй путь напоминает создание Volume Set в системах Windows NT и более новых.

    Отметим, что при использовании файловой системы ZFS в Solaris задачи расширения объема файловой системы решаются проще – добавлением нового устройства или раздела в пул; после этого все файловые системы, размещенные в этом пуле, могут пользоваться появившимся пространством. Ниже описанные процедуры более актуальны для использования более старой файловой системы UFS.

    Чтобы физически изменить размер раздела, надо, чтобы на диске вслед за этим разделом было свободное пространство, еще не отданное ни одному разделу. Если там есть какой-то другой раздел, то его придется удалить, предварительно сохранив нужные данные, которые в нем находятся. После этого потребуется выполнить резервное копирование всех данных увеличиваемого раздела в какой-то каталог другого раздела, удалить старый раздел, создать на его месте новый, больший, с помощью команды newfs, и затем восстановить файлы из резервной копии. Этот метод рекомендован для использования в любых системах UNIX. Однако, он требует значительных затрат времени и дискового (или ленточного, в зависимости от того, где вы создаете резервную копию) пространства.

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

    Синтаксис команды growfs:

    /usr/sbin/growfs [-M точка_монтирования] [параметры_newfs] [rawdevice]

    Аргументы команды growfs обозначают:

  • точка_монтирования – точка монтирования файловой системы, которую требуется расширить. При этом на время расширения произойдет блокировка файловой системы функцией lockfs() ;
  • параметры_newfs – те же параметры, которые может принимать программа newfs при создании новой файловой системы, см. описание newfs.;
  • rawdevice – имя файла прямого доступа для метаустройства в каталоге /dev/md/rdsk.
  • Команда growfs увеличивает размер файловой системы до размера указанного раздела.

    Увеличение размера раздела выполняется посредством добавления нового раздела к метаустройству и последущего запуска growfs. При увеличении размера зеркала (т.е. уже существующего метаустройства с реализованным зеркалированием, или, иначе говоря, с RAID уровня 1) следует вначале увеличить каждую из частей зеркала с помощью metaattach, как показано ниже, а затем – всю файловую систему с помощью growfs.

    Особым случаем является расширение журналируемого метаустройства (trans metadevice), которое состоит из двух устройств – главного и журналирующего. Увеличивается только размер главного устройства, а затем growfs "напускается" на само журналируемое метаустройство. Вообще говоря, можно увеличить и размер журналирующего устройства, но это не обязательно.

    Програма growfs на время модификации файловой системы блокирует запись в нее. Можно сократить время блокировки файловой системы, выполняя ее увеличение по частям. Например, мы хотим увеличить файловую систему размером 2 Гбайта до размера 8 Гбайт. Можно это делать поэтапно, добавляя по 16 Мбайт за этап, дав ключ s для явного указания размера общего размера новой файловой системы на каждом этапе. Число, следующее за ключом s, интерпретируется как общее число секторов новой файловой системы на каждом этапе и должно быть кратно размеру цилиндра в секторах. Иначе говоря, файловая система должна содержать целое число цилиндров.

    Подробнее об ограничениях, связанных с размером разделов, рассказано в руководстве по newfs и growfs.

    Представим себе, что требуется увеличить размер раздела /dev/dsk/c1t0d0s3, на котором расположена файловая система /export. Для этого нам потребуется вначале преобразовать этот раздел в метаустройство, поскольку добавлять дополнительное пространство можно только к метаустройству. Допустим, добавлять к существующему мы будем пока еще пустой, не содержащий файловой системы раздел /dev/dsk/c2t0d0s3:

    metainit -f d8 2 1 c1t0d0s3 1 c2t0d0s3

    Эта команда вызывает объединение разделов /dev/dsk/c1t0d0s3 и /dev/dsk/c2t0d0s3 в новое метаустройство d8. Теперь изменяем /etc/vfstab так, чтобы файловая система /export монтировалась на метаустройство d8:

    #device device mount FS fsck mount mount
    #to mount to fsck point type pass at boot options
    /dev/md/dsk/d8 /dev/md/dsk/d8 /export ufs 2 yes -

    Демонтируем /export и снова монтируем его (при монтировании будет использовано новое устройство из /etc/vfstab ):

    umount /export
    mount /export

    Запускаем growfs для расширения файловой системы на новый раздел:

    growfs -M /export /dev/md/rdsk/d8

    Ключ M нужен программе growfs для того, чтобы можно было увеличить размер смонтированной файловой системы. В процессе изменения размера запись в файловую систему блокируется программой growfs.

    Файл /etc/lvm/md.tab содержит таблицу метаустройств, которая служит файлом настроек для запуска программы metainit при старте системы.

    Ограничения при работе с growfs

    С помощью growfs можно расширять только файловые системы UFS (не важно, смонтированные или несмонтированные). Единожды расширенная файловая система не может быть уменьшена. Расширение файловой системы невозможно, если:

  • на задействованном в ней устройстве находится файл учета запущенной системы acct, или
  • включена система безопасности на уровне C2 и файл журналирования находится на расширяемом устройстве, или
  • на ней находится локальный файл свопинга, или
  • эта файловая система монтируется в каталог /usr или корневой каталог или является активным разделом свопинга.
  • Увеличение производительности дисковой подсистемы

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

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

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

    Приложение может вызвать функцию fsync() для принудительного сбрасывания данных из файлового кэша на диск. Кроме этого, к такому же результату приводит закрытие файла, используемого процессом. При завершении процесса все связанные с ним файлы закрываются, что вызывает немедленную запись всех еще не записанных в эти файлы данных из кэша на диск. Поэтому при одновременном завершении большого количества процессов дисковая активность может резко возрасти. Такое явление наблюдается, например, при завершении работы демона squid, кэширующего http-запросы.

    Вторая причина дисковой активности, свопинг или пейджинг, зависит от того, как объем памяти в системе соответствует реальным потребностям приложений. Настройку системы с целью оптимизации свопинга мы рассмотрим ниже в разделе "эффективное использование памяти и свопинга", а сейчас обратимся к оптимизации операций записи и чтения данных.

    Снижение частоты синхронизации файлового кэша с диском

    При частых и объемных операциях с файлами файловый кэш быстро заполняет значительный объем памяти. В системах Solaris до версии 8 он даже конкурировал с процессами за оперативную память. Процесс fsflush регулярно (по умолчанию – раз в 30 секунд) "сбрасывает" на диск содержимое кэша, обеспечивая таким образом синхронизацию кэша и файловой системы. Если количество открытых файлов велико, эта синхронизация может приводить и к потерям времени, и к чересчур высокой загрузке дисковой подсистемы.

    Демон fsflush руководствуется значением двух переменных, autoup и tune_t_fsflushr, – значение им можно присвоить в файле /etc/system.

    Для систем с большим объемом памяти установленное по умолчанию значение в 30 с делает процесс fsflush чересчур дорогостоящим. Для того. чтобы поубавить аппетит fsflush, время цикла синхронизации следует увеличить, изменив в бОльшую сторону значение autoup. Поскольку fsflush оказывает влияние на всю систему, лучше всего, чтобы он работал в течение более коротких промежутков времени. Для этого значение tune_t_fsflushr (время, отведенное fsflush на синхронизацию) должно быть меньше: отведя демону меньшее число секунд, вы заставите его выполнять в пять раз меньшее по объему сканирование.

    Приостановка записи (write throttle) в файловой системе UFS

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

    Переменная ядра ufs:ufs_WRITES отвечает за включение механизма write throttling (приостановки записи в файл). Если эта переменная равна 1, то приостановка записи разрешена. По умолчанию это именно так.

    Приостановка означает, что когда объем данных, ожидающих записи в один файл, превышает верхний предел ufs:ufs_HW, запись в этот файл блокируется до момента, пока объем данных в буфере не снизится до ufs:ufs_HW. Соответственно, пока запись в файл блокирована, пополнение буфера не осуществляется, зато данные из буфера записываются на диск, за счет чего буфер освобождается.

    Настройка этих параметров ядра может понадобиться, если количество приостановок постоянно растет. Это можно заметить, изучив с помощью отладчика счетчик ядра ufs_throttles. Его значение увеличивается на единицу при каждой приостановке записи, и постоянное увеличение этого значения говорит о том, что пределы ufs:ufs_HWufs:ufs_HW следует увеличить.

    Такое увеличение вполне допустимо и даже полезно при использовании метаустройств с расщеплением (striping metadevices), когда данные одного файла поблочно пишутся на несколько устройств одновременно (первый блок – на первый диск, следующий – на второй и т.д.), так как совокупная пропускная способность метаустройства выше, чем у одного физического диска. То же относится и к массивам RAID. Значения ufs:ufs_HWufs:ufs_HW не должны быть слишком близкими и не должны очень сильно отличаться. Если они слишком близки, то приостановки записи будут случаться слишком часто: едва объем буфера окажется у нижнего предела и запись будет разрешена, как сразу буфер и превысит верхний предел и запись приостановится. Большая разница между значениями приведет к тому, что запись в файл будет заблокирована при превышении верхнего предела и после этого пройдет значительное время до разблокировки записи, так как буфер не может быть мгновенно "сброшен" на диск и до достижения нижнего предела придется ждать относительно долго.

    Рекомендуется нижний предел устанавливать равным 1/32 объема оперативной памяти, а верхний – 1/16 этого объема.

    Приостановка записи производится на пофайловой основе, т.е. блокировка записи в один файл, буфер которого заполнен более чем ufs:ufs_HW байтами, не влияет на запись в другие файлы.

    Кэш поиска имен каталогов (DNLC)

    Чтобы не искать номер индексного дескриптора по имени файла каждый раз, когда к файлу происходит обращение, система кэширует имена файлов и каталогов вместе с номерами их виртуальных индексных дескрипторов. Этот специальный кэш называется кэш поиска имен каталогов (directory name lookup cache – DNLC).

    При открытии файла DNLC вычисляет соответствующий индексный дескриптор по имени этого файла. Если имя уже находится в кэше, то оно будет найдено очень быстро, поскольку не происходит сканирования каталогов на диске. Каждая запись DNLC в прежнем имела фиксированный размер, поэтому пространство для имени файла не могло превышать 30 символов, а более длинные имена файлов не кэшировались. Начиная с Solaris 7 это ограничение снято. Если в каталоге несколько тысяч записей, поиск номера индексного дескриптора конкретного файла среди них отнимет много времени. Если в системе открыто много файлов, а количество файлов в рабочих каталогах велико, то высокая частота успешных обращений к DNLC очень важна.

    Кэш имен каталогов не нуждается в настройке, хотя его размер зависит от значения maxusers. По умолчанию он определяется как (17xmaxusers)+90 (в Solaris 2.5.1) или 4x(maxusers + max_nprocs)+320 (в Solaris 2.6 и выше). Другие параметры, на которые тоже оказывает влияние maxusers, обсуждены в лекции 1.

    Команда

    vmstat –s

    показывает частоту успешных попаданий в DNLC с момента начала работы системы.

    Если частота промахов велика (попаданий обычно не должно быть меньше 90%), следует подумать об увеличении размера DNLC. Проверим этот показатель работы системы командой

    vmstat -s |grep 'name lookups'
    422920 total name lookups (cache hits 99%)

    Количество запросов к DNLC в секунду можно получить из поля namei/s в выводе команды sar –a:

    sar -a 1 5
    SunOS sunny 5.9 Generic_112234-03 i86pc 07/03/2004
    19:26:50 iget/s namei/s dirbk/s
    19:26:51 0 1 0
    19:26:52 0 0 0
    19:26:53 0 0 0
    19:26:54 0 4 0
    19:26:55 0 0 0

    Как видно, система не очень-то загружена запросами к файлам и отдыхает. А теперь запустим операцию, которая точно требует многократного обращения к DNLC:

    find / -name "top" 
    [1] 577
    sar -a 1 5
    SunOS sunny 5.9 Generic_112234-03 i86pc 07/03/2004
    19:27:14 iget/s namei/s dirbk/s
    19:27:15 1675 2592 1922
    19:27:16 1220 2365 1474
    19:27:17 968 1882 1172
    19:27:18 1057 2107 1292
    19:27:19 1231 2211 1443
    vmstat -s |grep 'name lookups'
    503370 total name lookups (cache hits 86%)

    При интенсивных файловых операциях и доступе ко многим каталогам одновременно эффективность кэша имен каталогов снижается, но по-прежнему остается достаточно высокой.

    Индексные дескрипторы

    При создании файловой системы для индексных дескрипторов выделяется отдельное пространство на разделе. Индексные дескрипторы хранят свойства файла, в том числе теневые индексные дескрипторы – расширенные права доступа. Количество индексных дескрипторов – это неизменяемая величина. Отсутствие свободных индексных дескрипторов в файловой системе приводит к невозможности записывать файлы в те каталоги, которые расположены в этой файловой системе. Количество свободных индексных дескрипторов можно определить, проанализировав вывод команды df –e:

    df -e
    Filesystem ifree
    /proc 862
    /dev/dsk/c0t0d0s0 294838
    fd 0
    /dev/dsk/c0t0d0s4 246965
    swap 9796
    /dev/dsk/c1t0d0s0 3256077

    Количество одновременно записываемых блоков

    Так как размер кластера файловой системы, как правило, составляет 8 Кб, драйвер файловой системы при записи собирает данные в блоки по 8Кб для большей эффективности использования дискового пространства. При записи сравнительно больших файлов драйвер файловой системы группирует вместе несколько блоков для того, чтобы вместо серии мелких операций ввода-вывода выполнить одну, большую по объему операцию. Количество группируемых блоков равно параметру файловой системы maxcontig. В версиях, предшествующих Solaris 8, этот параметр по умолчанию был равен семи, и, таким образом, операция ввода-вывода происходила одновременно с семью последовательными блоками, и позволяла одновременно записать порцию данных размером 56 KB. Такое значение по умолчанию связано с ограничениями конструкции в раннем оборудовании Sun: системы, основанные на архитектуре sun4, не способны передавать за одну операцию более 64 KB. В архитектурах sun4c, sun4m, sun4d и sun4u таких ограничений нет. В Solaris 8 значение по умолчанию изменилось и составляет 16 блоков (128 Kb).

    Изменение параметра maxcontig может серьезно повлиять на производительность файловой системы, при работе с которой преобладают последовательные операции по записи средних и больших (более нескольких десятков килобайт) файлов на диск. Если при доступе к файловой системе большинство операций ввода-вывода совершается с данными малого размера, то изменение maxcontig не принесет большой пользы.

    Размер кластера файловой системы задается с помощью ключа –С blocks команды newfs при создании файловой системы. Для существующей файловой системы его можно изменить с помощью ключа –a команды tunefs.

    Настройка maxcontig дает наилучший результат, если ее выполнить при создании файловой системы, так как это фактически определит размер кластера файловой системы. При выполнении настройки уже используемой файловой системы столь же впечатляющего результата не будет: при такой настройке блоки, которые уже были записаны, не будут перекомпонованы.

    Настройка параметров файловой системы

    Чтобы оценить загрузку файловых систем, имеет смысл запустить команду

    iostat -x 5

    в тот момент, когда интенсивность ввода-вывода будет наиболее близка к обычному (или пиковому, в зависимости от того, как вы хотите настроить файловую системы) уровню:

    ...
    device r/s w/s kr/s kw/s wait actv svc_t %w %b
    cmdk0 17.6 2.9 138.4 53.1 1.1 0.2 60.1 3 13
    fd0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0
    sd0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0
    nfs1 0.0 0.0 0.0 0.0 0.0 0.0 9.3 0 0
    extended device statistics
    device r/s w/s kr/s kw/s wait actv svc_t %w %b
    cmdk0 307.7 0.2 766.1 2.0 0.0 0.9 2.9 0 89
    fd0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0
    sd0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0
    nfs1 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0
    extended device statistics
    device r/s w/s kr/s kw/s wait actv svc_t %w %b
    cmdk0 253.4 0.7 768.0 6.0 0.0 0.9 3.6 0 88
    fd0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0
    sd0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0
    nfs1 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0
    ...

    Средние значения загрузки можно получить из колонок kr/s и kw/s, в более ранних версиях системы для получения таких значений приходилось делить содержимое колонок "K/r" и "K/w" на "r/s" и "w/s" соответственно для получения средних показателей "прочитано килобайт в секунду" и "записано килобайт в секунду".

    Для получения информации о распределении файлов по размеру можно использовать команду:

    quot -c file_system

    Например, вот каково распределение в моей тестовой системе:

    quot -c /export/home
    ...
    1128 1 165156
    1136 1 166292
    1160 1 167452
    1176 1 168628
    1184 1 169812
    1192 1 171004
    1224 1 172228
    1232 1 173460
    1240 1 174700
    1264 1 175964
    1360 1 177324
    1376 1 178700
    1440 1 180140
    1488 1 181628
    1536 1 183164
    1608 1 184772
    1648 1 186420
    1704 1 188124
    1768 1 189892
    1792 1 191684
    1832 1 193516
    2047 40 437396
    ...

    Первая колонка вывода – это размер файла в блоках, вторая – число файлов такого размера, третья – общее число блоков, занятых файлами такого размера и меньшими.

    Эффективное использование памяти и свопинга

    Вопрос об установке в систему дополнительной оперативной памяти представляет собой классический вопрос выбора между ценой и производительностью. Если цена важнее производительности, то при нехватке памяти увеличивают размер раздела свопинга, если важнее производительность, увеличивают объем оперативной памяти. Если же нет возможности сделать ни то, ни другое, новые процессы не смогут быть запущены при нехватке виртуальной памяти (ее можно заметить по сообщениям "Not enough space" или "WARNING: /tmp: File system full, swap space limit exceeded").

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

    Индикаторами нехватки памяти в системе являются активность сканирования страниц на предмет пометки для выгрузки и активная работа устройства, на котором расположен swap-раздел.

    В обоих случаях высокая активность может быть временной или постоянной. В любом случае, имеет смысл уяснить ее причину.

    Частота сканирования страниц

    Повышенная частота сканирования страниц ( scan rate ) – главный показатель того, что в системе перестало хватать оперативной памяти. Для просмотра значения scan rate используйте команды

    sar –g

    или

    vmstat

    При анализе частоты сканирования с помощью vmstat имеет смысл запустить эту программу с параметром 60 для получения статистики каждые 60 секунд:

    vmstat 60
    kthr memory page disk faults cpu
    r b w swap free re mf pi po fr de sr cd f0 s0 -- in sy cs us sy id
    0 0 0 482100 7288 23 63 126 31 46 8 54 28 0 0 0 333 1519 327 5 11 84
    0 1 0 470816 2060 0 26 1 51 103 0 123 240 0 0 0 960 969 649 4 92 4
    ...

    Первую строку (суммарную статистику) можно игнорировать. Если показатель page/sr остается выше 200 страниц в секунду в течение длительного времени, это говорит о вероятной нехватке оперативной памяти в системе.

    Постоянно низкое значение частоты сканирования страниц говорит о том, что системе хватает памяти. С другой стороны, высокое значение может быть вызвано активностью процесса (или нескольких процессов одновременно), читающих данные с диска или получающих их через сеть – эти данные не только кэшируются операционной системой, но и занимают место в памяти процессов, поэтому запросто могут вызвать активный пейджинг. Такоим образом, не следует слепо полагаться на обсуждаемые рекомендации и считать 200 страниц в секунду абсолютной догмой индикации нехватки памяти: действуйте по ситуации, смотрите, какие процессы в действительности запущены и насколько они требовательны к памяти.

    Активность свопинга

    Если устройство, на котором находится область свопинга, загружено вводом-выводом, это говорит о нехватке памяти. Можно оценить дисковую активность с помощью программы iostat.

    Для Solaris 2.6 и выше следует использовать команду

    iostat -xPnce

    для получения информации об активночти передачи данных в/из конкретных разделов дисков, в Solaris 2.5.1 доступна команда

    iostat -xc

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

    Можно также использовать

    sar –d

    или

    vmstat

    Длинная очередь страниц для выгрузки свидетельствует о необходимости нарастить оперативную память в системе.

    Использование памяти процессами

    В системах Solaris, начиная с версии 2.6, есть возможность выяснить, какие программы сколько памяти занимают (и подробнее – размеры сегментов данных, кода и т.п.) с помощью программы pmap. Для получения детальной информации дайте команду

    /usr/proc/bin/pmap –x PID

    Информация о размере процесса в памяти также содержится в колонке RSS вывода программ top и ps (используйте ps –ly ).

    В пакете SunPro есть отладчик dbx, который помогает находить источник утечки памяти в программе; для такой работы следует компилировать программу компилятором SunPro с ключом –g.

    Статистику использования разделяемой памяти вы получите по команде

    ipcs -mb

    Эти программы следует использовать для определения размера процессов и основных потребителей памяти в системе.

    Размер пространства свопинга

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

    Для управления пространством свопинга (получения информации о нем, добавления и удаления разделов свопинга) применяется программа swap. Для получения информации о текущем состоянии пространства свопинга используйте swap –l.

    Для выяснения общего объема виртуальной памяти, который включает объем оперативной памяти и пространства свопнига вместе, следует запустить swap –s или sar –r.

    Если своп-раздел смонтирован в /tmp как файловая система типа tmpfs, команда

    df -k /tmp

    покажет общий объем свободной виртуальной памяти, включая оперативную память.

    Алгоритм пейджинга

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

    Параметры ядра и пейджинг

  • physmem: общее количество страниц в оперативной памяти.
  • lotsfree: сканер страниц начинает работать, когда количество свободной оперативной памяти становится меньше lotsfree. Значение по умолчанию – physmem/64, но может быть изменено в /etc/system. Сканер страниц по умолчанию запускается в режиме пейджинга. Частота сканирования ( scan rate, столбик sr в выводе vmstat ) устанавливается равной параметру slowscan, который по умолчанию равен fastscan/10.
  • minfree: пока объем свободной памяти находится между lotsfree и minfree, частота сканирования страниц растет линейно от slowscan к fastscan по мере уменьшения свободной памяти (рис. 6.2). Значение minfree по умолчанию – desfree/2, значение fastscan по умолчанию – physmem/4. Если свободной памяти становится меньше, чем desfree (что по умолчанию равно lotsfree/2 ), сканер страниц начинает запускаться 100 раз в секунду.

    Каждый свой запуск сканер страниц проверяет desscan страниц. Этот параметр изменяется динамически вместе с частотой сканирования.

  • maxpgio: этот параметр (в зависимости от конкретной аппаратуры – 40 или 60) по умолчанию ограничивает частоту ввода-вывода на устройство пейджинга. Для современных дисков с частотой вращения больше 7200 оборотов в минуту можно установить значение maxpgio в сто раз больше количества жестких дисков, задействованных в свопинге.
  • throttlefree: когда свободной оперативной памяти становится меньше throttlefree (по умолчанию этот параметр равен minfree ), запросы процессов на выделение им новых страниц памяти переводятся в состояние ожидания, до тех пор, пока не появится свободных страниц.
  • cachefree: имеет значение в для систем Solaris 7 (или систем 2.5.1 и 2.6 с установленными самыми свежими обновлениями); если в этих системах параметр priority_paging установлен равным 1 (т.е. priority paging включен), то пока свободной памяти больше, чем lotsfree, освобождаются только страницы файлового кэша в памяти, а страницы процессов не затрагиваются. Значение по умолчанию – удвоенное lotsfree. Системы Solaris более поздних версий, начиная с 8, имеют другой алгоритм освобождения оперативной памяти, и в них НЕ следует включать priority paging и устанавливать значение cachefree.
  • (рис 6.2) Зависимость частоты запуска сканера страниц от объема свободной памяти

    В системах Solaris до версии 7 включительно сканер страниц работает так: для выбранных сканером страниц обнуляется флаг "используемости" страницы, выбор страниц происходит со скоростью, которую можно посмотреть с помощью vmstat или sar –g (scan rate). После обработки handspreadpages страниц, сканер проверяет, установлен ли флаг "используемости". Фактически, сканер состоит из двух процессов, один из которых идет по памяти и очищает флаги встреченных страниц, а второй следует за ним на некотором расстоянии и проверяет, не было ли новых обращений к этой странице (не установился ли снова этот флаг). Если флаг не установлен снова (обращений к странице за то время, пока сканер отмечал handspreadpages страниц, не произошло), то страница отправляется в своп. Параметр handspreadpages по умолчанию равен physmem/4.

    В системах Solaris 8 и более новых алгоритм освобождения памяти иной (он называется cyclical page cache ). Он рассчитан на то, что при нехватке памяти выгружаются прежде всего страницы файлового кэша, и только затем – страницы процессов. Этот алгоритм разработан для тех же целей, что и priority paging в Solaris 7. Новый алгоритм использует два списка свободных страниц. Один – для помещения в него страниц файлового кэша, которые освобождаются, другой – для помещения в него прочих освобождающихся страниц (разделяемой памяти, процессов и т.п.). При таком подходе файловый кэш не соперничает ни с кем, кроме самого себя, за место в памяти.

    В результате этих изменений, в системах Solaris, начиная с версии 8, vmstat сообщает иные цифры, чем в той же ситуации в более старых системах, а именно:

  • скорость возврата страниц выше;
  • весь файловый кэш показывается как свободная память;
  • скорость сканирования страниц ( scan rate ) низкая (даже близка к нулю), за исключением ситуаций, когда в системе действительно сильно не хватает памяти приложениям.
  • Для получения отдельного отчета по пейджингу страниц приложений ( executables ), данных ( anonymous ) и файловой системы используйте команду.

    vmstat -p

    Свопинг

    Если системе в течение некоторого времени (обычно – 30 секунд подряд) не хватает памяти (объем свободной оперативной памяти падает ниже desfree ), то начинается свопинг процессов. Планировщик задач выгружает те процессы, которые не претендовали на процессорное время в течение более чем maxslp секунд. По умолчанию maxslp равно 20. Этот режим свопинга называется мягким.

    Если дело дошло до того, что памяти меньше, чем desfree, и, кроме того, два и более процессов выстроились в очередь к процессору, а активность пейджинга превышает maxpgio, начинается жесткий свопинг. Это означает, что ядро выгружает модули и страницы кэша, а затем начинает последовательно выгружать процессы до тех пор, пока объем свободной памяти не станет больше desfree.

    Не выгружаются процессы:

  • классов планирования SYS и RT ;
  • запускаемые в данный момент или остановленные по сигналу (например, при отладке);
  • завершающие работу;
  • находящиеся в состоянии зомби;
  • системные потоки;
  • процессы, которые блокируют другие, более высокоприоритетные потоки.
  • Ввод-вывод без кэша

    Значительный объем чтения и записи данных может вызвать нехватку памяти из-за стремления системы кэшировать весь ввод-вывод. При действительно существенных объемах ввода-вывода можно отменить кэширование и производить ввод-вывод напрямую.

    Для этого можно использовать функцию directio() или параметр forcedirectio при монтировании файловой системы командой mount.

    Файловая система VxFS включает ввод-вывод в обход кэша всегда, когда объем операции ввода-вывода превышает значение параметра discovered_direct_iosz (см. man vxtunefs ) (по умолчанию – 256KB).

    Если в вашей системе преобладают множественные операции ввода-вывода небольших объемов данных и даже VxFS не помогает освободить память от большого количества кэшируемых данных, попробуйте уменьшить до приемлемого размера значение discovered_direct_iosz.

    Вернуться к учебному плану