Как реализовать оптимистическую (или пессимистическую) блокировку при использовании двух баз данных, которые должны быть синхронизированы? - PullRequest
0 голосов
/ 29 октября 2018

Я работаю над решением, в котором у нас есть две базы данных, которые используются в следующих целях:

  • Elasticsearch, используемый для поисковых целей
  • База данных Postgres, которая служит источником правды для данных

Наше приложение позволяет пользователям получать и обновлять продукты, а продукт имеет несколько атрибутов: имя, цена, описание и т. Д. ... И два типичных варианта использования:

  • Извлечение товаров по названию: поиск выполняется с использованием эластичного поиска, а затем идентификаторы, полученные ES, используются во вторичном запросе к Postgres для получения фактических и достоверных данных (поэтому мы получаем быстрый поиск по большим таблицам при получении достоверных данных )
  • Обновление полей продукта: мы разрешаем пользователям обновлять любую информацию о продукте (в виде совместной вики). Сначала мы храним данные в Postgres, а затем в Elasticsearch.

Однако, как я и боялся, а количество людей, использующих приложение, увеличилось, мы столкнулись с условиями гонки; если пользователь № 1 изменил название продукта на «Банан», а затем пользователь № 2 одновременно изменил название продукта на «Яблоко», иногда в эластичном поиске последней сохраненной записью будет «Банан» в то время как в Postgres «Apple» будет последним значением, создающим серьезное несоответствие между базами данных.

Так что я рискнул прочитать об оптимистической / пессимистической блокировке, чтобы решить мою проблему, но пока все статьи, которые я нахожу, связаны, когда вы используете только 1 реляционную базу данных, и предлагаемые решения основаны на реализациях ORM (например, Hibernate) , Но наше комбинированное хранилище ES + Postgres требует больше «балета», чем это.

Какие методы / опции доступны для решения моей проблемы?

1 Ответ

0 голосов
/ 29 октября 2018

Ну, я могу привлечь некоторых критиков, но позвольте мне объяснить вас так, как я понимаю. Что я понимаю, так это то, что эта проблема / беспокойство является скорее архитектурной, нежели перспективой дизайна / кода.

Немедленная последовательность и, конечно, возможная последовательность

Из уровня приложений

Для immediate consitency между двумя базами данных единственный способ, которым вы можете их достичь, - это сделать polygot persistence in a transactional way, чтобы либо те же данные в Postgres и Elasticearch обновлялись, либо ни одна из них не обновлялась. Я бы не рекомендовал это только потому, что это оказало бы большое давление на приложение, и его было бы очень трудно масштабировать / поддерживать.

Так что в основном GUI --> Application Layer --> Postgres/Elasticsearch

Механизм потоковой передачи в очереди / в реальном времени

Вам необходимо иметь очередь сообщений, чтобы обновления направлялись в очередь при приближении на основе событий.

GUI --> Application Layer --> Postgres--> Queue --> Elasticsearch

Возможная последовательность, но не немедленная последовательность

Есть отдельное приложение, обычно давайте назовем это indexer. Цель этого инструмента - выполнить обновления с postgres и вставить их в Elasticsearch.

То, что вы можете иметь в indexer, имеет кратное single configuration per source, которое будет иметь

  • Возможность сделать select * и индексировать everything в Elasticsearch или полное сканирование
    • Это будет сделано, если вы хотите удалить / переиндексировать все данные в Elasticsearch
  • Способность обнаруживать only the updated rows в Postgres и таким образом толкать их в Elasticsearch или инкрементный обход
    • Для этого вам потребуется запрос select с предложением where, основанный на статусе ваших строк postgres, например, извлекать записи со статусом 0 для документа, который был недавно обновлен, или на основе timestamp извлекать записи, которые были обновлены за последний 30 secs/1 min или в зависимости от ваших потребностей. Дополнительный запрос
    • Как только вы выполните инкрементный обход, если вы реализуете инкремент, используя status, вам нужно изменить статус этого на 1 (успех) или '-1' (сбой), чтобы при следующем сканировании документ не получен. Постинкрементный запрос
    • В основном планируйте задания для выполнения над запросами как часть операций индексирования.

В основном у нас было бы GUI --> Application Layer --> Postgres --> Indexer --> Elasticsearch

Резюме

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

Отсоединение систем очень поможет в масштабировании и определении проблем, связанных с правильностью / качеством данных, и в то же время поможет вам справляться с частыми обновлениями, а также с темпами роста данных и обновлениями вместе с ними.

Также я рекомендую еще одну ссылку , которая может помочь

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...