|
|
|
Синхронизация дублированных БД
|
|||
|---|---|---|---|
|
#18+
Доброе время суток. Вводная: Два промышленных ПК, два ПК для ведения БД. Промышленный ПК пишет данные в свою БД. Источники данных работают синхронно, пишут одинаковые данные в одинаковом порядке т.е. абсолютно синхронно (повышение надёжности дублированием). Выбранная 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.. Механизмами других СУБД у меня не получилось решить эту задачу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.10.2010, 07:49 |
|
||
|
Синхронизация дублированных БД
|
|||
|---|---|---|---|
|
#18+
Аттач забыл ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.10.2010, 07:50 |
|
||
|
Синхронизация дублированных БД
|
|||
|---|---|---|---|
|
#18+
FZT, А не проще писать на сервер записи о неуспешности записи на второй сервер? Т.е. клиент пишет запись на сервер1, при ошибке пишет лог на сервер2 Потом пишет запись на сервер2, при ошибке пишет лог на сервер1 В этом случае при нормальной работе никакой избыточности, при падении одного сервера на втором об этом будут записи. И синхронизировать (сравнивать) ничего не надо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.10.2010, 09:39 |
|
||
|
Синхронизация дублированных БД
|
|||
|---|---|---|---|
|
#18+
FZT, А стоит ли усложнять задачу? Промышленные ПК могут спокойно: 1. сначала писать данные в свой текстовый (например) лог, если эти данные им не нужны оперативно (скорее всего), или локальную БД, если нужны. 2. сразу после этого пытаться записать данные в 1 центральную БД и выставлять таймстамп последнего. Или отдельным процессом - писать изменения лога через нужное время. Таким образом, никакой синхронизации и тем более репликации БД не нужно - нужен просто 1 надежный сервер БД (можно рядом поставить 2-й в стендбае с логшиппингом на него, например). Достаточно синхронизации времени пром. ПК от сервера, что несколько проще репоикации :) В случае проблем на сервере - подмена основного на стендбай и накат пропущенных изменений из логов на ПК. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.10.2010, 10:17 |
|
||
|
Синхронизация дублированных БД
|
|||
|---|---|---|---|
|
#18+
FZT, А что, есть два (и более) независимых источника параллельных данных ? Т.е. с одного устройства можно в два потока снимать информацию? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.10.2010, 10:27 |
|
||
|
Синхронизация дублированных БД
|
|||
|---|---|---|---|
|
#18+
alexeyvgFZT, А не проще писать на сервер записи о неуспешности записи на второй сервер? Т.е. клиент пишет запись на сервер1, при ошибке пишет лог на сервер2 Потом пишет запись на сервер2, при ошибке пишет лог на сервер1 В этом случае при нормальной работе никакой избыточности, при падении одного сервера на втором об этом будут записи. И синхронизировать (сравнивать) ничего не надо. Нет. Умереть может и сам промышленный ПК. Далее получиться что данные для анализа будут запрашиваться сразу с двух серверов (ведь каждый из них не полон). Когда начнёт новую транзакцию на сервер1, то может не успеть. Favn FZT, А стоит ли усложнять задачу? Промышленные ПК могут спокойно: 1. сначала писать данные в свой текстовый (например) лог, если эти данные им не нужны оперативно (скорее всего), или локальную БД, если нужны. 2. сразу после этого пытаться записать данные в 1 центральную БД и выставлять таймстамп последнего. Или отдельным процессом - писать изменения лога через нужное время. Таким образом, никакой синхронизации и тем более репликации БД не нужно - нужен просто 1 надежный сервер БД (можно рядом поставить 2-й в стендбае с логшиппингом на него, например). Достаточно синхронизации времени пром. ПК от сервера, что несколько проще репоикации :) В случае проблем на сервере - подмена основного на стендбай и накат пропущенных изменений из логов на ПК. Данные должны оперативно падать в БД, в случае любого управления системой оперативный персонал смотрит лог событий из БД (на экране у него лишь текущее состояние системы). Промышленный ПК стоит в "опасном" месте, на них нет HDD (твердотельные диски или флешки, для старта юникса (иногда винды >_<), диск в процессе работы не используется вообще, СУБД стоят отдельно с массивами дисков под горячую замену). Винты магнитные будут лететь, чтобы его заменить на ПК, нужно вывести из работы систему, или вводить троирование, это дорого для клиента (по сравнению с конкурентами, просто не выиграем конкурс по цене или техническому решению). На ПК нельзя хранить логи, они могут испариться физически. Про один Мастер сервер БД, и репликацию(бин-лог) на второй - не устраивает, при отказе мастера транзакцию придётся повторить на второй сервер, если развивается авария мы можем потерять часть данных для анализа. Когда оба ПК независимо пишут в свою БД - это надёжней. В общем люди в промышленности привыкли к дублированию, меня мягко говоря не поймут. Siemargl А что, есть два (и более) независимых источника параллельных данных ? Т.е. с одного устройства можно в два потока снимать информацию? Да, с одного устройства в два(и более) потока на разные ПК, для не опрашиваемых устройств (сами шлют данные, ПК "нюхают" сеть). И сами устройства дублированы. Каждый ПК получает данные с обоих устройств. Перестраивать схему ПК1 <=> БД1; ПК2 <=> БД2, нельзя. Мне лишь нужно поддержать данные в актуальном состоянии максимально быстро. И неким образом гарантировать, что до развития аварии каждый сервер (пока есть связь) содержал полную информацию о промышленном процессе. Почти закончил с вторым лагоритмом. В штатном режиме информации относительно немного, примерно 100 записей в секунду. Моделирование показало при развитии аварии до 1000 записей в секунду. Сейчас мои БД и архиваторы в работе на нескольких объектах, на хорошем железе "успевают" отправить и принять до 1400 записей в секунду. Данных немного при пересылке, куча классификаторов и всяких извратов. Когда развивается авария, синхронизировать что-то особенно актуально. "Старая" же информация нужна для определения деградации по времени какого-либо параметра. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.10.2010, 11:50 |
|
||
|
Синхронизация дублированных БД
|
|||
|---|---|---|---|
|
#18+
FZTalexeyvgFZT, А не проще писать на сервер записи о неуспешности записи на второй сервер? Т.е. клиент пишет запись на сервер1, при ошибке пишет лог на сервер2 Потом пишет запись на сервер2, при ошибке пишет лог на сервер1 В этом случае при нормальной работе никакой избыточности, при падении одного сервера на втором об этом будут записи. И синхронизировать (сравнивать) ничего не надо. Нет. Умереть может и сам промышленный ПК. Далее получиться что данные для анализа будут запрашиваться сразу с двух серверов (ведь каждый из них не полон). Когда начнёт новую транзакцию на сервер1, то может не успеть. Тогда так: 1. клиент пишет лог на сервер2 и на сервер1 2. клиент пишет запись на сервер1, удаляет запись лога на сервер2 3. клиент пишет запись на сервер2, удаляет запись лога на сервер1 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.10.2010, 12:04 |
|
||
|
Синхронизация дублированных БД
|
|||
|---|---|---|---|
|
#18+
alexeyvgFZTalexeyvgFZT, А не проще писать на сервер записи о неуспешности записи на второй сервер? Т.е. клиент пишет запись на сервер1, при ошибке пишет лог на сервер2 Потом пишет запись на сервер2, при ошибке пишет лог на сервер1 В этом случае при нормальной работе никакой избыточности, при падении одного сервера на втором об этом будут записи. И синхронизировать (сравнивать) ничего не надо. Нет. Умереть может и сам промышленный ПК. Далее получиться что данные для анализа будут запрашиваться сразу с двух серверов (ведь каждый из них не полон). Когда начнёт новую транзакцию на сервер1, то может не успеть. Тогда так: 1. клиент пишет лог на сервер2 и на сервер1 2. клиент пишет запись на сервер1, удаляет запись лога на сервер2 3. клиент пишет запись на сервер2, удаляет запись лога на сервер1"лог" в моём варианте - это только ИД записи, больше ничего не надо ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.10.2010, 12:07 |
|
||
|
Синхронизация дублированных БД
|
|||
|---|---|---|---|
|
#18+
alexeyvg 1. клиент пишет лог на сервер2 и на сервер1 2. клиент пишет запись на сервер1, удаляет запись лога на сервер2 3. клиент пишет запись на сервер2, удаляет запись лога на сервер1 Попробовал смоделировать (на доске =), так наверное проще будет и достаточно. Ещё обдумаю. Спасибо огромное за идею, глаз уже замылился.. изменять Архиватор (клиент) ведь тоже можно. Только у меня получилось не ID а составной PK (ID + TimeStamp) в качестве лога. Число запросов сократил. Клиент1 пишет запись в БД1, лог в БД2. Синхронизатор чекает соответствие в каждой базе Лога и записи. Если что-то не нашёл (лог или запись) Либо запрашивает с второго сервера запись, либо добавляет второму серверу запись (с логом). Удачно сверенные логи удаляются. На вскидку, достаточно быстро. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.10.2010, 15:18 |
|
||
|
|

start [/forum/topic.php?fid=32&msg=36910996&tid=1542478]: |
0ms |
get settings: |
6ms |
get forum list: |
10ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
176ms |
get topic data: |
7ms |
get forum data: |
2ms |
get page messages: |
36ms |
get tp. blocked users: |
1ms |
| others: | 196ms |
| total: | 438ms |

| 0 / 0 |
