По просьбам граждан излагаю свою позицию по поводу особенностей
работы Linux вообще и мейнфреймовского в частности. Чтобы не дергать
переключатель языка на клавиатуре в дальшейшем буду называть Linux
Линуксом, а мейнфреймовский Linux for System Z или zLinux - МФЛинукс.
Поскольку все, написанное ниже, будет написано быстро, и я не собираюсь
делать из своих соображений полноценную статью, то и располагаю
написанное здесь, в разделе Колонок. Ранее это было опубликовано на этом же сайте, на Блог-площадке, но коллеги указали, что заметка не соответствует формату блогов. Все, написанное ниже, является моей
субъективной точкой зрения, я вполне готов услышать аргументы в пользу
противоположной точки зрения и вполне допускаю, что где-то ошибся.
Во-первых,
хочу сразу и недвусмысленно заявить: я не являюсь ни
Линукс-ненавистником, ни даже Линукс-скептиком. Более того, именно с
Юникс-системы Демос начался мой путь на мейнфреймы, так что с Юниксом на
мейнфреймах я работаю уже больше времени, чем некоторые живут на свете.
Я свободные Юниксы люблю (Линукс в их числе), с удовольствием ими
пользуюсь в повседневной жизни, отдаю должное их вкладу в формирование
нашего ИТ-ланшафта и убежден в их огромном потенциале для будущего
развития.
Во-вторых, говоря о
Линуксе, я в большей степени буду говорить о ядре, потому что
многозадачность обеспечивается именно подпрограммами ядра. Кроме того,
именно для ядра осуществляется четких контроль вносимых изменений и
отслеживается соблюдение авторских прав. В этом смысле вне зависимости
от дистрибутива Линукс, речь будет идти о некоей общей сущности, а
значит, и об особенностях вообще всех Линуксов, включая и МФЛинукс. Ядро
- это не только базовая часть Линукса, но и одинаковая часть
дистрибутивов (при условии одинаковости версий).
Прямым
побуждением написать то, что вы тут читаете, были мои реплики на
небольшой (я бы даже сказал - камерной) встрече мейнфреймщиков в 17
декабря в зале ресторана Обломов. Там неоднократно прозвучала
формулировка «в связи с однозадачностью Линукса...». Более того,
некоторое время назад уже звучал тезис, что «для нормальной работы
установок на базе Линукс требуется применение гипервизоров». Я бы хотел
порассуждать на эту тему. При этом я не буду затрагивать вопросы
«вплетания» Линукса в WLM-конфигурации и глобальное управление
приоритетами, потому что это совершенно отдельная тема, и если тащить ее
в эту заметку, то она распухнет до неприличия.
Факт номер один:
Линукс ни в коем случае не однозадачная система. Она вполне себе
многозадачная, поддерживает параллельное выполнение нескольких адресных
пространств и нескольких задач в адресном пространстве. И поддерживал
это с самого начала, также как прародители Линукса, типа Миникса. В
составе Линукса есть хорошо разработанные средства переключения адресных
пространств, а значит, и сохранения/восстановления контекста. Все
разговоры про однозадачность Линукса (равно как и Windows) - результат
либо недопонимания, либо неверного истолкования чьих бы то ни было
вызказываний.
Факт номер два: Линукс,
как и его предшественник Миникс (разработанный Танненбаумом),
разрабатывался для процессоров вполне определенной архитектуры, а
именно, Линукс - для Intel 80386, Миникс - для Intel 80286. Он, вообще
говоря, не задумывался как многоплатформенная система. Затем, когда
стало понятно, что есть огромный общественный интерес к такой системе,
было сделано многое, чтобы повысить перносимость ядра. Оно было
определенным образом структурировано, была осуществлена стандартизация
средств обмена информацией с драйверами и предприняты огромные усилия,
чтобы локализовать машинно-зависимую часть. Именно благодаря этой работе
ядро (а также компиляторы и утилиты) перенесены на массу других
архитектур. Хочу, чтобы все меня поняли хорошо именно в этом месте.
Основа Линукса - это очень хорошо структурированное ядро, которое
фактически работает на абстрактной Intel-подобной архитектуре,
взаимодействуя с реальным оборудованием посредством хорошо
документированного набора сервисов. Поэтому портирование Линукса на
мейнфрейм было осуществлено (как гордо заявил в свое время IBM) с
помощью переработки не более 5% исходных текстов. Фактически с помощью
программной прослойки архитектура System Z была превращена в ту самую
Intel-подобную абстрактную машину, что имеет массу прямых последствий.
Но к этому мы вернемся позже.
Факт номер три:
Архитектура Intel не имеет жестко закрепленных приоритетов у
прерываний. Что это значит на практике? То, что в реальной жизни в
случае ошибок, стечения обстоятельств или преднамеренных действий
программа, обладающая достаточными полномочиями, может легко понизить
приоритет прерываний от таймера (обработка которых, вообще говоря,
критически важна для диспетчера системы и обработчиков прерываний других
типов) и от других аппаратных ресурсов. А это, с свою очередь, делает
систему непредсказуемой в случае превышения нагрузки выше некоторой
граничной величины.
Конечно, любая система
захлебывается, когда ее «заваливают» запросами и когда у нее не хватает
ресурсов на обработку этих запросов. Но на оборудовании с жестко
закрепленными приоритетами прерываний есть техническая возможность
написать программное обеспечение таким образом, чтобы система при
перегрузках не потеряла управляемости или хотя бы сообщила о недостатке
ресурсов! Вы скажете: «Какие проблемы? Давайте писать на Intele
программы так, чтобы не менять приоритеты прерываний, и все дела!». Это
было бы неплохо, но увы, ни в Windows, ни в Линукс явно запретить это
действие вам не удасться уже потому, что над целым рядом программ,
работающих с полномочиями ядра, вы не властны. Это, в частности,
драйвера оборудования. Да, Microsoft борется за качество драйверов,
подписывая их. Да, Линуксовые сборщики дистрибутивов тоже пытаются идти в
этом направлении. Но реальность такова: гарантировать
неприкосновенность приоритетов прерываний вы не можете, уже потому, что
возможность их поменять есть, а в систему лезут «третьи силы».
А
есть ли системы, куда прямым директивным способом не допускаются чужие
низкоуровневые программы? Конечно. Это - гипервизоры первого уровня. Для
них фиксируется оборудование, на которых они будут работать, сами
гипервизоры поставляются как проприетарные программные комплексы, где
нет неверифицированного производителем системного программного
обеспечения. Вот там вероятность того, что диспетчер задач получит квант
процессора вовремя, во много крат выше, чем у обычного Линукса (и
Windows тоже), что кардинально повышает устойчивость работы системы в
целом и в случае высоких нагрузок - в частности. Мы поговорим об этом
дальше, запомните эту мысль.
Факт номер четыре:
переключение контекста при переходе между адресными пространствами в
Линуксе, как и порождение адресного пространства - серьезные по объему
накладных расходов операции. Это происходит по двум причинам:
необходимость быть легко портируемой системой (а значит, пользоваться
максимально простым и переносимым механизмом сохранения и восстановления
контекста) и необходимость следовать уже прописанным соглашениям.
Вообще говоря, в расходности переключения контекста особого криминала
нет, если переключение выполняется надежно. А в надежности такого
переключения не только в Линуксе, но и в его прародителе, Юниксе SVR 4.2
у меня сомнений нет. Еще бы! Судя по исходным текстам, в Линуксе силами
самого ядра ведутся все нужные таблицы страниц и сегментов для
виртуальной памяти, все структуры данных для сохранения состояния
оборудования и контекста адресного пространства.. Эти фрагменты исходных
текстов многократно уже просмотрены, и не изменяются уже много лет.
Можете сами убедиться, если скачаете с linux.org исходники, там в
текстах тех модулей, которые относятся к переключению контекста, только
косметические изменения. Линукс очень честно (и подчеркнуто
дистанцированно от оборудования) переключается между адресными
пространствами. Диспетчер уверенно с помощью программ на C пробегает
нужные таблицы, копирует (опять же с помощью подпрограмм на C) состояние
адресного пространства, затем готовит (да-да, с помощью подпрограмм на
С) контекст нового пространства и с помощью вызова программульки на
ассемблере толкает новый процесс. Порождение процесса (fork) тоже
делается похожим образом, при этом выполняется изрядный кусок C-шных
текстов и пересылаются приличные размеры данных. Должен скажать, что это
давно никого не пугает, пока ресурсов хватает. А вот когда их не
хватает.... Это уже совсем другая история.
Предлагаю
вам всем повторить пару экспериментов, которые я провел пару месяцев
назад, выбирая конфигурацию программ и оборудования для одного своего
маленького проекта. Я взял системный блок, и поставил туда Линукс,
Ubuntu LTS без графической части. Инсталлировал Apache, MySQL и создал 4
виртуальных сайта, куда был установлен WordPress и выложен некий
контент, небольшой, только чтобы обеспечить выполнение тестов. WordPress
был использован потому, что сайты предполагалось делать на нем, и
потому, что он достаточно прожорлив - для эксперимента было интересно
обеспечить приличную нагрузку. После этого с помощью бесплатных сервисов
было проведено нагрузочное тестирование. Сначала, пока запросов было
мало, на графике зависимости времени ответа от количества запросов было
совершенно плоское плато (рост количества запросов не вызывал роста
времени ответа сайта), ресурсов системы вполне хватало для их обработки.
Далее, по достижении определенного количества запросов к сайтам (N1),
рост времени ответа системы стал линейным, зависящим от количества
запросов (система боролась, но справлялась). Затем при некоем пороге
(N2) время начало расти экспоненциально (система подходила к порогу
насыщения). В конце концов при достижении порога N3 сервер перестал
отвечать, потому что время обработки запросов стало больше сетевого
таймаута. Сервер умер. На нем работал один Линукс и четыре виртуальных
сайта. Кому интересно, посмотрите при этом, сколько адресных пространств
Апача висит в такой конфигурации (я помню, вроде 7), пара адресных
пространств MySQL, и около двух десятков адресных пространств всякой
сервисной шняги. Всего было задействовано около 800 Мбайт памяти, я
специально посмотрел, это важная информация.
Далее
я заколотил (о, это была отдельная мучительная история!) на этот же
системный блок (обычный I7 и 8 ГБайт памяти) KVM. Да, я знаю, что этот
гипервизор, может быть, не самый лучший, но у меня были конкретно
заточенный под мое оборудование продукт и инструкция по его установке
именно на системный блок Lenovo для работы с Ubuntu. После этого я, как
вы понимаете, инсталлировал четыре Линукса, в каждом из которых был
Apache, MySQL с WordPress - по одному сайту на каждый Линукс. При этом
количество адресных пространств в сумме было в разах больше, чем в
первом случае, ибо Линуксов стало 4 (с четырьмя ядрами и всей системной
шнягой), плюс сам гипервизор, который тоже вроде как специально
заточенный Линукс. То есть совокупное количество запущенных процессов на
железке выросло очень существенно. Каждому гостевому Линуксу я дал по
гигабайту памяти, предыдущий эксперимент показал, что этого должно
хватить, и, как показали дальнейшие наблюдения, хватило. Нагрузочное
тестирование было повторено. В результате было следующее. Начальное
время ответа сайтов было несколько (процентов на 30%) больше, чем в
первом случае. А вот далее была пологая-пологая линейная кривая, но
все-таки не плато. Разницу между значением N1 и N2 я поймать не смог,
так как кривая была очень пологая с постепенным увеличением угла
наклона. Но самое забавное в том, что в пределах моих бесплатных
возможностей на сервисе нагрузочного тестирования я не смог загнать
сервер в экспоненциальный рост времени ответа (граница N3), не говоря об
умирании сервера! То есть время реакции росло, оно и в начале второго
эксперимента было выше, чем в начале первой фазы первого эксперимента,
процессор молотил, диск мигал - но на сетевой тайм-аут я не вышел, все
четыре сайта (хотя и со скрипом!!) отдавали потребителям свои страницы.
Что это значит? Что диспетчер KVM упорно получал свой квант процессора и
распределял ресурсы по гостевым Линуксам, где этот квантик отдавался
соответствующим адресным пространствам Apache и MySQL.
(Обновление в процессе обсуждения - графиков нет, потому что я и не думал на этапе экспериментирования что-то подобное публиковать. Предлагаю желающим потратить недельку и повторить мои изыскания, готов выложить сюда графики).
Теперь вопрос: почему
в первом случае Линукс захлебнулся, а во втором - нет? Ведь в первом
случае совокупная нагрузка на систему была меньше, чем во втором. Было
арифметически меньше адресных пространств (процессов) и подзадач (нитей,
или тредов, как их называют в Линуксе), запросы ввода-вывода,
инициированные прикладными процессами Apache и MySQL отрабатывались
ядром и оборудованием по более короткому пути, нежели в при
использовании KVM, где ввод-вывод отбрасывается на специально выделенный
системный процесс. Более того, KVM должен был не только разбираться с
запросами на процессор и ввод-вывод, но и обслуживать запросы на память
от виртуальных Линуксов, чего в первом случае не было. Количество
переключений контекстов тоже вроде бы было существенно больше, чем в
первом случае (а это, как говорилось в факте 4, очень расходная
операция) То есть, по общим соображениям, система во втором варианте должна
была бы захлебнуться раньше, чем в первом варианте, а не только время ответа
должно быть больше. В реальной жизни, как вы можете проверить сами,
время ответа будет действительно больше, а вот граница умирания и
профиль кривой зависимости времени ответа от количества запросов будет
совсем иными. Вот правда, почему? Ведь в KVM ядро практически такое же,
как в обычном Линуксе!
Ответ, по моему мнению, вот какой.
Действительно, с учетом факта 4 (огромное количество ресурсов,
требуемых для переключения контекста), во втором случае мой системный
блок должен был захлебнуться раньше в связи с тем, что адресных
пространств стало больше. Но на самом деле вышло вот что. В первом
эксперименте (с одним ядром и 4 виртуальными сайтами) при росте
количества запросов накладные расходы, связанные с переключением
адресных пространств, в конце концов завалили диспетчер. Он уже не
столько раздавал кванты процессора пользовательским адресным
пространствам, сколько готовил под них контекст, затем давал маленький
квант и тут же готовил новый контекст. Мгого запросов - много
переключений. Фактически с ростом количества запросов именно диспетчер
со своей расходной (хотя и мобильной) дисциплиной переключения адресных
пространств в Линуксе становится ахиллесовой пятой системы, даже если
какой-нибудь кривоватый драйвер не изменит приоритета прерываний (а уж
если изменит, то оборудование и при минимальной нагрузке может уйти в
зацикливание, потому что диспетчер не получает вовремя свой квант). Вот
попадание в это состояние, когда при определенном количестве запросов
становится невозможно гарантировать получение пользовательским адресным
пространством кванта процессора в разумный промежуток времени, и дал
основание считать Линукс однозадачной системой. Ведь для того, чтобы
сдвинуть границу захлебывания приходилось уменьшать количество задач в
Линуксе, вплоть до одного-единственного, но важного пользовательского
адресного пространства! На уровне одного пользовательского процесса
можно было потреблять сколько угодно ресурсов, ядро от этого не
страдало, свой квант оно всегда отъедало, а вот роста количества
адресных пространств, особенно потребляющий чуть-чуть процессора и тут
же уходящих в ожидание, диспетчер боится как огня! А ведь именно так и
работают большинство СУБД и вообще информационных систем - короткие
процессорные запросы на доставание из устройств хранения данных и
ожидание завершения ввода-вывода.
А что
происходит во втором эксперименте? Во втором эксперименте заваливание
диспетчера не происходит потому, что запросы и адресные пространства
четко эшелонированы по уровням иерархии. На уровне первичного Линукса
(то есть KVM) адресных пространств было немного - фактически четыре
виртуальные машины с гостевыми Линуксами, адресное пространство
ввода-вывода, диспетчер и небольшое количество служебных процессов.
Диспетчер честно крутился между пятью основными потребителями ресурсов, и
на чистом железе уверенно разбрасывал эти ресурсы. Далее, внутри
виртуальных машин, ядро гостевых Линуксов тоже неплохо справлялось с
распределением выделенных, пусть небольших, ресурсов между малым
количеством основных потребителей - на один виртуальный сайт нужно
относительно небольшое количество активно потребляющих ресурсы адресных
пространств. Диспетчер KVM обрабатывал небольшое количество запросов от
оборудования и переключал малое количество адресных пространств,
поскольку львиную долю запросов от оборудования пространство
ввода-вывода отображало на гостевые Линуксы. А внутри гостевых Линуксов
было и самих запросов меньше, и адресных пространств меньше. Поэтому был
линейных рост времени ответа от количества запросов, но не произошло
насыщения системы и ее умирания.
Значит ли это,
что систему с гипервизором вообще нельзя завалить? Конечно можно! У
меня просто кончилась бесплатная квота на серверах нагрузочного
тестирования. Любые системы можно завалить, если не центральную часть,
то коммуникационную, на этом и стоят DDOS-атаки. Просто вид графика
зависимости времени реакции от количества запросов будет, как я полагаю,
несколько иной - будет линейная кривая, которая переходит в более
плавную экспоненту, которая тоже уйдет в бесконечность при полном
исчерпании аппаратных ресурсов.
В этом смысле
абсолютно предсказуемым был третий эксперимент, когда конфигурация
первого эксперимента была перенесена в среду виртуальной машины. Под KVM
в одном гостевом Линуксе были созданы 4 виртуальных сайта, и
нагрузочное тестирование было повторено. Картина в точности повторила
график первого эксперимента с тем лишь отличием, что вместо плато была
пологая, но линейная кривая, а все временные характеристики были хуже
процентов на 25-30. Веб-сайты на вопросы не отвечали, а вот консоль KVM
была вполне себе жива, и системный блок был вполне управляем. Правда, на
уровне гостевого Линукса толку от этого было мало.
То,
что проблема переключения адресных пространств в Линуксе носит
архитектурно-независимый характер, доказывает и поведение МФЛинукса. Я
не доводил ситуацию до полноразмерного эксперимента, описанного выше, но
могу сказать совершенно точно - временные характеристики работы трех
нагруженных баз данных DB2, помещенных в один МФЛинукс, были хуже, чем
работа трех МФЛинуксов под VM, в каждом из которых была только одна
база. При этом, как вы все понимаете, эффективность VM как гипервизора, в
сотни раз выше KVM-а! Понятно, почему МФЛинукс также плох в
переключении контекста, как и обычный Линукс: ведь основные подпрограммы
ядра не перерабатывались, они охраняются патентным правом,
перерабатывались только минимально необходимые компоненты, которые
работают с оборудованием и без которых некуда деться (те самые 5% кода).
Все попытки использовать преимущества архитектуры на уровне ядра
приведут к потере права называть систему Линуксом, а значит, придется
постоянно доказывать совместимость новорожденной системы с Линуксом. На
это, как мне кажется, никто сейчас не пойдет.
Формулирую короткие выводы. В
чем основное преимущество Линукса? В его переносимости и единообразии
на всех платформах. В этом же и его основная беда. Для мейнфреймовского
Линукса эта беда, в основном, выражается в отказе от использования
крайне эффективных механизмов обеспечения многозадачности и примитивная
работа с аппаратными ресурсами. Именно использование максимально
переносимых механизмов многозадачности приводит к необходимости
дополнять Линукс проприетарными гипервизорами. Для мейнфрейма, чтобы
обеспечить более высокие эксплуатационные характеристики Линукса
приходится использовать не только проприетарные гипервизоры (VM, PR/SM),
но и прямой доступ к FBA-дискам (фактически - сдвигать работу с дисками
на уровень дискового контроллера), аккуратно управлять сетевыми
адаптерами (как и с дисками, сдвигать работу с оборудованием на плечи
проприетарного гипервизора) и применять виртуальные устройства (то есть
опять же, пользоваться возможностями VM). Все это, по моему мнению, не
позволяет считать Линукс вообще и МФЛинукс в частности самодостаточными
ОС, готовыми для того, чтобы стать основой современных информационных
систем корпоративного масштаба, особенно в случаях применения
высоконагруженных критически важных приложений. Отказ от переносимости в
сторону использования возможностей оборудования для повышения
надежности и эффективности работы МФЛинукса я считаю маловероятным. |