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

Размер области подкачки. Размер области подкачки — компромиссное решение, поскольку проблемы могут возникнуть, и когда эта область слишком велика, и когда она слишком мала. На консоли никогда не появится простое сообщение «Размер области подкачки слишком мал». Сообщение «Слишком мало памяти» увидеть можно, но «Слишком много памяти» — никогда, хотя такая ситуация порой случается.

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

То, что, с одной стороны, можно считать неэффективной тратой памяти емкостью 100 Мбайт, с другой — можно рассматривать и как недорогую страховку от проблем с производительностью. С учетом реализации области подкачки в Solaris, обычное правило, в соответствии с которым емкость устройства подкачки должна в два-три раза превышать объем реальной памяти, больше нельзя считать актуальным, и все эти параметры следует уменьшить на единицу. Таким образом, вполне разумно для начала задать размер области подкачки равным объему реальной памяти или в два раза большим.

iowait. Статистика iowait в случае крупных машин Solaris может ввести в заблуждение. Раньше некоторые системы требовали, чтобы прерывание ввода/вывода обслуживал тот же центральный процессор, который этот ввод/вывод инициировал; в результате доступ к этому центральному процессору в таких системах блокировался до выполнения запроса на ввод/вывод. Время ожидания рассматривалось как одно из состояний процессора — он был либо занят пользователем, либо использовался в коде ядра, либо ожидал ввода/вывода, либо простаивал и был свободен для выполнения других процессов.

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

По мнению Эдриана Кокрофта, сбор статистики %wio (время простоя в ожидании ввода/вывода) производится до сих пор по одной-единственной причине: администраторам крайне сложно отказаться от сложившихся привычек. Некоторые до сих пор интересуются: «Через какой промежуток времени после инициирования ввода/вывода прерывание будет обработано?» В лучшем случае это попытка определить характеристики поведения аппаратного обеспечения ввода/вывода, но данный показатель, безусловно, не отражает состояние центрального процессора. Наличие нескольких невыполненных операций ввода/вывода означает, что любой освободившийся центральный процессор потенциально способен обслужить прерывания, когда они появятся. Однако их будет обрабатывать только один центральный процессор, и реальной возможности установить соответствие с числом процессов, находящихся в очереди ввода/вывода, не существует.

В случае системы с симметричной многопроцессорной обработкой с 20 процессорами можно запустить однопоточный процесс с интенсивным вводом/выводом, и sar покажет, что для всей системы время ожидания ввода/вывода составляет около 95%. Это создает ложное впечатление, что один поток, последовательно подающий запросы на ввод/вывод, может связать до 20 процессоров. Поэтому статистику %wio лучше вообще игнорировать. (Имеющемуся предложению скорректировать эту статистику потребуется определенное время прежде, чем оно станет стандартом.) У меня нет достаточного опыта работы с отличными от SPARC многопроцессорными системами, чтобы настаивать на некорректности этого показателя для всех платформ, но Кокрофт ссылается на свой разговор с одним из инженеров по производительности HP, по мнению которого данный показатель не соответствует истине для всех многопроцессорных систем, включая HP-UX.

Использование возможностей протоколирования при монтировании. Протоколирование при монтировании особенно полезно в тех файловых системах, где применение fsck не имеет смысла из-за имеющихся ограничений как по затраченному времени, так и по влиянию, которое оно оказывает при сбое. Ошибки могут обойтись очень дорого, поскольку могут быть утрачены последние изменения, сделанные в файлах, или даже файлы вообще не сохранятся в каталоге lost+found.

При протоколировании файловой системы изменения метаданных рассматриваются как атомарные операции в последовательности «намерение, операция, подтверждение». В силу чего проверка согласованности становится тривиальной и не занимает много времени.

Увеличение числа блоков на inode в крупных файловых системах. Файловые системы UNIX — это системы общего назначения, поэтому при их инициализации требуется часто принимать различные компромиссные решения. Для крупных систем, на которых выполняются базы данных, определенных преимуществ можно добиться с помощью настройки параметров newfs. В более старых версиях Solaris значения по умолчанию устанавливаются статически (например, в версии 2.8 значение выбирается от 2048 до 8192). Такой выбор вполне оправдан в случае системы общего назначения (например, при среднем размере файла около 2—8 Кбайт с небольшими изменениями в размере и регулярно увеличивающимися и уменьшающимися требованиями к емкости). При создании файловой системы для современного компьютера с базой данных или сервера файлов значение по умолчанию следует установить равным 500 Кбайт или больше. Это значительно сократит время на выполнение newfs.

Некоторые опции для mkfs и newfs больше не используются; они по-прежнему описаны в документации, но не оказывают влияния на современные диски. (Одним из параметров, который игнорируется, является rotdelay или gap.)

Настройка fsflush. В зависимости от объема памяти, выделенной для буферизации файловой системы, системный процесс fsflush может оказаться перегружен. Файлы, не открытые с флагом O_DSYNC, обновляются через fsflush, задача которого состоит в периодической проверке всех буферов в соответствии с двумя переменными, autoup и tune_t_fsflushr, — значение им можно присвоить в файле /etc/system.

В версиях ядра до 2.8 такое сканирование было единственным способом восстановить занятую память. Формирование свободной памяти особенно важно, когда ее ресурсы расходуют множество процессов с помощью операций чтения наподобие malloc, read(2) или mmap(2). Для систем с большим объемом памяти установленное по умолчанию значение в 30 с делает процесс fsflush чересчур дорогостоящим.

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

Задание noatime при монтировании. Иногда в файловых системах выполняются приложения, которым не нужны метаданные файловой системы уровня ОС. В этом случае время последнего доступа просто не будет использоваться, но опция mount по умолчанию поддерживает обновление времени доступа, т. е. при каждом обращении к файлу указанное значение меняется. Это может весьма серьезно сказаться на производительности. Начиная с версии Solaris 7, можно указать, чтобы при выполнении команды mount политика в отношении времени доступа игнорировалась.

Настройка maxcontig. UFS в операционной среде Solaris использует так называемую функцию «кластеризации» по типу зон extent. Значение по умолчанию не оптимально для всех файловых систем, поскольку оно зависит от приложений. Если обращение ко множеству небольших файлов происходит случайным образом, то никаких зон не нужно, а при использовании таких зон производительность может снижаться и при операциях чтения, и при операциях записи. Во время работы с более крупными файлами можно добиться выигрыша благодаря prefetch (предварительной выборки) при операциях чтения и оптимизации единицы выделения памяти за счет создания зон при операциях записи.

Что касается операций чтения, то функция формирования зон по существу представляет собой чтение с упреждением. Настройка алгоритма fetchahead выполняется просто и динамично с помощью команды tunefs(1m). Изменяемое значение maxcontig определяет число блоков файловой системы, которые считываются при чтении с упреждением. Когда процесс считывает более одного блока файловой системы, ядро будет планировать операции чтения таким образом, чтобы заполнить оставшиеся maxcontig * filesystem байт в размере блока. Одна операция чтения 8 Кбайт (или меньше) при случайном доступе к файлу не активирует fetchahead. Кроме того, fetchahead также не применяется при чтении файлов с помощью mmap.

Ядро будет пытаться автоматически определить, выполняет ли приложение небольшие случайные операции ввода/вывода или длительный, последовательный ввод/вывод. Это решение зачастую прекрасно работает, но понятия «небольшой» и «длительный» в немалой степени зависят от системных критериев для приложений, нежели от характеристик устройств. Настройка maxcontig позволяет добиться оптимальной производительности.

В версии Solaris 2.5.1 значение maxcontig по умолчанию всегда было равно 7. После этого оно менялось с учетом специфики устройства и других связанных значений.

Устройство Значение maxcontig по умолчанию
SDmaxphys
SSD1 Мбайт
Vxvmstripe_width/512k
DiskSuitemaxphys

Поскольку аппаратные устройства RAID (A3500 и T3) выполняют операцию prefetch, преимущества от ее реализации на уровне файловой системы практически сходят на нет, поэтому для этих устройств полезнее ее отключить или уменьшить maxcontig.

В случае обработки транзакций для базы данных никакие блоки предварительной выборки, как правило, не используются, поэтому все блоки, извлеченные с помощью операций чтения с упреждением, будут только увеличивать непроизводительную работу с дисками. В этом случае maxcontig следует установить равным 1. С другой стороны, для крупных файлов, обращение к которым происходит более или менее последовательным образом, увеличение maxcontig вместе с maxphys может привести к росту эффективности передачи за счет увеличения объема считываемых данных при установке головок диска на цилиндре. Лучше всего, если это значение будет сравнимо с размером цилиндра (около 1 Мбайт), т. е. maxcontig будет равен 128.

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

Маршрутизация в ядре. Наличие более одной платы сетевого интерфейса (NIC) должно, по умолчанию, предусматривать маршрутизацию в ядре между двумя подсетями. Просто добавьте файл /etc/notrouter, и сценарии инициализации не позволят этому произойти:

touch /etc/notrouter

Настройка таблицы диспетчеризации. Таблица диспетчеризации используется планировщиком ядра для выбора процессов, которые следует запускать в первую очередь, когда центральный процессор слишком занят для эксклюзивной работы с каждым из них. С классической точки зрения если процесс интенсивно занимает ресурсы центрального процессора, то он автоматически принудительно получает более низкий приоритет. Это происходит, если выясняется, что процесс еще не закончен, когда выделенный ему промежуток (квант) времени истек. Интерактивная производительность увеличивается за счет присвоения процессам более высокого приоритета, когда они «спят» (ожидая ввода/вывода) до истечения отведенного им кванта времени. Именно на основе этого классического подхода работает по умолчанию таблица диспетчеризации Time-share компании Sun.

С другой стороны, для крупных серверов с базами данных подобный подход способен породить проблемы, если интенсивно занимающая центральный процессор часть базы данных блокирует структуры данных, когда она работает с более низким приоритетом. Чтобы этого избежать, для квантов устанавливаются большее значение; такой подход известен как таблицы диспетчеризации Starfire или Cray и автоматически используется в определенных случаях на E10000, но может оказаться полезным и на других машинах. Эта возможность реализуется в разных версиях операционной среды с некоторыми отличиями. В версиях 2.5.1 и 2.6 в E10K автоматически загружается таблица с большими значениями по умолчанию. В 2.7 599 в E10K имеется специальный сценарий инициализации под названием S99bigquanta, который загружается при включении. В ядрах 2.8 загружается специфический для платформы модуль, но при этом можно задействовать и сценарий.

Любой пользователь вправе инициировать команду dispadmin -c TS -g, чтобы посмотреть, каковы эти кванты времени. Таблица с большими квантами работает от 400 до 340 мс, а с обычными — от 200 до 20 мс. Я часто прибегал к созданию нового сценария rc3.d для переключения между таблицами с разными квантами с помощью аргументов stop и start. Возможно, для системы полезно использовать в ночное время пакетный режим, а в дневное — интерактивный.

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

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

Самая быстрая файловая система. Tempfs — это не всегда самая быстрая файловая система. Тип файловой системы tempfs оптимизирован для работы с небольшими файлами и поддержки интенсивного доступа к метаданным. Выполните реальную монтировку ufs, если хотите поддерживать быстрые последовательные операции чтения. Для /tmp типичная скорость равна 12 Мбайт/с, в то время как при повторном чтении кэшированных данных ufs легко добиться 150 Мбайт/с.

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

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

alias newv=?mv /etc/vxprint.out
 /etc/vxprint.out.old;
date >/etc/vxprint.out ;vxprint
 -thr >>/etc/vxprint.out?
format 

Копии критически важных файлов. Оцените размер некоторых файлов с учетом важности настройки при сохранении критически важных файлов. Я храню резервные или «прежние» версии /etc/system, карты разделов дисков, vfstab и другую подобного рода информацию непосредственно на сервере в каталоге etc:

prtvtoc /dev/rdsk/c1t0d0s2 >/etc/vtoc.ddisk

Полная установка на крупном сервере. Нет смысла пытаться сохранить несколько сотен мегабайт только для того, чтобы выяснить, что вам необходим пакет, который устанавливается лишь в «серверной» опции.

Произведите полную установку на большом сервере.

Правила работы с coreadm. На поиск файлов ядра может уйти уйма времени, если не определены правила работы с coreadm. Порядок действий по умолчанию при сохранении файлов ядра рекомендуется поменять на обратный, выполнив limit coredumpsize 0 в каталоге /etc/.login и ulimit -c 0 в каталоге /etc/profile. В Solaris 8 управлять системными правилами работы намного проще с помощью утилиты coreadm.

Следите за /var/adm/messages. В случае возникновения проблемы обратите внимание на /var/adm/messages. Подсистемой доставки журналов ошибок можно управлять с помощью процесса syslogd. Помимо стандартных действий по занесению в журнальный файл и выводу на консоль сообщения могут быть маршрутизированы с учетом серьезности сбоев.

Утомительные процедуры монтирования. Если монтирование после выполнения umount -f окончилось неудачей, точку монтирования можно повторно инициализировать, выполнив действия: rmdir mntpoint; mkdir mntpoint.

/var/sadm/install/contents. Используйте файл /var/ sadm/install/contents для формирования очевидных ассоциаций между именем пакета и именем утилиты.

Скорость mkfile. Не стоит рассчитывать на то, что mkfile будет выполняться быстро, если установлено небольшое значение maxcontig. Операция mkfile использует размер блока, равный 8192. Это слишком мало для работы с очень большими файлами без помощи maxcontig. Если увеличить размер блока нельзя, то при инициализации крупных файлов следует перейти на другую утилиту. В этом случае прекрасно работает dd:

dd if=/dev/zero of=/misc/junk.3 bs=1024k
 count=100
timex mkfile 100m /misc/junk/junk.2

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

Печать страниц справочника man. Создайте удобочитаемые страницы справочника man, задав переменную среды TCAT в /usr/lib/lp/postscript/dpost, тогда:

man -t whatever |lp

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

0 0 ***(IFS=»»;trap ?kill 0? 0;
 vmstat 2|&while read -p 
line;do X=?date +%Y.%m.%d.%H:%M:%S?; echo $X
 $line; done) >> /tmp/vmstat. ?date +%m%d?

Боб Ларсон — инженер группы Strategic Applications Engineering компании Sun Microsystems, которая специализируется на вопросах архитектуры и производительности корпоративных серверов. Уже 12 лет Ларсон занимается настройкой производительности, разработкой приложений и ядер, а также тестами на производительность.