Эффективный дизайн для обновления другой базы данных всякий раз, когда объект обновляется в приложении

#database #postgresql #database-design #architecture #orientdb

#База данных #postgresql #база данных-дизайн #архитектура #orientdb

Вопрос:

У меня есть приложение (App A), которое использует orientdb (DB # 1) в качестве базы данных. Сейчас мы разрабатываем другое приложение (приложение B), которое использует PostgreSQL (DB # 2) в качестве базы данных.

Теперь у нас есть требование, в соответствии с которым нам нужно перечислить несколько объектов приложения «A» в приложении «B», а также разрешить пользователям изменять эти объекты в приложении B. Все изменения, которые выполняются для объектов приложения ‘A’ в приложении ‘B’, должны быть отражены в DB # 1. После серии внутренних обсуждений с командой мы убеждены в необходимости немедленного переноса данных необходимых объектов из базы данных № 1 в базу данных № 2, а затем динамического обновления базы данных № 2 записями, которые создаются / обновляются в базе данных № 1, и наоборот. Может кто-нибудь, пожалуйста, предложить эффективные способы синхронизации db # 1 и db # 2?

Примечание:

  1. Мы не заинтересованы в синхронизации БД № 1 и БД № 2 в режиме реального времени, конечная согласованность нам подходит.
  2. Orientdb предоставляет 2 вида перехватов
    • Динамические перехваты ( https://orientdb.com/docs/last/Dynamic-Hooks.html ), которые работают на уровне схемы, а не между базами данных.
    • Java-перехваты (https://orientdb.com/docs/last/Java-Hooks.html ), для чего требуется создать jar и поместить его в папку lib orientdb.Мы исключили этот вариант, поскольку у нас есть несколько экземпляров orientdb, работающих в разных регионах, что означает, что каждый раз, когда мы обновляем jar, нам нужно обновлять во всех экземплярах oriendb, и отладка может быть затруднена, поскольку этот jar выполняется как подпроцесс внутри oriendb.

Некоторые из рассмотренных нами подходов:

  1. Всякий раз, когда пользователь создает / обновляет объект в приложении ‘A’, создайте / обновите соответствующую запись в db # 1, и как только мы обновим ее в db # 1, на прикладном уровне (java), отправьте эквивалентный запрос Postgres sql для обновления записи в db # 2 в постоянную очередь и обрабатывайте эти сообщения асинхронно и наоборот

Комментарии:

1. Есть ли конкретная причина, по которой вы думаете об интеграции на уровне базы данных? Рассматривали ли вы эту синхронизацию на уровне приложения через веб-службы или обмен сообщениями (jms?)?

Ответ №1:

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

  1. Приложение A напрямую обновляет базу данных, используемую приложением B.
  2. Приложение A вызывает веб-службу, предоставляемую приложением B, а затем эта веб-служба обновляет базу данных, используемую приложением B.

Оба вышеперечисленных подхода приводят к тесной связи между приложениями A и B, что не очень хорошо. Если схема базы данных, используемая приложением B, изменяется, приложение A также необходимо обновить в обоих вышеуказанных подходах.

Вместо этого стандартным и рекомендуемым способом интеграции данных между приложениями в современном мире является использование постоянных очередей, таких как Kafka. В этом случае всякий раз, когда приложение A получает обновления данных, оно отправляет событие в очередь Kafka с данными, и ему все равно, получит его приложение B или нет. Приложение B подписывается на очередь, и когда оно получает события, отправленные приложением A, оно обновляет свою собственную базу данных.

При таком подходе оба приложения очень слабо связаны. Поддержка этой инфраструктуры Kafka сопряжена с накладными расходами, но в долгосрочной перспективе это того стоит, если приложения будут увеличиваться. И если Kakfa совершенно не подходит, то подход 2 (через веб-сервисы) лучше, чем подход 1 или другие механизмы интеграции.

Надеюсь, это поможет.

Комментарии:

1. Спасибо за быстрый и точный ответ!!

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

3. Поскольку я включаю имена таблиц в свою полезную нагрузку события, мне придется изменить логику обработки событий в одном или обоих приложениях при изменении схемы. Есть ли лучший способ сделать это?

4. итак, слабая связь здесь означает, что не возникнет немедленной необходимости в развертывании обоих приложений, если одно из приложений изменит свою схему. Например, в приложении A есть таблица с 5 столбцами, и, скажем, всякий раз, когда в этой таблице происходит какая-либо операция crud, событие выталкивается, чтобы приложение B могло обновить свою собственную базу данных. Теперь предположим, что в этой таблице в приложении A добавлен дополнительный столбец, в этом случае данные события Kafka будут содержать данные для этого нового столбца. Однако потребитель в приложении B может безопасно игнорировать дополнительные данные, и, таким образом, ничего не ломается. Позже приложение B может добавить этот столбец, повторно развернуть.

5. Идея заключается в том, что благодаря этой архитектуре, управляемой событиями, ничто не сломается немедленно. Приложение-производитель должно поддерживать обратную совместимость с форматом данных события (подробнее читайте о обратной совместимости protobuf), а приложение-потребитель может позже начать использовать его, когда оно будет готово, без необходимости немедленного удаления при внесении изменений в приложение-производитель.

Ответ №2:

Вы также можете рассмотреть возможность использования решения, основанного на подходе «изменить сбор данных» с помощью внешнего инструмента, такого как debezium.

Принцип заключается в том, чтобы подключить что-то к журналам bin вашей базы данных, что вызовет события при изменении данных, затем вы реализуете прослушиватели, отвечающие за репликацию изменений во 2-й БД. Этот подход позволяет избежать явного соединения разных приложений.