MyWackoSite : Chilim/NetworkProtocol

Разработка и реализация протокола сетевого взаимодействия для репликации данных в приложениях с ORM слоем


1 Введение

Существует множество приложений, использующих реляционные системы управления базами данных, которые в своей реализации не предназначены для работы в распределенном режиме. В частности, это относится к геоинформационным системам, основанным на централизованной модели хранения данных, которая оказывается неприменимой в сетях с большим количеством узлов. Поэтому возникает задача развертывания этих систем для работы в распределенном режиме с минимальной модификацией кода. В частности, эту задачу нужно решить для приложений, применяемых, или планирующихся для применения в органах государственного управления. При этом можно разместить части базы данных на серверах, расположенных в районных и муниципальных учреждениях. Каждое учреждение должно обладать всей информацией, необходимой для его работы, причем необходимо обеспечивать актуальность информации и распространение изменений в вышестоящие учреждения.
Для этого применяется репликация – полная или частичная синхронизация содержимого нескольких хранилищ данных [1].
Репликация может использоваться для организации распределенной работы с данными в сети, состоящей из обособленных хранилищ. С точки зрения каждого узла такой сети, его хранилище является локальной репликой, хранилища же других узлов – удаленными репликами.
В РСУБД не существует универсального способа организации репликации, особенно частичной и периодической, с сохранением целостности данных [2]. Поэтому каждое приложение, использующее РСУБД, должно реализовывать собственную схему репликации, опираясь при этом на знание модели данных и критериев их целостности. Наиболее распространенные решения, обеспечивающие репликацию в распределенных приложениях, основанных на РСУБД, подразумевают одновременное проведение транзакции на всех узлах либо полное копирование всего содержимого одной реплики в другую. Оба метода неприменимы в сетях с низкой скоростью передачи данных и низкой отказоустойчивостью.
Большинство современных приложений на основе реляционных СУБД используют объектно-реляционное отображение (ORM, Object-relational mapping) для хранения состояний объектов. Суть проблемы, которая решается с помощью ORM-слоя, заключается в необходимости преобразования объектных структур в памяти приложения в форму, удобную для сохранения в реляционных базах данных, а также для решения обратной задачи—развертывания реляционной модели в объектную с сохранением свойств объектов и отношений между ними.
Посредством ORM объекты бизнес логики приложения транслируются в строки таблиц БД. При этом нередко целостность данных сводится к поддержанию целостности состояния отдельных объектов. В этих условиях для обеспечения целостности связей может оказаться достаточно осуществлять репликацию на уровне объектов. Цель проекта Relational DataBase Replication (RDBR), разрабатываемого в лаборатории «Parallels», заключается в реализации механизма репликации объектно-реляционных данных, приспособленного к плохим каналам связи.
Задача RDBR состоит в том, чтобы обеспечить репликацию в оффлайн-режиме, когда изменение данных происходит независимо в каждой реплике, а синхронизация содержимого обеспечивается за счет анализа метаинформации об этих изменениях, которой обмениваются узлы во время сеанса репликации. В связи с этим, возникает потребность в создании отдельного модуля, обеспечивающего сетевое взаимодействие узлов.
Задача, поставленная перед автором в рамках проекта RDBR: разработка и реализация протокола сетевого взаимодействия для репликации данных в приложениях с ORM слоем.

2 Relational DataBase Replication Project

2.1 Цель проекта

Как уже упоминалось, в общем случае возможно несколько способов синхронизации данных:
1.при обращении к СУБД на запись соответствующая транзакция проводится на всех синхронизируемых узлах одновременно;
2.создается дамп всей БД одного узла и импортируется в БД другого;
Также возможно использование специфичных для конкретной СУБД средств.
Оба решения неприменимы в сети с низкой отказоустойчивостью и низкой скоростью передачи данных, в особенности первый способ, где отключение узла от сети приводит к необходимости использования иных средств синхронизации с другими узлами кластера. Передача дампа БД по сети с пропускной способностью в несколько КБ/сек. может занять неприемлемо длительное время, за которое данные на узлах изменятся так, что необходимо будет повторить процесс заново. Штатные средства производителя СУБД можно применять, главным образом, в случаях, когда приложение использует в качестве локального хранилища именно данную СУБД. Но более распространена обратная ситуация, когда данное приложение для обработки и хранения информации использует различные СУБД.
Таким образом, механизм репликации для таких сетей должен обладать рядом свойств:
1.поддерживать продолжение репликации после обрыва связи;
2.передавать минимальное количество информации;
3.быть универсальным как с точки зрения работы с различными СУБД, так и с точки зрения реализации на различных языках программирования;
Конечной целью проекта является создание системы репликации на объектном уровне, удовлетворяющей перечисленным выше требованиям.

2.2 Репликация RDBR

Механизм, обеспечивающий репликацию RDBR, отслеживает обращения приложения к ORM-слою на запись в базу и сохраняет необходимые для репликации метаданные в отдельной таблице той же СУБД. Метаданные для каждого объекта включают в себя уникальный в рамках всей сети идентификатор (GID, Global ID), временные штампы, а также флаг удаления объекта из базы.
GID представляет собой объединение имени класса объекта и hash-код его уникальных полей. В качестве временных штампов объекта используются:
1.время фактической модификации атрибутов;
2.время его сохранения в локальной реплике;
Данной информации достаточно для организации репликации методом «распространения слухов» [1].
При удалении объекта из базы, в его метаинформации устанавливается специальный флаг, что позволяет рассматривать удаление как частный случай модификации. Метаинформация об удаленных объектах имеет ограниченное время жизни. Это время можно установить. По умолчанию оно составляет 90 дней.
БД определяются идентификатором реплики (replica ID), который представляет собой строку удобную для восприятия. Эта строка на самом деле соответствует адресу узла репликации. Каждая реплика хранит историю проведенных операций (replication history) – времена последних успешных репликаций со всеми серверами, с которыми она когда-либо происходила.
В репликации участвуют два узла, при этом в общих чертах механизм выглядит следующим образом (более подробно он будет описан в разд. 3.1): каждый из взаимодействующих узлов составляет специальный документ, содержащий описанную выше метаинформацию об измененных с даты последней удачной репликации объектах; далее происходит обмен этой информацией, разрешаются возможные конфликты несогласованных модификаций в обеих репликах, а затем составляются списки объектов для отправки.
Таким образом, можно выделить основные составляющие такого механизма:
1.Как можно более стандартизированный формат записи метаинформации и самих объектов;
2.Клиент-серверная часть, реализующая непосредственно обмен данными;
3.Средства объектно-реляционного отображения;
В качестве последнего было решено использовать библиотеку Hibernate [3], имеющую реализацию на языках Java и C#. В качестве стандартизированного формата представления данных используется XML (для обмена метаинформацией используется формат RSS). Клиент-серверную часть решено было реализовать в виде web-приложения на языке Java.

2.3 Архитектура RDBR

В качестве тестового приложения используется система управления контентом XWiki, также представляющая собой web-приложение Tomcat. Для сбора метаинформации используется предложенный разработчиками Hibernate интерфейс Interceptor [3], методы которого вызываются при обращении к СУБД. Таким образом, модификация Hibernate должна быть прозрачной для бизнес-приложения, что позволит внедрить RDBR в уже существующие системы. Прототип репликатора, использующий Hibernate для хранения информации в реляционной СУБД, состоит из следующих основных компонентов (рис. 1):

file:!/ff_5312_litvinenko_ilya_diplom_picture1.jpg
Рис. 1: Структурная организация репликатора.

1.Библиотека DBAbstractionLayer, реализующая сбор репликационной метаинформации и предоставляющая доступ к базе данных для компонента Replication Manager.
2.ReplicationManager – основная подсистема – представляет собой сервер репликатора (набор Java-сервлетов, обрабатывающих HTTP-запросы) и сервис, исполняющий активную роль (клиент, инициирующий соединение с сервером на другом узле).
Сетевое взаимодействие узлов репликации предоставляет RDBR Network protocol.
Благодаря такой архитектуре приложение никак не связано с системой репликации. При этом система репликации связана с СУБД посредством библиотеки DBAbstractionLayer, что позволяет заменить лишь её при использовании другой библиотеки ORM, вместо Hibernate.
В прототипе репликатора узлы репликационной сети обмениваются информацией в режиме «один к одному», еще не поддерживается частичная репликация (т.е. все БД имеют одинаковый набор данных после успешного окончания репликации). Следующий прототип будет обеспечивать одновременную репликацию с несколькими узлами, полную автоматизацию управления репликацией, представленную выделенным узлом-менеджером и соответствующим протоколом обмена данными между менеджером и остальными узлами. Возможным будет как ручное редактирование топологии репликационной сети, так и автоматическое, основанное на статистике частоты изменений на узле, скорости обмена данными с узлом и средней нагрузки [5]. В дальнейшем планируется реализация частичной репликации.

2.4 Требования к бизнес-приложению

Использование ORM в RDBR накладывают ряд ограничений и требований к бизнес-приложению. Так как перенос каждого объекта представляет собой отдельную транзакцию, то в процессе репликации бизнес-логике приложения будет доступно частично отреплицированное множество объектов. Поэтому либо бизнес-логика приложения должна рассматривать практически любое сочетание объектов как консистентные данные, либо те объекты, для которых это требование выполнить невозможно, должны реплицироваться другим способом.
На текущий момент RDBR выдвигает к приложению следующие требования:
1.Универсальный (относительно различных копий приложения) алгоритм генерации идентификаторов объектов, либо такой алгоритм работы с объектами и идентификаторами, чтобы в случае совместного использования двумя приложениями одной базы, не возникало коллизий;
2.Корректная работа с частично отреплицированным множеством объектов;
3.Синхронизация времени на серверах, поскольку именно временные штампы играют главную роль при обработке метаинформации;
4.В каждую таблицу посредством ORM должен отображаться один класс;
5.Все отображенные классы должны допускать загрузку по идентификатору;
2.5 Место сетевого слоя в RDBR

В RDBR репликация происходит между двумя серверами. Для передачи между репликационными узлами метаинформации об изменениях и сериализованных в XML объектов, собираемых библиотекой DBAbstractionLayer, используется RDBRNetwork protocol, реализованный в сетевой части. Таким образом, сетевой слой обеспечивает передачу объектов из одной БД в другую.

3 Постановка задачи

3.1 Механизм репликации RDBR

Поскольку одним из основных требований является отказоустойчивость системы при сбоях у части участников, то для сетевой части предполагается выбрать архитектуру peer-to-peer (P2P). Таким образом, сеть сможет содержать много узлов, работа которых будет происходить по схеме «точка-точка». Пиринговые сети также обладают следующими существенными особенностями:
отсутствие центрального сервера;
равные права участников;
прямое взаимодействие узлов;
Как уже упоминалось, проект RDBR обеспечивает репликацию в оффлайн-режиме. Рассмотрим, как должна производиться репликация между двумя узлами (рис. 2):
Одна машина – назовем её Alice (или Node 1) – инициирует репликацию, вторая – назовем её Bob (или Node 2) – принимает соединение (рис. 1). Репликация обязана инициироваться по явному запросу пользователя или по расписанию.
Когда Alice установит соединение с Bob-ом, и, если оно успешно состоится, то инициатор репликации должен составить XML-сообщение в RSS-формате (пример 1), содержащее метаинформацию об измененных с даты последней удачной репликации объектах в своей реплике базы. Затем, после выполнения запроса №1, инициатор должен получить RSS сообщение, содержащее метаинформацию об изменениях со стороны удаленной реплики. После выполнения запроса №2, Bob-у необходимо заблокироваться для работы с Alice, используя её replica_id. Это означает, что сервер удаленной реплики будет работать только с данным узлом, до окончания репликации. Далее инициатору нужно будет проанализировать списки изменений, и сформировать окончательные списки (export list и import list), содержащие информацию об объектах, подлежащих передаче и соответственно закачиванию с узла удаленной реплики. При анализе метаинформации возможны следующие ситуации:
1.Объект изменен в реплике Alice, но не менялся или отсутствует в реплике Bob. Метаинформация в этом случае добавляется в список экспорта;
2.Объект изменен в реплике Bob, но не менялся или отсутствует в реплике Alice. Метаинформация в этом случае добавляется в список импорта;
3.Объект изменен в обеих репликах, и временной штамп последнего изменения совпадает. Это значит, что Alice или Bob получили это изменение, каким-то другим путем, через другие узлы репликации, или во время аварийно прервавшейся попытки репликации, при которой была передана часть объектов, но не была обновлена история репликации. Передача этого объекта не требуется;
4.Объект изменен на обоих узлах, и временные штампы не совпадают. Данная ситуация считается конфликтом репликации, а такой объект объявляется конфликтным. Разрешение конфликтов, в зависимости от приложения, должно возлагается либо на пользователя, либо на администратора, либо на бизнес-логику приложения;
Важно отметить, что начальный отбор метаинформации об объектах производится по времени сохранения их в локальной реплике, а сравниваются затем даты модификаций.
После окончательно сформированных export и import list удаленному узлу по запросу №3 необходимо отправить RSS документ, содержащий информацию об объектах, которые ему нужно передать, и запустить транспортные потоки:
При выполнении ObjectReceiverThread инициатор репликации должен закачать объекты в соответствии с import list по запросу №4. При этом для каждого переданного объекта необходимо отправить отчет по запросу №5 о его успешном сохранении в локальной реплике.
При выполнении Object Sender Thread Alice нужно начать выталкивать объекты в соответствие с export list по запросу №6. В качестве ответа необходимо получать отчеты об успешном сохранении переданных объектах в удаленной реплике.
Передача и получение каждого объекта будет оформляться в одну транзакцию, что позволит корректно обрабатывать ошибки соединений в сетях с плохим качеством связи.
После выполнения запроса №7 инициатору необходимо закончить репликацию. При этом на сервере обязана сняться блокировка для работы только с данным узлом. Если репликация закончиться удачно, т.е. будут сохранены все переданные и полученные объекты то должна обновиться история репликации на обоих узлах. В случае обрыва соединения между №2–7 запросами, с сервера нужно снять блокировку по таймауту. При этом репликация должна считаться незавершенной.

file:!/ff_5312_litvinenko_ilya_diplom_picture2.jpg
Рис. 2: Механизм репликации RDBR.

Пример 1: RSS для import document

<rss version="2.0">
<channel>
<title>http://10.4.0.102:8080/Replicator</title>
<link>http://10.4.0.102:8080/Replicator/server_transport.perform</link>
<description/>
<lastBuildDate>4/5/09 7:44:46 AM UTC</lastBuildDate>
<item>
<link>com.xpn.xwiki.doc.XWikiDocument@000000040000000106cd5ce1</link>
<description/>
<pubDate>4/5/09 7:48:03 AM UTC</pubDate>
<saveDate>4/5/09 7:48:03 AM UTC</saveDate>
</item>
</channel>
</rss>

3.2 Задача, поставленная перед автором

При репликации ключевое значение имеет качество каналов связи. Поэтому нужен отдельный модуль, обеспечивающий сетевое взаимодействие репликационных узлов. При этом должны выполняться следующие требования:
1.приспособленность к плохим каналам связи, с пропускной способностью в несколько Кб/сек;
2.обеспечение конфиденциальности и сжатия передаваемой информации;
Задача автора в проекте RDBR: разработка и реализация протокола сетевого взаимодействия репликационных узлов в рамках реализации механизма репликации данных в приложениях с ORM слоем для выполнения вышеупомянутых требований.
На базе данного протокола необходимо реализовать вышеупомянутый механизм репликации.

4 Протокол сетевого взаимодействия RDBR
4.1 Общие сведения

RDBR Network protocol описывает алгоритм передачи контрольных сообщений и сериализованных объектов между репликационными узлами. Он написан поверх протокола HTTP [9] и использует GET и POST запросы для взаимодействия. Также предусмотрена возможность использования расширения HTTP, поддерживающего шифрование (HTTPS) с помощью SSL (Secure Sockets Layer), что позволяет применять протокол для передачи конфиденциальных данных. В качестве платформы для реализации используются Java-сервлеты, что дает дополнительный плюс: отсутствие необходимости открытия еще одного порта за исключением уже созданного веб-сервером.

4.2 Реализация

RDBR Network protocol состоит из двух независимых компонент (рис. 3): серверной и клиентской.
Клиентская часть (рис. 4) предоставляет приложению набор классов, которые позволяют отправить запрос серверу. Серверная часть реализована на Java-сервлетах (рис. 6) обрабатывает запросы и отвечает на них.
Дополнительным необходимым компонентом для реализации протокола является Web-сервер c поддержкой java-сервлетов и HTTP соединений (рис. 7).

file:!/ff_5312_litvinenko_ilya_diplom_picture3.jpg
Рис. 3: UML-диаграмма пакетов.

file:!/ff_5312_litvinenko_ilya_diplom_picture4.jpg
Рис. 4: UML-диаграмма классов пакета client.

file:!/ff_5312_litvinenko_ilya_diplom_picture5.jpg
Рис. 5: UML-диаграмма классов пакета wrapstream.

file:!/ff_5312_litvinenko_ilya_diplom_picture6.jpg
Рис. 6: UML-диаграмма классов пакета server.

file:!/ff_5312_litvinenko_ilya_diplom_picture7.jpg
Рис. 7: Логическое представление структуры протокола RDBR.

RDBR Network protocol предусматривает передачу данных в виде XML. Избыточность синтаксиса XML порождает соответствующий недостаток: большой размер сообщений. Для решения данной проблемы в протокол встроены средства компрессии и декомпрессии передаваемой информации, которые реализованы с использованием стандартной библиотеки java.util.zip.
Важной задачей было приспособить протокол к передаче объектов, которые не реализуют интерфейс java.io.Serializable. Существует множество способов сериализовать Java-объект в XML и, соответственно, десериализовать. В SDK входят Java Architecture for XML Binding (JAXB) и связка XMLEncoder – XMLDecoder. Так же существует ряд сторонних библиотек для решения данной задачи. Одной из таких библиотек является xstream, которая предоставляет следующие возможности для сериализации:
Сериализуемые классы не обязаны реализовывать интерфейс Serializable;
Для получения списка полей класса и значений этих полей используется Reflection API;
Константы не сериализуются;
Поля с модификатором transient не сериализуются;
Коллекции и связанные классы сериализуются прозрачно. Никаких дополнительных действий предпринимать не надо;
Формирование XML возможно через несколько поддерживаемых библиотек;
Вид результирующего XML удобно настраивается как с помощью методов, так и с помощью Annotation;
Можно управлять процессом генерации XML. Имеется возможность самостоятельно описывать процедуры сериализации/десериализации для того или иного класса;
Из-за описанных выше свойств было решено использовать xstream в RDBR Network protocol для сериализации объектов в XML.
xstrem предоставляет альтернативную реализацию java.io.ObjectInputStream и java.io.ObjectOutputStream, позволяющую сериализовать/десериализовать потоки объектов в/из XML не реализующих интерфейс java.io.Serializable. Именно эта возможность используется в RDBR Network protocol. Рассмотрим пример сериализации (пример 2) и десериализация (пример 3) объекта (toSend) посредством xstream.

Пример 2: Сериализация объекта в XML

XStream xstream = new XStream();
Collection<Object> toSend = new Hash Set<Object>();
toSend.add(new Data());
toSend.add(new Integer(0));
Byte Array Output Stream outputStr = new Byte Array Output Stream();
Object Output Stream oos = xstream.createObjectOutputStream(outputStr);
oos.writeObject(toSend);
oos.close();
outputStr.close();
Пример 3: Десериализация объекта из XML
XStream xstream = new XStream();
Collection<Object> toGet = new Hash Set<Object>();
Object Input Stream objectInput = xstream.createObjectInputStream(inputStr);
toGet = (Collection<Object>) objectInput.readObject();

Сериализованный в XML объект будет выглядеть следующим образом (пример 4):

Пример 4: Метод System.out.println(outputStr)

<object-stream>
<set>
<date>2009–05–27 16:37:15.51 NOVST</date>
<int>0</int>
</set>
</object-stream>
4.3 Программный интерфейс, предоставляемый пакетами

Рассмотрим основные классы и методы клиентской компоненты протокола (рис. 4):
net.client.ConnectionFactory
Реализуя шаблон “Фабрика” [10], создает соединения с удаленными узлами и возвращает Http Connection для обычных сессий HTTP или Https Connection при защищенном соединении.
net.client.Connection
Методы классов, реализующих этот интерфейс, предназначены для отправки запросов и обработки ответов на них, полученных в той же сессии. Рассмотрим их:
sendGetRequest(Map<String, String> sessionParameters) :Wrapped Input Stream
Создает новую сессию HTTP(S) с параметрами sessionParameters типа <ключ=значение> и посылает в нее Get-запрос. Данные, посланные серверной частью, с которой установлено соединение, в ответ на идентификатор запроса, присутствующий в параметрах сессии, будут доступны клиентской части в возвращаемом потоке. После получения ответа на запрос созданная HTTP(S)-сессия закрывается.
sendPostRequest(Map sessionParameters, Object data) :Wrapped Input Stream
В отличие от предыдущего метода, в новой сессии будет создан Post-запрос. Этот тип HTTP(S)-запроса отличается тем, что используется для передачи не только параметров сессии sessionParameters, но и объекта data удаленному узлу. Ответ сервера также будет доступен через возвращаемый поток.
Рассмотрим классы потоков данных (рис. 5): net.wrapstream.WrappedInputStream и net.wrapstream.WrappedOutputStream наследуются от соответствующих потоков (рис. 4), что позволяет использовать всю их функциональность. Отличительной особенностью является то, что Wrapped Output Stream перед записью любой информации сериализует её в XML а затем сжимает. Wrapped Output Stream разархивирует и десериализует информацию при чтении.

4.4 Серверная компонента реализации протокола

Основой серверной компоненты (рис. 5) является сервлет net.server.Server. net.server.ActionFactory содержит поле Map<String, Class<?>> mapServletNames, в которое включены названия классов на которые net.server.Server перенаправляет все запросы-<Control Servlet.perform,Control Servlet.class> и <Transport Servlet.perform, Transport Servlet.class>. Рассмотрим их:
Control Servlet – класс, обрабатывающий все запросы до обмена объектами между репликационными узлами.
Transport Servlet – класс, отвечающий за получение и передачу, измененных с даты последней удачной репликации, объектов.
Для подключения серверной компоненты, сервлету нужно сопоставить URL в конфигурационном файле контейнера. К примеру, если в качестве контейнера выступает Apache Tomcat, работающий на узле с ip=10.4.0.112 по порту 8080, то для отображения Transport Servlet на URL=http://10.4.0.112:8080/TransportServlet.perfrm в Apache Tomcat нужно в файле web.xml добавить (пример 5):

Пример 5: Настройка web.xml

<servlet>
<servlet-name>server</servlet-name>
<servlet-class>
ru.nsu.swsoft.parallels.net.server.model.Server
</servlet-class>
<load-on-startup />
</servlet>
<servlet-mapping>
<servlet-name>server</servlet-name>
<url-pattern>Transport Servlet.perform</url-pattern>
</servlet-mapping>

Настройка отображения Control Servlet делается аналогично.
Рассмотрим пример POST запроса, посылающего коллекцию объектов от клиента на сервер к классу Transport Servlet, находящемуся на узле с URL = ”http://10.4.0.112:8080/ Transport Servlet.perform” (пример 6):
Пример 6: Отправка коллекции объектов
Connection connection = Connection Factory.create Http(URL);
Map<String, String> parameters = new Hash Map<String, String>();
parameters.put(«node_id»,"http://10.4.0.102:8080/Replicator" );
parameters.put(«ids», “none”);
parameters.put(«action», “post_objects”);
Collection<Object> toSend = new Hash Set<Object>();
toSend.add(new Date());
toSend.add(new Integer(0));
Wrapped Input Stream stream = connection.sendPostRequest(parameters,toSend);

Здесь node_id – идентификатор узла, который посылает объекты, action – выполняемое действие, а ids – уникальные в рамках всей сети идентификаторы (Global ID’s) объектов, которые нужно передать клиенту от сервера.
Объединения node_id, ids, action составляют контрольные сообщения. Рассмотрим их варианты (табл. 1):

Таблица 1:Контрольные сообщения
node_id action ids Request Type / Content Server response in format XML 
1 requiredinit unrequired GET/none Если успешное выполнение запроса то RSS, содержащее метаинформацию об измененных объектах с даты последней удачной репликации с репликой клиента. В противном случае XML с причиной отказа.
2 required startunrequired GET/none Если сервер не занят и может начать сеанс репликации с node_id (инициатором репликации), возвращается true; в противном случае – false
3 required post_rss unrequired POST/RSS-содержащая метаинформацию об объектах которые нужно скачать серверу Если успешное выполнение запроса, то RSS is got; в противном случае false с указанием причины
4 required get_objects required GET/none Объекты, идентификаторы которых перечислены в параметре ids 
5 required post_reports unrequired POST/Отчет о успешном сохранении объекта в реплике клиента Если успешное выполнение запроса, то Reports are supplied; в противном случае error с указанием причины
6 required post_objects unrequired POST/объект Отчет о успешном сохранении объекта в реплике сервера
7 required doneunrequiredGET/none Если успешное выполнение запроса, то true; в противном случае false с указанием причины

4.5 Результаты

Автором разработан и реализован протокол сетевого взаимодействия репликационных узлов. Контрольные сообщения и сериализованные объекты посылаются посредством клиентской компоненты протокола в виде сжатого XML. Серверная компонента, получая определенные запросы (таблица 1) выполняет необходимую для репликации последовательность действий по их обработке (рис. 8):

file:!/ff_5312_litvinenko_ilya_diplom_picture8.jpg
Рис. 8: Диаграмма деятельности серверной компоненты.

1.При получении контрольного сообщения № 1, серверная компонента протокола генерирует RSS документ, содержащий метаинформацию об измененных с даты последней удачной репликации объектах в своей реплике базы. Затем этот документ отправляется инициатору запроса.
2.При получении контрольного сообщения № 2, сервер блокируется для работы с инициатором, используя в качестве идентификатора поле node_id контрольного сообщения.
3.При получении контрольного сообщения № 3, сервер сохраняет у себя присланный RSS документ, содержащий информацию об объектах которые нужно получить,
4.При получении контрольного сообщения № 4, сервер отправляет в ответ инициатору запроса объекты, идентификаторы которых перечислены в параметре ids.
5.При получении контрольного сообщения № 5, сервер проверяет присланный ему отчет о сохранении объекта. Затем данная информация будет использоваться для обновления истории репликации.
6.При получении контрольного сообщения № 6, сервер получает объект, и сохраняет его в своей реплике базы. Затем генерируется отчет об успешном, или нет сохранении объекта, который отправляется в ответ инициатору запроса.
7.При получении контрольного сообщения № 7, сервер снимает блокировку с инициатора репликации. Затем, если все отчеты о сохранении объектов, полученные от инициатора, успешны то обновляется история репликации.
В случае обрыва соединения между запросами №2–7, сервер снимает блокировку с инициатора репликации по таймауту.
На базе RDBR Network protocol реализован описанный выше (см. разд. 3.1) механизм репликации (рис. 2, active_side). Необходимая последовательность действий выполняется в отдельном потоке ReplicationWorkThread.

4.6 Сравнение с аналогами

4.6.1 Lotus Notes/Domino

Механизм репликации RDBR построен по аналогии с механизмом, применяющимся в распределенной нереляционной СУБД Lotus Notes/Domino [1,4,7].
Базы данных в Notes/Domino представляют собой коллекции документов (note). Документ являются основной единицей хранения данных, а его структура определяется формой, содержащей в себе набор полей различных типов, называемых элементами (item). Изменение документа в БД происходит транзакционно. Это означает, что все элементы в документе изменяются одновременно либо не изменяются вообще. Каждый элемент характеризуется UNID (Universal Note Identifier – универсальный идентификатор документа) своего документа, а также именем и серийным номером, определяющим количество изменений этого элемента. После успешной репликации соответствующие элементы в репликах будут иметь одинаковые значения и серийные номера. Документ имеет два временных штампа:
1.время модификации документа. Это время последнего изменения значения любого из элементов или время добавления или удаление элемента в документ;
2.время последнего изменения документа в этом реплике, то есть время последней репликации, при которой этот документ был изменен.
После удаления документа из базы его элементы удаляются, а на месте документа остается пенек (stub), в котором сохраняется UNID документа. Пеньки хранятся в специальной таблице, и имеют ограниченное время жизни, которое превосходит полный цикл распространения изменений между всеми репликами. По умолчанию это время составляет 90 дней. Таким образом, удаление рассматривается как частный случай модификации объекта.
БД идентифицируются идентификатором реплики (replica ID), который представляет собой время создания БД с точностью до миллисекунд, а также сервером или клиентской машиной, на которой БД находится. Каждая реплика хранит историю репликации (replication history) – времена последних успешных репликаций со всеми серверами, с которыми репликация когда либо происходила.
Основные отличия механизма репликации Lotus Notes/Domino от RDBR заключаются в следующем:
В Notes/Domino в начале репликации происходит построение списка реплицируемых баз, то есть организованна частичная репликация. В RDBR такая возможность на данный момент не реализована.
В Notes/Domino передача и получение каждого документа оформляется в одну транзакцию. При этом передача изменений в документе происходит поэлементно, то есть аналогично тому, как сравнивались временные штампы документов, сравниваются серийные номера на каждом из элементов и передаются только те элементы, которые были изменены. При этом гарантируется целостность документов. В RDBR, с точки зрения схемы репликации, объект рассматривается как аналог документа Lotus Notes/Domino.
В Notes/Domino при построении списка документов, измененных с даты последней удачной репликации, учитываются права доступа для каждого документа в обеих репликах. В текущей версии RDBR данная возможность не реализована.
В системе Lotus Notes/Domino топология соединений между серверами определяется на основании документов подключения (Connection) Корпоративной Адресной книги (Domino Directory), которую вручную должен настроить администратор сети. Репликация может инициироваться по запросу пользователя или по расписанию. Обычно расписание составляется так, чтобы один из серверов периодически вызывал другой (документ Connection для поддержки репликаций создаётся только на стороне вызывающего сервера, на другой стороне обычно документ заводится для поддержки маршрутизации почты). В RDBR топология соединений между серверами также задается вручную. Опыт эксплуатации Lotus Notes/Domino утверждает, что для сети разумного размера это приемлемо.
Для аутентификации Notes/Domino использует схему на основе алгоритма с открытым ключом. Каждый сервер имеет свой приватный ключ RSA, а также публичный ключ зарегистрированного пользователя. При аутентификации пользователя на сервере, они обмениваются сертификатами и публичными ключами. Для этого в Notes/Domino используется собственный протокол. RDBR же для аутентификации использует стандартный протокол HTTPS. Данное решение выбрано из за того что HTTPS стандартизован, прост в использовании и использует SSL.
Основные преимущества RDBR заключаются в том, что система построена на открытых протоколах(RSS, HTTP, HTTPS) и использует реляционное хранилище, которое можно применить для построения сложных отчетов. Notes/Domino это не реляционная СУБД. В ней нельзя делать сложные запросы с использованием информации, которой нет в документе. Это ограничивает их приминимость для построения сложных отчетов.
Одним из наибольших недостатков Notes/Domino является отсутствие публичной спецификации протокола, который используется клиентами продукта для связи с серверами. Известно, что протокол является специализированным RPC (Remote Procedure Call — вызов удаленных процедур).

4.6.2 db4o Replication System

Идея репликации объектно-реляционных данных посредством передачи объектов была реализована в продукте dRS (db4o replication system) [6,8], который позволяет реплицировать РСУБД с помощью Hibernate. Реплицирующиеся РСУБД называются провайдерами и имеют уникальные идентификаторы. Для того чтобы отслеживать измененные посредством Hibernate объекты, нужно особым образом настроить сессию Hibernate. После настройки сессии устанавливается перехватчик, который для каждого нового объекта генерирует UUID (Unique universal identifier), а измененным объектам увеличивает номер версии. dRS для поддержки репликации создает в БД таблицу, содержащую историю репликации со всеми провайдерами. Для каждого провайдера хранится максимальная версия среди объектов локальной и удаленной реплики на момент окончания последней репликации. Для начала репликации клиенту dRS нужно указать конфигурационные файлы Hibernate (hibernate.cfg.xml) для обоих РСУБД. В процессе репликации клиент создает соединения между реплицирующимися базами данных, используя стандартные API Hibernate.
Механизм репликации dRS выглядит следующим образом:
1.Инициализация: проверка того, что указанные в конфигурации провайдеры существуют, и что пользователь с данным паролем имеет необходимые права для доступа к РСУБД.
2.Проверка версий: в начале репликации проверяются номера версий, установленных после последней репликации друг с другом. Если они не совпадают, то возникает ошибочная ситуация и репликации не происходит.
3.Поиск изменений: список измененных объектов строится по номерам версий объектов, то есть если номер версии объекта больше номера записанного в истории репликации, то он был модифицирован после последней удачной репликации.
4.Репликация: может производиться как в одну сторону (все объекты, измененные со времени последней репликации, отсылаются от одного провайдера второму), так и в обе (тогда повторяется та же операция, но от другого провайдера). Конфликты репликации разрешаются сразу после передачи или получения объекта, решение возлагается на бизнес-логику приложения или на пользователя.
5.Репликация удаленных объектов: проводится отдельно от остальных. При этом просматриваются объекты обеих реплик, и при обнаружении удаленного объекта на одной стороне он удаляется на другой.
6.Подтверждение репликации: все изменения сохраняются в базе данных, и обновляется история репликации.
Вся сессия репликации рассматривается как одна транзакция.

Рассмотрим основные отличия dRS от RDBR:
1.dRS жестко привязан к библиотеке Hibernate. RDBR для работы с базой данных имеет собственный дополнительный слой DBAbstractionLayer, и соответственно, концептуально не зависит от Hibernate;
2.dRS требует прямой доступ к серверам СУБД, с которыми работает, в отличие от RDBR, где узлам репликации достаточна HTTP связь в одном направлении;
3.dRS рассматривает сессию репликации как одну транзакцию и при обрыве соединения откатывает все изменения. В RDBR передача и получение каждого объекта оформляется в одну транзакцию.


5 Заключение

В ходе данной работы был разработан и реализован протокол сетевого взаимодействия репликационных узлов, предназначенный для передачи контрольных сообщений и сериализованных объектов между репликационными узлами. RDBR Network protocol основан на протоколе HTTP и использует GET и POST запросы для взаимодействия. Для передачи конфиденциальных данных, в протоколе предусмотрена возможность использования HTTPS – расширения HTTP, поддерживающего шифрование с помощью SSL. В качестве платформы для реализации было принято решение использовать Java-сервлеты. Данные в протоколе передаются в виде XML, сжатого с помощью zip. В отличие от Notes/Domino. в RDBR используются современные технологии и открытые протоколы. Также RDBR, как и dRS работает с реляционным хранилищем, что может использоваться для построения сложных отчетов. Но в dRS под транзакцией подразумевается вся сессия репликации, а в RDBR передача и получение каждого объекта. Другие участники группы проекта занимаются реализацией механизма репликации RDBR. Сетевую часть данного механизма решено было организовать с использованием архитектуры peer-to-peer. Для работы с каналами связи с пропускной способностью в несколько килобайт в секунду, решено было передачу и получение каждого объекта при репликации оформлять в одну транзакцию.
В RDBR мы объединяем преимущества систем Notus/Domino и dRS, то есть, реализуем оффлайн-репликацию по расписанию с поддержкой продолжения репликации, после обрыва связи.


Литература

1.Иртегов Д.В. Введение в сетевые технологии. — СПб.: БХВ-Петербург, 2004.
2.Таненбаум А.Э., ван СТЕЕН М. Распределенные Системы. Принципы и парадигмы. — СПб.: Питер, 2003.
3.Christian Bauer, Gavin King Java Persistence with Hibernate. — USA: Manning Publications Co., 2007.
4.Роб Кирклэнд Domino версий 5 и 6. Администрирование сервера. — ДМК пресс, 2003.
5.A. Rowstron, P. Druschel Pastry: Scalable, distributed object location and routing for large-scale peer-to-peer systems // IFIP/ACM International Conference on Distributed Systems Platforms – 2001.
6.Jim Paterson, Stefan Edlich The Definitive Guide to db4o. — USA: Apress., 2006.
7.Некрасов В.В. Почтовая система сервера Lotus Domino 7.0 — Интер Траст, 2006.
8.Product Information for db4o Replication System // URL: www.db4o.com]
9.Hypertext Transfer Protocol – HTTP/1.1: RFC 2616 //
URL: http://rfc.sunsite.dk/rfc/rfc2616.html
10.Стивен Стелтинг, Олав Маасен Применение шаблонов java – Издательский дом “Вильямс”, 2002.


Публикации

1.Литвиненко И.А., Тищенко Н.А., Бельский А.Ю., Ипполитов В.Д., Баженов Н.А., Афонина А.Д., Кременная О.А., Вельдяксов В.Н. Реализация механизма репликации в среде с объектно-реляционным отображением // Труды 51-й научной конференции МФТИ «Современные проблемы фундаментальных и прикладных наук»: Часть VII. Управление и прикладная математика. Том 3., 2008 – с. 93–96

2.Литвиненко И.А., Тищенко Н.А., Бельский А.Ю., Ипполитов В.Д., Баженов Н.А., Афонина А.Д., Кременная О.А., Вельдяксов В.Н Реализация механизма репликации в среде с объектно-реляционным отображением // Материалы XLVII Международной научной студенческой конференции «Студент и научно-технический прогресс». Информационные технологии, 2009 – с. 71