Библиографическое описание:

Симоненко Д. Н. Доменный подход к повышению отказоустойчивости систем выполнения [Текст] // Технические науки: проблемы и перспективы: материалы междунар. науч. конф. (г. Санкт-Петербург, март 2011 г.). — СПб.: Реноме, 2011. — С. 156-159.

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

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

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

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

Также такой подход позволяет производить верификацию кода и строить более адаптированную архитектурную модель в целом.

Остановимся на втором случае, поскольку в данном случае этот подход является более предпочтительным и безопасным.

Возникает следующий закономерный вопрос, каким образом мы можем изолировать сбои и по возможности их устранить?

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

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

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

Но для начала введем само понятие ошибки.

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

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

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

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

В данном случае необходим механизм, который:

  • может обеспечить логику переадресации запросов – маршрутизацию между объектами;

  • имеет интерфейс вызова и обращений и может ситуационно восстановить сбой в работе, при этом восстановление должно происходить прозрачным образом;

Подойти к решению этой комплексной задачи можно по крайней мере несколькими путями.

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

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
















Рис. 2. Среда выполнения, сочетающая в себе основную и

контролирующую среды.

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

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

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

Рассмотрим эту модель подробнее и введем новое понятие доменного объекта.

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

Логика работы проиллюстрирована на рис. 2. Рассмотрим её подробнее.












Рис. 2. Принцип работы доменных объектов.

(1) Объект g из пространства Y (Y.g для краткости) обращается к объекту X.n.

(2) Среда выполнения располагает информацией, что объект n ассоциирован с доменным объектом X, поэтому переводит управление на него.

Доменному объекту X сообщается, кто совершил вызов, объект вызова, тип вызова или операции, и аргументы вызова.

(3) На основе этих данных доменной объекта X передает управление в вызываемый объект n.

(4) После обработки запроса объекта n, значение возвращается обратно через доменной объект X в объект g.

(5) Если происходит сбой в объекте n, то об этом сообщается его доменному объекту X путем передачи необработанного исключения. Доменной объект производит восстановительные действия, учитывая характер ошибки. Далее, оперируя со своей структурой маршрутизации, устанавливает, что все дальнейшие вызовы к объекту n должны переадресовываться его дублеру – объекту p.

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

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

Прежде всего, необходимо проработать методы обнаружения логических ошибок, и ошибок, связанных с валидностью входных и выходных данных. Хорошим направлением в этом отношении стало введение контрактов в языке программирования D[1].

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

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

Также понятия контрактов хорошо сочетаются с концепцией модульного тестирования [2].

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

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

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

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

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

Заключение

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

На основе полученного опыта, была развита концепция единой отказоустойчивой среды выполнения[3]. Создан специализированный язык программирования и среда выполнения[4]. В настоящее время происходит адаптация предлагаемых подходов к современным требованиям и их аппробация.


Литература:
  1. D programming language. // Digital Mars, 2003.

  2. Rajendran R. White paper on Unit Testing. // Decanet Designs Lts.

  3. Симоненко Д.Н. «Концепция единой отказоустойчивой среды выполнения» // Сборник научных трудов НТЦ РУП МЭСИ №6

  4. Симоненко Д.Н. «Архитектура и реализация единой отказоустойчивой среды выполнения.» // Сборник научных трудов НТЦ РУП МЭСИ №6

Обсуждение

Социальные комментарии Cackle