E1Distributed operating system project
ГлавнаяАрхитектура Е1ДокументыКоманда
Rus
Eng
Архитек...Репликация
Архитектура E1
Концепциии E1
Распределенный объект
Обзор архитектуры
Домены защиты
Междоменные вызовы
Потоки
Компонентные сервисы
Репликация
Разработка ПО
Репликация

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

Примеры стратегий репликации

В данном разделе кратко описывается несколько широко распространенных классов стратегий репликации, составляющих основу библиотеки стратегий репликации Е1. Цель данного обзора - дать представление о возможностях подхода, основанного на репликации объектов. Подробное описание различных стратегий репликации читатель найдет в работах [9, 5, 28, 16, 2, 57, 19, 26].

Клиент-сервер

Клиент-сервер - простейшая стратегия репликации. Единственная копия состояния объекта хранится в серверной реплике. Остальные реплики являются клиентами. Все вызовы методов реплик-клиентов направляются серверу.

Стратегия репликации клиент-сервер

Стратегия репликации клиент-сервер

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

Пассивная репликация

В случае пассивной репликации [9, 5] каждая реплика хранит копию состояния объекта. Одна из реплик назначается первичной. Операции чтения выполняются локально во всех узлах. Операции, модифицирующие состояние объекта, направляются первичной реплике, которая, после выполнения метода, обновляет все остальные реплики.

Пассивная репликация

Пассивная репликация

Активная репликация

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

Активная репликация

Активная репликация

К активным стратегиям репликации относится широкий класс алгоритмов, обеспечивающих различную степень согласованности реплик распределенного объекта (последовательная [28, 16], каузальная [2], временная [57], слабая [19], пассивная (lazy) [26]) согласованность.

Миграция

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

Наиболее просто мигрировать реплику, когда в ней не выполняется ни один поток. В этом случае достаточно скопировать состояние объекта в новый узел. Иногда необходимо мигрировать реплику объекта, один или несколько методов которого выполняются длительное время или даже в течение всего времени существования объекта. Примером может являться UNIX-программа, портированная под Е1. Метод main такого объекта вызывается сразу после его создания и выполняется в течение всего времени существования объекта. Для миграции данного объекта необходимо перенести из исходного узла в целевой его состояние вместе со всеми выполняющимися в объекте потоками. Такая возможость предоставляется потоковой моделью Е1 (>> ).

Взаимодействие реплик распределенного объекта

Любая стратегия репликации предполагает наличие некоторых коммуникационных примитивов, обеспечивающих взаимодействие реплик распределенного объекта. В Е1 такие примитивы предоставляются механизмом группового удаленного вызова процедур, позволяющим обращаться непосредственно к методам удаленных объектов репликации. В основе удаленного вызова процедур лежит механизм группового взаимодействия, обеспечивающий обмен однонаправленными (unicast) и широковещательными (multicast, broadcast) сообщениями между репликами распределенного объекта с определенными гарантиями надежности, упорядоченности и времени доставки.

Механизм группового взаимодействия

Система группового взаимодействия Е1 включает два основных сервиса: сервис формирования группы и сервис доставки сообщений. В данном случае, группа - это множество реплик распределенного объекта. Сервис формирования группы позволяет динамически добавлять в группу новые реплики и удалять существующие, а также отслеживает такие изменения в составе группы, вызванные сбоями в работе узлов и сетевых соединений, как уничтожение отдельных реплик, временная или перманентная фрагментация группы. Заметим, что сохранение целостности группы после сбоев - достаточно нетривиальная задача, поскольку в асинхронной среде невозможно отличить отказ узла от его временной недоступности, вызванной задержкой при доставке сообщений [41]. Следовательно, необходим распределенный алгоритм, выявляющий доступных участников группы и достигающий соглашения относительно нового состава группы среди ее выживших членов[45]. Данный алгоритм реализуется специальным компонентом в составе сервиса формирования группы - Детектором Сбоев(ДС). В случае, если некоторые члены группы оказались недостижимы в результате разрыва сетевых соединений, а не отказа узлов, происходит фрагментация группы. При этом, ДС в каждом фрагменте формирует новую группу. Позднее фрагменты могут воссоединиться.

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

Свойство

Описание

НАДЕЖНОСТЬ ДОСТАВКИ

Ненадежная доставка

Не предоставляет каких-либо средств контроля успешной доставки сообщения.

Атомарная доставка

Гарантирует, что каждое сообщение будет либо доставлено во все пункты назначения, либо ни в один из них

ПОРЯДОК ДОСТАВКИ

Неупорядоченная доставка

Не накладывает каких-либо ограничений на порядок доставки сообщений

FIFO-доставка

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

Каузальный порядок

Сохраняет возможные причинно-следственные отношения [27] между сообщениями.

Полное упорядочивание

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

Свойства доставки сообщений

Разработка системы группового взаимодействия с нуля - весьма сложная задача, включающая имплементацию ряда распределенных алгоритмов доставки сообщений и управления составом группы. Поэтому механизм группового обмена сообщениями Е1 планируется построить на основе одной из существующих имплементаций. На сегоднящний день описанные выше сервисы реализованы в ряде систем группового взаимодействия [6, 40, 3]. Такие системы изначально ориентированы на использование в составе более сложного программного комплекса, в первую очередь, в качестве средства поддержки реплицированных сервисов. Поэтому они могут быть легко интегрированы в Е1. Кроме того, они обладают высокой модульностью, позволяющей легко расширять их поддержкой новых свойств доставки сообщений [40].

Групповой удаленный вызов процедур

Примитивы обмена сообщениями являются основой взаимодействия реплик распределенного объекта. Однако, для разработчика стратегии репликации более удобной и естественной является процедурная модель, позволяющая обращаться непосредственно к методам удаленного объекта репликации. В случае двухточечного взаимодействия для выполнения операций над удаленными объектами используется механизм удаленного вызова процедур (RPC). Обобщением RPC на случай группового взаимодействия является групповой удаленный вызов процедур(GRPC). На основе группового обмена сообщениями GRPC реализует единый примитив, позволяющий вызывать методы сразу нескольких удаленных объектов и обрабатывать результаты вызова. Архитектура механизма GRPC Е1 показана на рисунке.

Выполнение удаленного вызова посредством механизма GRPC

Выполнение удаленного вызова посредством механизма GRPC.

Как и в обычном RPC, в GRPC объекты взаимодействуют посредством клиентских и серверных стабов. Стабы компилируются автоматически из IDL-описания объекта. Клиентские стабы локально предоставляют интерфейсы удаленных объектов репликации. Каждый вызов клиентского стаба преобразуется в сообщение, которое при помощи механизма группового взаимодействия отправляется одной или нескольким удаленным репликам. Сообщение доставляется серверному стабу, который преобразует его в вызов соответствующего метода объекта репликации. Результат вызова отправляется вызывающей реплике, где он анализируется клиентским стабом. После получения необходимого числа ответных сообщений (определяемого семантикой вызова), клиентский стаб возвращает управление вызывающему объекту.

Изменение структуры распределенного объекта

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

Рассмотрим, например, сценарий восстановления распределенного объекта после фрагментации сети (см. рисунок). Исходная конфигурация объекта (рис. а) включает клиентскую реплику C, первичный сервер P и вторичный сервер B. Стрелками показаны сильные ссылки между репликами. В результате выхода из строя сетевого соединения объект распадается на три фрагмента (рис. b). Если стратегия репликации не предусматривает возможности воссоединения фрагментов в будущем и не предполагает каких-либо специальных действий, направленных на сохранение целостности объекта, то все его реплики будут удалены. Действительно, на серверные реплики (P и B) не остается ни одной сильной ссылки, а клиентская реплика не владеет копией сотояния объекта и не может успешно обрабатывать вызовы методов. Предположим, однако, что в данном примере используется вариант стратегии репликации, учитывающий возможность фрагментации. Первичная серверная реплика искусственно создает на себя сильную ссылку из корневого набора для того чтобы не быть уничтоженной системой сборки мусора (рис. с). Кроме того, поскольку данная стратегия репликации предусматривает наличие вторичного сервера, хранящего копию состояния объекта, первичный сервер создает дополнительную вторичную реплику. Все обращения к клиентской реплике возвращают ошибку, указывающую на фрагментацию объекта. Таким образом, только вторичный сервер B будет удален как мусор. Если впоследствии сетевое соединение будет восстановлено, выжившие реплики объекта могут воссоединиться (рис. d) и продолжить нормальное функционирование.

Фрагментация распределенного объекта

Фрагментация распределенного объекта

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

Проблема автоматической сериализации состояния объекта

Рассмотрим еще один важный аспект разработки распределенных объектов. Любая стратегия репликации использует некоторый набор операций, которые объект репликации может выполнить, только взаимодействуя с реплицируемым объектом семантики. Наиболее важными примерами являются сериализация и десериализация состояния объекта. Эти операции используются практически всеми стратегиями репликации при копировании состояния объекта из существующей реплики в новую, а также для синхронизации реплик. Объект репликации не располагает информацией о структуре объекта семантики, поэтому каждый объект семантики в Е1 должен предоставлять интерфейс ISerializable, содержащий методы сериализации и десериализации. ISerializable является аналогом интерфейса Checkpointable в CORBA, также предназначенного для поддержки репликации объектов [35].

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

Существуют классы языков, для которых возможно реализовать автоматическую сериализацию/десериализацию объектов. К ним относятся языки, хранящие во время выполнения информацию о типах, например, Java и C#. Авторы предвидят, что такие языки будут широко использоваться для прикладного программирования в Е1.

Однако, наряду с ними, должны поддерживаться и другие языки, в частности, С++, для которого ни на этапе компиляции программы, ни на этапе выполнения невозможно в общем случае автоматически проанализировать структуру объекта и произвести его сериализацию [48]. Поэтому хотелось бы разработать не зависящий от языка программирования метод генерации интерфейса ISerializable. В Е1 поддержка автоматической сериализации объектов предоставляется системой управления памяти. Каждый локальный объект состоит из статической части, а также динамически выделяемых данных. Для динамического выделения памяти используются объекты типа Куча (heap). Куча описывает непрерывный участок виртуального адресного пространства и предоставляет примитивы для динамического выделения и высвобождения памяти внутри этого участка. Каждый домен предоставляет локальную кучу, используемую по умолчанию всеми находящимися в нем объектами. Кроме того, любой объект может создать отдельную кучу и выделять память только из нее. Для сериализации такого объекта достаточно запаковать в некоторую структуру данных все участки памяти, выделенные данным объектом из кучи, с указанием их виртуальных адресов. При десериализации объекта создается точная копия исходной кучи в новом узле. Таким образом, сериализация/десериализация объекта семантики сводится к сериализации/десериализации кучи. В отличие от подхода, основанного на свойствах языка программирования, такой способ является универсальным. Однако, использование отдельной кучи для объекта семантики означает, что в физической памяти динамические данные объекта занимают целое число страниц, что понижает эффективность использования памяти.

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

Два способа автоматической сериализации/десериализации объекта семантики.

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

В случаях, когда язык программирования не позволяет реализовать автоматическую сериализацию состояния объекта, а использование собственной кучи для каждого объекта приводит к недопустимому расходу физической памяти, разработчик объекта самостоятельно имплементирует интерфейс ISerializable. По-видимому, данный подход будет использован для ряда системных объектов Е1.

Copyright E1 Team 2003
mail:team@E1OS.org