OberonCore
https://forum.oberoncore.ru/

Репликация данных в реальном времени
https://forum.oberoncore.ru/viewtopic.php?f=27&t=520
Страница 1 из 1

Автор:  Сергей Губанов [ Среда, 13 Июнь, 2007 15:22 ]
Заголовок сообщения:  Репликация данных в реальном времени

Задача 1.
Есть два компьютера. Один работает, второй - "на подхвате" (standby). Если вдруг первый упадёт (произошла авария), то второй должен тот час же приняться выполнять работу вместо первого. Для этого в его оперативной памяти уже должна быть размещена структура данных из первого компьютера. Вобщем, надо в реальном режиме времени постоянно передавать изменение структуры данных находящейся в оперативной памяти первого компьютера на второй. Естественно, что структура данных слишком большая чтобы можно было передавать её мгновенные копии, нужно передавать именно её изменение.

Задача 2.
То же что и (1), но при аварии имеем полное право "нечаянно" потерять до 10% данных.

Кто-нибудь сталкивался с такими задачами?

Автор:  Димыч [ Среда, 13 Июнь, 2007 18:13 ]
Заголовок сообщения:  Re: Репликация данных в реальном времени

Сергей Губанов писал(а):
Задача 1.
Есть два компьютера. Один работает, второй - "на подхвате" (standby).

Задача 2.
То же что и (1), но при аварии имеем полное право "нечаянно" потерять до 10% данных.

Кто-нибудь сталкивался с такими задачами?


В качестве одного из вариантов решения подобной задачи можно предложить понятие "журнала работы".
Первый компьютер работает, и в процессе работы пишет последовательность обработки [упомянутой большой структуры]. Это и есть журнал. Вводится понятие контрольной точки, которая предназначена для переброски журнала на ведомый компьютер. После передачи первый компьютер продолжает работу, второй выполняет модификацию в порядке поступления журнальной информации. Получается обработка с некоторым запаздыванием. Возможно, потребуется приостановка основного компьютера или какая-то синхронизация, но в целом механизм работоспособный.
Так работает репликация данных на ведомую БД Oracle.

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

Автор:  Сергей Губанов [ Четверг, 14 Июнь, 2007 13:09 ]
Заголовок сообщения: 

Похоже, что решение найдено. Ту огромную структуру данных удалось разбить на кластеры, каждый из которых можно (де)сериализовывать по отдельности "обычным Stores", а взаимосвязи между этими кластерами и остальной системой восстанавливать "руками". Но эти кластеры всё же ещё не достаточно мелкие, чтобы отправлять их сериализованное представление по сети после каждой модификации. Для уменьшения трафика мы тут придумали следующее. Буду сериализовать кластер объектов в массив и побайтово сравнивать полученный массив с тем, что был получен при сериализации этого кластера в прошлый раз. Если эти два массива мало отличаются, то пересылатся будет только их разница. Случай удаления кластера обрабатывается отдельно. Расход памяти, правда, увеличивается почти в 2 раза - кроме самой структуры данных хранится ещё и её сериализованная копия.

Автор:  Сергей Губанов [ Пятница, 15 Июнь, 2007 10:25 ]
Заголовок сообщения:  Re: Репликация данных в реальном времени

Димыч писал(а):
...второй выполняет модификацию в порядке поступления журнальной информации. Получается обработка с некоторым запаздыванием.

Чтобы не было запаздывания, логично писать не в журнал, а в сокет. Весь вопрос в том, что конкретно писать-то?

Автор:  Сергей Губанов [ Пятница, 15 Июнь, 2007 10:35 ]
Заголовок сообщения: 

Ещё есть такая идея. Сначала копируем всю структуру (обычным Stores), а затем...

Пусть у каждого объекта будет уникальный идентификатор и пусть будет реестр объектов (идентификатор <--> слабая ссылка).

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

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

Автор:  Сергей Губанов [ Суббота, 16 Июнь, 2007 14:51 ]
Заголовок сообщения: 

А задачка-то, оказывается, имеет точное решение.

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

По сравнению со Stores.Store у реплицируемого объекта есть ещё парочка методов: ReExternalize и ReInternalize. Они предназначены специально для (повторной) модификации ранее экстернализированного/интернализированного объекта. Через них может передаваться не всё состояние объекта, а лишь его модификация, что может быть существенно меньше по объёму.

Есть сервис репликации, у которого есть метод Service.Commit(obj: Object) экстернализирующий или пере-экстернализирующий указанный объект. Когда у объекта-оригинала изменяется состояние, то он сообщает об этом сервису репликации вызывая: service.Commit(this). Если (пере)экстернализируемый объект ссылается на другие объекты и они ещё не были ни разу экстернализированы, то они экстернализируются. Пере-экстернализация выполняется только по явной команде.

У каждого реплицируемого объекта есть скрытое поле - GUID, благодаря ему восстанавливаются все взаимные ссылки при десериализации.

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

Концептуальный интерфейс:
Код:
DEFINITION Replication;

  TYPE
    Object = POINTER TO ABSTRACT RECORD
      (obj: Object) Externalize- (VAR wr: Writer), NEW, EXTENSIBLE;
      (obj: Object) Internalize- (VAR rd: Reader), NEW, EXTENSIBLE;
      (obj: Object) ReExternalize- (VAR wr: Writer), NEW, EXTENSIBLE;
      (obj: Object) ReInternalize- (VAR rd: Reader), NEW, EXTENSIBLE
    END;

    Reader = LIMITED RECORD
      (VAR rd: Reader) ReadByte (OUT b: BYTE), NEW;
      (VAR rd: Reader) ReadBytes (OUT buffer: ARRAY OF BYTE; offset, count: INTEGER), NEW;
      ...
      (VAR rd: Reader) ReadObject (OUT obj: Object), NEW
    END;

    Writer = LIMITED RECORD
      (VAR wr: Writer) WriteByte (b: BYTE), NEW;
      (VAR wr: Writer) WriteBytes (IN buffer: ARRAY OF BYTE; offset, count: INTEGER), NEW;
      ...
      (VAR wr: Writer) WriteObject (obj: Object), NEW
    END;

    Service = POINTER TO ABSTRACT RECORD
      (c: Channel) Commit (obj: Object), NEW, ABSTRACT;
    END;

  PROCEDURE NewService (listenerEndPoint: ARRAY OF CHAR): Service;

END Replication.

Автор:  Илья Ермаков [ Суббота, 16 Июнь, 2007 15:32 ]
Заголовок сообщения: 

Сергей, а реализация будет на КП?

Автор:  Сергей Губанов [ Воскресенье, 17 Июнь, 2007 18:17 ]
Заголовок сообщения: 

Илья Ермаков писал(а):
Сергей, а реализация будет на КП?

Ну, мне же это на работе надо, а мы там не на КП пишем...

Я уже где-то на этом форуме писал, что если бы была "железобетонная" серверная версия Блэкбокса под Linux, которая бы не уступала как минимум реализации тамошнего .Net - Mono, то кто знает, может быть была бы и на КП.

Автор:  Димыч [ Понедельник, 18 Июнь, 2007 17:44 ]
Заголовок сообщения: 

Сергей Губанов писал(а):
Ещё есть такая идея. Сначала копируем всю структуру (обычным Stores), а затем...

Пусть у каждого объекта будет уникальный идентификатор и пусть будет реестр объектов (идентификатор <--> слабая ссылка).

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


Может я что не так понял в исходной задаче.
Попробую свое понимание изложить и высказать свое понимание решения.
Имеем два компьютера идентичной структуры. На одном происходит обработка большой (но при этом вмещающейся в ОЗУ) структуры.
Задача состоит в том, чтобы организовать зеркалирование указанной процедуры (обработки) на втором компьютере с целью обеспечения отказоустойчивости.
Есть три точки зрения на процесс передачи информации о модификации.
1) Производить преобразование в массив байт с последующим анализом изменений.
2) Каждый модифицируемый объект сообщает о том, что его изменили (вариант п.1, на самом деле)
3) Каждая процедура, приводящая к модификации структуры данных, записывается вместе со своими параметрами, а затем воспроизводится на ведомом компьютере.

п.3 и имелся ввиду под "журналом".
Вопрос передачи журнала на ведомый компьютер - предмет отдельного обсуждения, возможных вариантов масса - сокеты, RPC, http и т.д.
По варианту №3 работает (насколько я знаю) удаленный рабочий стол в Windows (в добавление к приведенному выше Ораклу). Там производится запись команд GDI наподобие WMF и передаются записанные команды, которые затем воспроизводятся на удаленном столе.

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

PS. Можно какую-то ссылочку на более подробное описание решения с сериализацией?

Автор:  Сергей Губанов [ Вторник, 19 Июнь, 2007 09:58 ]
Заголовок сообщения: 

Там не просто структура данных, а взаимосвязанные объекты. Данные в них инкапсулированы и наперёд не известно что там внутри объектов и как изменяется. С этой точки зрения каждый объект атомарен.

Ссылочку на сериализацию можно - смотрите в Блэкбоксе модуль Stores.

Автор:  Сергей Губанов [ Вторник, 19 Июнь, 2007 17:29 ]
Заголовок сообщения: 

Кстати, методы ReExternalize (VAR wr: Writer) и ReInternalize (VAR rd: Reader) логичнее обозвать как BeginReplication (VAR wr: Writer) и EndReplication (VAR rd: Reader). Метод BeginReplication (VAR wr: Writer) вызывается системой у объекта-оригинала на одном компьютере, а метод EndReplication (VAR rd: Reader) вызывается системой у объекта-копии на другом компьютере. При этом соответствующие Writer и Reader относятся к одному и тому же Carrier - переданному по сети бинарному сообщению.

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/