пятница, 27 марта 2009 г.

Работа с зеркалами ZFS root pool

Когда мне пришлось делать зеркала ZFS для root pool, все было гладко и просто. И я слышал множество грозных предупреждений на тему того, что-де, и баги незакрытые есть, и проблема запуститься с половины зеркала, особенно в x86/x64. И массу других столь же жутких страшилок, о чем можно судить по поиску в Гугле и на docs.sun.com. Что-де нужно и экспорт пула выполнять, и тому подобные рукопашные процедуры, и загрузку с внешнего носителя нужно обеспечить итп.

Насколько эти жуткие истории праводподобны?

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

Итак, задача.

Есть зеркалированный root pool ZFS на i86pc (совершенно заурядный писюк с двумя A TA-дисками на 80 Гб). ОС Solaris 10 10/08 с ядром 138889-07 (установлены все обновления на сегодняшний день).

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

Оба диска содержат установленный boot loader и совершенно одинаковы.

1 подход. После успешного выполнения команды zpool detach rpool c1d1s0 и физического отключения диска загрузка новой машины с этого диска закончилась неудачей. Система вылетела в командную строку GRUB, не давая никакой возможности любого запуска. Cannot mount partition. Точка. Аминь.

2 подход. Относим второй диск обратно, аттачим к зеркалу в пул и ресильверим. Записываем GRUB на диск:

# /boot/grub/installgrub -m stage1 stage2 /dev/rdsk/c1d1s0

Затем, не выполняя detach, выключаем систему и отключаем второй диск. Вынимаем. Включаем первую систему. Естественно, zpool status показывает для второго отключенного диска UNAVAILABLE.

Детачим физически уже отсутствующий диск:

# zpool detach rpool c1d1s0

Берем вторую машину, вставляем в нее второй диск и стартуем с него.

Замечание: ВАЖНО - второй диск подключается так же, как он стоял в первой машине. То есть на тот же порт и на тот же разъем шлейфа (оба диска стоят в режиме CS).

Стартует.

zpool status показывает недоступным первый диск. Ошибок на диске нет.

Детачим отсутствующий первый диск.

Выключаем машину.

На место отсутствующего первого диска подключаем другой пустой диск.

Загружаемся с реконфигурацией.

Используем format для создания метки диска, и для разбивки слайса 0.

Аттачим первый диск ко второму. Примерно через 20 минут (после ресильверинга) - вуаля,
реконструкция завершена.

Обратите внимание: никаких архисложных манипуляций с загрузчиком, дисками, БИОСом или собственно конфигурациями ZFS.

Собственно, для окончательной расстановки точек над Ё после ресильверинга БИОС выставлялся на старт с любого из зеркал - старт выполняется.

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

Например, на родной архитектуре x64 ставим загрузку (как на SPARC) последовательно с первого и второго диска зеркалированного пула. И при полном отказе в случае рестарта системы стартуем при перезапуске с зеркала.

Замечание: Важно не забыть при добавлении дисков в зеркалированный пул записать на каждый из них загрузчик.

Все просто. Не надо усложнять сущего сверх необходимого. ;)

пятница, 20 марта 2009 г.

Solaris 10 и real time

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

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

По определению - системой реального времени называют систему, которая имеет гарантированное (и очень маленькое - в идеале чем меньше, тем лучше) время отклика.

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

Собственно, задача подразделяется на две части - так называемый hard real time (истинное реальное время, когда отклик гарантируется, что бы не выполняла в данный момент система) и soft real time (с откликом, укладывающимся в некоторые приемлемые величины допуска).

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

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

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

Причина очень проста. Водитель - и педаль тормоза. Время реакции. Или, говоря умными словами - латентность системы.

В областях high risk activity латентность системы управления должна быть минимально возможной. Дабы управляющее воздействие происходило своевременно и задержка не приводила бы к катастрофическим последствиям.

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

Обработка которых выполняется ядром монопольно (до завершения обработки прерывания ядро не выполняет других задач и новых прерываний не обрабатывает) и приводит к тому, что ОС общего назначения в лучшем случае реагирует в режиме soft real time.

Характерным примером является поведение Windows, которая в момент, когда требуется предсказуемый отклик, может неожиданно погрузиться в медитативный свопинг или другую столь же неотложную задачу, когда даже события консоли не могут ее прервать. Как это согласуется с компьютерными играми, например - видно по наличию DirectX. Обходной прямой доступ к периферии.

Однако речь не о недостатках существующих систем и их костылях (а также о попытках приспособить неприсобсабливаемое), а о решениях.

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

Первое и самое главное - ядро Солярис, хоть и не крошечное, является полностью динамическим. Что означает, что оно постоянно жонглирует ресурсами, обеспечивая выполнение процессов.

Второе - не менее важное: прерывания в Солярис являются тредами. То есть при возникновении прерывания ядро инициирует запуск процесса обработки треда, обслуживаюшего прерывания, не прекращая выполнения других тредов.

Третье - ядро Солярис является полностью прерываемым.

Четвертое - Солярис использует очень продвинутый планировщик (scheduler), позволяющий выполнять управление процессами весьа резво.

Иначе говоря, Солярис пытается реагировать в soft real time.

Насколько хорошо это у него получается? Приблизительно вот так. То есть достаточно хорошо.

Как это выглядит на практике?

Проведем небольшой эксперимент на живой системе и посмотрим, что вообще дает реальное время на Солярис.

Итак, есть сервер SPARC с двумя процессорами SPARC-IIIi 1,5 ГГц, 4 Гб памяти DDR, четыре диска SAS 10K. На сервере установлен Solaris 10/08 и Oracle10gR2.

Имеется небольшая БД с таблицей в 3,5 миллиона строк, и пакет, запрашивающий данные из этой таблицы.

Говоря точнее - база геолокации, которая по IP возвращает географические данные.

Тест.
______________________________________________________

Включен планировщик по умолчанию (TS), система перезапущена.

root @ athena # dispadmin -d TS

root @ athena # init 6

oracle @ athena ~ $ sqlplus ip2city_own

SQL*Plus: Release 10.2.0.4.0 - Production on Сб Мар 7 22:49:54 2009

Copyright (c) 1982, 2007, Oracle. All Rights Reserved.

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, Data Mining and Real Application Testing options

SQL> set timing on
SQL> select ip2city_api.getalldata('82.115.41.117') from dual;

IP2CITY_API.GETALLDATA('82.115.41.117')
--------------------------------------------------------------------------------
KZ|Kazakhstan|02|Almaty|-|43,25|76,95|-|-

Elapsed: 00:00:17.05
SQL> /

IP2CITY_API.GETALLDATA('82.115.41.117')
--------------------------------------------------------------------------------
KZ|Kazakhstan|02|Almaty|-|43,25|76,95|-|-

Elapsed: 00:00:00.34
SQL> /

IP2CITY_API.GETALLDATA('82.115.41.117')
--------------------------------------------------------------------------------
KZ|Kazakhstan|02|Almaty|-|43,25|76,95|-|-

Elapsed: 00:00:00.33

Итак, выполнение первого запроса достаточно длительное. Динамическое выделение SGA, реакция процессов (включая их запуск и планирование в очередь выполнения) - все это приводит к достаточно замедленной реакции в первом прогоне однотипного запроса.

Включим планировщик реального времени и посмотрим:

root @ athena # dispadmin -d RT

root @ athena # init 6

oracle @ athena ~ $ sqlplus ip2city_own

SQL*Plus: Release 10.2.0.4.0 - Production on Сб Мар 7 22:53:01 2009

Copyright (c) 1982, 2007, Oracle. All Rights Reserved.

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, Data Mining and Real Application Testing options

SQL> set timing on
SQL> select ip2city_api.getalldata('82.115.41.117') from dual;

IP2CITY_API.GETALLDATA('82.115.41.117')
--------------------------------------------------------------------------------
KZ|Kazakhstan|02|Almaty|-|43,25|76,95|-|-

Elapsed: 00:00:07.11
SQL> /

IP2CITY_API.GETALLDATA('82.115.41.117')
--------------------------------------------------------------------------------
KZ|Kazakhstan|02|Almaty|-|43,25|76,95|-|-

Elapsed: 00:00:00.33
SQL> /

IP2CITY_API.GETALLDATA('82.115.41.117')
--------------------------------------------------------------------------------
KZ|Kazakhstan|02|Almaty|-|43,25|76,95|-|-

Elapsed: 00:00:00.34

В чем разница?

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

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

95 processes: 94 sleeping, 1 on cpu
CPU states: 97.1% idle, 2.0% user, 0.9% kernel, 0.0% iowait, 0.0% swap
Kernel: 241 ctxsw, 43 trap, 271 intr, 899 syscall, 26 flt
Memory: 4096M phys mem, 837M free mem, 8193M total swap, 8193M free swap

PID USERNAME LWP PRI NICE SIZE RES STATE TIME CPU COMMAND
1018 oracle 11 100 -20 0K 0K sleep 0:01 1.59% oracle
1039 root 1 100 -20 3896K 2400K cpu/1 0:00 0.16% top
982 oracle 3 100 -20 31M 17M sleep 0:00 0.13% httpd
1008 oracle 11 100 -20 0K 0K sleep 0:01 0.11% oracle
1014 oracle 11 100 -20 0K 0K sleep 0:00 0.10% oracle
1028 oracle 11 100 -20 0K 0K sleep 0:01 0.10% oracle
853 oracle 1 100 -20 0K 0K sleep 0:02 0.09% oracle
986 oracle 3 100 -20 32M 17M sleep 0:00 0.05% httpd
988 oracle 3 100 -20 31M 16M sleep 0:00 0.04% httpd
869 oracle 11 100 -20 0K 0K sleep 0:06 0.04% oracle
919 oracle 3 100 -20 31M 16M sleep 0:00 0.04% httpd
863 oracle 11 100 -20 0K 0K sleep 0:01 0.02% oracle
555 root 1 100 -20 25M 19M sleep 0:02 0.02% nessusd
861 oracle 15 100 -20 0K 0K sleep 0:01 0.02% oracle
266 root 1 100 -20 3000K 1656K sleep 0:00 0.01% xntpd

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

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

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

Так ли все безоблачно? Нет ли подводных камней?

Оказывается, есть.

В реальном времени Солярис блокирует все страницы процессов в памяти.

Наиболее ощутимый отрицательный эффект - свободной памяти у системы (реально свободной) оказывается меньше.

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

Цитирую дословно документ Принстонского университета:

Real time processes also lock all their pages in memory. This can cause problems on a system that is underconfigured for the amount of memory that is required.

Это не все. Проблемы могут быть с демонами:

Since real time processes run at such a high priority, system daemons may suffer if the real time process does not permit them to run.

Также могут быть серьезные неприятности с плохо написанными приложениями:

When a real time process forks, the new process also inherits real time privileges. The programmer must take care to prevent unintended consequences. Loops can also be hard to stop, so the programmer also needs to make sure that the program does not get caught in an infinite loop.

Говоря простым языком, реальное время хорошо в Солярис для стационарных систем, с неизменным количеством процессов (сильно не варьирующимся) и запасом ресурсов, как по оперативной памяти, так и по CPU.

Что в сухом остатке?

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

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

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

Чудес не существует даже в реальном времени.