пятница, 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 или несоответствии их количества числу одновременно выполняющихся процессов.

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

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