powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Синхронизация дублированных БД
9 сообщений из 9, страница 1 из 1
Синхронизация дублированных БД
    #36910996
FZT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FZT
Гость
Доброе время суток.

Вводная:
Два промышленных ПК, два ПК для ведения БД.
Промышленный ПК пишет данные в свою БД.
Источники данных работают синхронно, пишут одинаковые данные в одинаковом порядке т.е. абсолютно синхронно (повышение надёжности дублированием).
Выбранная SQL платформа: MySQL, MsSQL, Oracle, Db2(4) (по желанию/ что установлено у заказчика, для некоторых допустимо ставить и MySQL)

Необходимо не прерывая процесс записи (или минимально мешая ему) помечать данные как "синхронизированные", дабы больше никогда не проверять их.

Соответственно если данные рассинхронизированы - значит один из серверов период времени не писал данные, и нужно эти данные дополнить с другого сервера. Останавливать запись для проведения синхронизации нельзя.

Источники данных получают данные с устройств, уже помеченные TimeStamp (64 бита). В единицу времени одно событие может произойти 1 раз, но два разных события (датчики одного типа) могут иметь равные TimeStamp.

Сложность для использования найденных мной "стандартных" методов синхронизации:
Работают два сервера и пишут данные:
1 2 (10 записей в каждом)
1 * (10 записей в первом сервере, второй помер)
* 2 (10 записей во втором сервере, первый выпал, второй поднялся)
* * (не работают оба, парень с топором всё активней)
1 2 (работают оба, в каждом 30 записей, у парня отобрали топор, сервера поднялись)

Делать чумовые по тяжести запросы, раз в сутки не получится, сервера одинаково нагружены 24/7.

Давайте предположим что на серверах всего по 1 таблице, которую нужно синхронизировать.
Есть такие мысли:
Таблицы снабжать составным индексом (TimeStamp, и суррогатный ID), кластеризовать по TimeStamp. Это обеспечит удобный порядок данных для выборок по времени, кластеризовать данные СУБД будет просто (вставки по штампу времени будут почти всегда в конец таблицы).
Считать контрольную сумму CRC для каждой записи, CRC для последующей записи будет в качестве начального полинома использовать CRC предыдущей записи - это обеспечит зависимость полей данных от предыдущих и можно будет сверять не каждую строчку, а допустим группу строк подряд из 10 штук.

т.е. примерно поля таблицы: TimeStamp, ID, CRC, Data.
Поле ID будет не автоинкрементным, его будет формировать Источник данных на основании чего-нибудь (времени например) при старте, синхронизировать с вторым ПК, расхождения возможны, поэтому поле не будет участвовать в выборках, но обеспечить одинаковый порядок записи в БД, и уникальность PK вполне может.

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

32х битный CRC обеспечит отсутствие коллизий (одинаковых CRC) для группы из тысячи(или 10 или 100) записей с запасом.

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

Если записи не равны ("дырка" в данных)- сравнивать эту группу записей простым SELECT из второго сервера.
Уже рассчитанные CRC после пропущенных данных обнулить (они рассчитаны не верно ибо записи мы пропустили) и пересчитать когда сравнением записей убедимся что данные далее опять синхронизированы. Алгоритм расчета CRC поточный, миллионы в секунду, в общем быстр.

На каждую таблицу будет вспомогательная, назовём её <журнал таблицы>, которая будет хранить информацию о каждой кратной 100 записи, её поля такие-же но без суррогатного ID:
TimeStamp, CRC, Sync, Data (Sync - флаг синхронизации, "выше" него таблица синхронизирована)

Так-же на каждую таблицу заведём некий лог транзакций (чем-то похоже на bin-log) <журнал заданий>. В нём будут дублироваться все записи из <журнал таблицы>. Синхронизатор второго сервера будет его читать и сверять с аналогичными записями в своём журнале, или таблице (если в журнале будет отсутствовать такая запись).

Поскольку ждать заполнения блока в 100 записей не всегда удобно (некоторые таблицы обновляются редко), по таймауту в журналы будет сбрасываться лог "сколько есть".

Синхронизированное задание синхронизатор удалит с другого сервера.

Алгоритм выполнения заданий ещё не готов, в аттаче выложу что есть.

Собственно вопроса два.
1) Такая схема будет полноценной?
2) Есть ли готовые решения, позволяющие постоянно проверять БД на зеркальность (с учётом что в обе базы почти одновременно пишутся одинаковые данные)? Из рассмотренных мной, как мне показалось, более/менее удовлетворяет репликация Master - Master у Oracle.. Механизмами других СУБД у меня не получилось решить эту задачу.
...
Рейтинг: 0 / 0
Синхронизация дублированных БД
    #36910997
FZT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FZT
Гость
Аттач забыл
...
Рейтинг: 0 / 0
Синхронизация дублированных БД
    #36911163
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
FZT,

А не проще писать на сервер записи о неуспешности записи на второй сервер?

Т.е. клиент пишет запись на сервер1, при ошибке пишет лог на сервер2
Потом пишет запись на сервер2, при ошибке пишет лог на сервер1

В этом случае при нормальной работе никакой избыточности, при падении одного сервера на втором об этом будут записи.

И синхронизировать (сравнивать) ничего не надо.
...
Рейтинг: 0 / 0
Синхронизация дублированных БД
    #36911240
Favn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
FZT,
А стоит ли усложнять задачу?
Промышленные ПК могут спокойно:
1. сначала писать данные в свой текстовый (например) лог, если эти данные им не нужны оперативно (скорее всего), или локальную БД, если нужны.
2. сразу после этого пытаться записать данные в 1 центральную БД и выставлять таймстамп последнего. Или отдельным процессом - писать изменения лога через нужное время.

Таким образом, никакой синхронизации и тем более репликации БД не нужно - нужен просто 1 надежный сервер БД (можно рядом поставить 2-й в стендбае с логшиппингом на него, например). Достаточно синхронизации времени пром. ПК от сервера, что несколько проще репоикации :)
В случае проблем на сервере - подмена основного на стендбай и накат пропущенных изменений из логов на ПК.
...
Рейтинг: 0 / 0
Синхронизация дублированных БД
    #36911273
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
FZT,

А что, есть два (и более) независимых источника параллельных данных ?
Т.е. с одного устройства можно в два потока снимать информацию?
...
Рейтинг: 0 / 0
Синхронизация дублированных БД
    #36911603
FZT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FZT
Гость
alexeyvgFZT,
А не проще писать на сервер записи о неуспешности записи на второй сервер?
Т.е. клиент пишет запись на сервер1, при ошибке пишет лог на сервер2
Потом пишет запись на сервер2, при ошибке пишет лог на сервер1
В этом случае при нормальной работе никакой избыточности, при падении одного сервера на втором об этом будут записи.
И синхронизировать (сравнивать) ничего не надо.
Нет. Умереть может и сам промышленный ПК. Далее получиться что данные для анализа будут запрашиваться сразу с двух серверов (ведь каждый из них не полон). Когда начнёт новую транзакцию на сервер1, то может не успеть.

Favn
FZT,
А стоит ли усложнять задачу?
Промышленные ПК могут спокойно:
1. сначала писать данные в свой текстовый (например) лог, если эти данные им не нужны оперативно (скорее всего), или локальную БД, если нужны.
2. сразу после этого пытаться записать данные в 1 центральную БД и выставлять таймстамп последнего. Или отдельным процессом - писать изменения лога через нужное время.

Таким образом, никакой синхронизации и тем более репликации БД не нужно - нужен просто 1 надежный сервер БД (можно рядом поставить 2-й в стендбае с логшиппингом на него, например). Достаточно синхронизации времени пром. ПК от сервера, что несколько проще репоикации :)
В случае проблем на сервере - подмена основного на стендбай и накат пропущенных изменений из логов на ПК.

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

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

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

Да, с одного устройства в два(и более) потока на разные ПК, для не опрашиваемых устройств (сами шлют данные, ПК "нюхают" сеть). И сами устройства дублированы. Каждый ПК получает данные с обоих устройств.

Перестраивать схему ПК1 <=> БД1; ПК2 <=> БД2, нельзя.
Мне лишь нужно поддержать данные в актуальном состоянии максимально быстро. И неким образом гарантировать, что до развития аварии каждый сервер (пока есть связь) содержал полную информацию о промышленном процессе.

Почти закончил с вторым лагоритмом.
В штатном режиме информации относительно немного, примерно 100 записей в секунду. Моделирование показало при развитии аварии до 1000 записей в секунду. Сейчас мои БД и архиваторы в работе на нескольких объектах, на хорошем железе "успевают" отправить и принять до 1400 записей в секунду. Данных немного при пересылке, куча классификаторов и всяких извратов.
Когда развивается авария, синхронизировать что-то особенно актуально. "Старая" же информация нужна для определения деградации по времени какого-либо параметра.
...
Рейтинг: 0 / 0
Синхронизация дублированных БД
    #36911664
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
FZTalexeyvgFZT,
А не проще писать на сервер записи о неуспешности записи на второй сервер?
Т.е. клиент пишет запись на сервер1, при ошибке пишет лог на сервер2
Потом пишет запись на сервер2, при ошибке пишет лог на сервер1
В этом случае при нормальной работе никакой избыточности, при падении одного сервера на втором об этом будут записи.
И синхронизировать (сравнивать) ничего не надо.
Нет. Умереть может и сам промышленный ПК. Далее получиться что данные для анализа будут запрашиваться сразу с двух серверов (ведь каждый из них не полон). Когда начнёт новую транзакцию на сервер1, то может не успеть.
Тогда так:
1. клиент пишет лог на сервер2 и на сервер1
2. клиент пишет запись на сервер1, удаляет запись лога на сервер2
3. клиент пишет запись на сервер2, удаляет запись лога на сервер1
...
Рейтинг: 0 / 0
Синхронизация дублированных БД
    #36911675
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alexeyvgFZTalexeyvgFZT,
А не проще писать на сервер записи о неуспешности записи на второй сервер?
Т.е. клиент пишет запись на сервер1, при ошибке пишет лог на сервер2
Потом пишет запись на сервер2, при ошибке пишет лог на сервер1
В этом случае при нормальной работе никакой избыточности, при падении одного сервера на втором об этом будут записи.
И синхронизировать (сравнивать) ничего не надо.
Нет. Умереть может и сам промышленный ПК. Далее получиться что данные для анализа будут запрашиваться сразу с двух серверов (ведь каждый из них не полон). Когда начнёт новую транзакцию на сервер1, то может не успеть.
Тогда так:
1. клиент пишет лог на сервер2 и на сервер1
2. клиент пишет запись на сервер1, удаляет запись лога на сервер2
3. клиент пишет запись на сервер2, удаляет запись лога на сервер1"лог" в моём варианте - это только ИД записи, больше ничего не надо
...
Рейтинг: 0 / 0
Синхронизация дублированных БД
    #36912490
FZT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FZT
Гость
alexeyvg
1. клиент пишет лог на сервер2 и на сервер1
2. клиент пишет запись на сервер1, удаляет запись лога на сервер2
3. клиент пишет запись на сервер2, удаляет запись лога на сервер1

Попробовал смоделировать (на доске =), так наверное проще будет и достаточно. Ещё обдумаю. Спасибо огромное за идею, глаз уже замылился.. изменять Архиватор (клиент) ведь тоже можно.
Только у меня получилось не ID а составной PK (ID + TimeStamp) в качестве лога.
Число запросов сократил.

Клиент1 пишет запись в БД1, лог в БД2.
Синхронизатор чекает соответствие в каждой базе Лога и записи. Если что-то не нашёл (лог или запись) Либо запрашивает с второго сервера запись, либо добавляет второму серверу запись (с логом). Удачно сверенные логи удаляются.
На вскидку, достаточно быстро.
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Синхронизация дублированных БД
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]