postgresql - 使用需要同步的两个数据库时如何实现乐观(或悲观)锁定?

标签 postgresql elasticsearch concurrency optimistic-locking pessimistic-locking

我正在研究一个解决方案,其中我们有两个用于以下目的的数据库:

  • 用于搜索目的的 Elasticsearch
  • 作为数据真实来源的 Postgres 数据库

  • 我们的应用程序允许用户检索和更新产品,并且一个产品具有多个属性:名称、价格、描述等……而两个典型的用例是:
  • 按名称检索产品:使用elasticsearch进行搜索,然后将ES检索到的ID用于对Postgres的二次查询以获得真实可信的数据(因此我们在获取可信数据的同时快速搜索大表)
  • 更新产品字段:我们允许用户更新任何产品信息(一种协作 wiki)。首先我们将数据存储在 Postgres 中,然后存储到 Elasticsearch 中。

  • 然而,正如我所担心的那样,随着使用该应用程序的人数增加,我们遇到了竞争条件;如果用户 #1 将产品名称更改为“Banana”,然后用户 #2 同时将产品名称更改为“Apple”,则在 Elasticsearch 中,有时在 Postgres 中保存的最后一条记录将是“Banana” “Apple”将是最后一个值,从而在数据库之间造成严重的不一致。

    因此,我冒险阅读有关乐观/悲观锁定以解决我的问题,但到目前为止,我发现的所有文章都与您仅使用 1 个关系数据库相关,并且提供的解决方案依赖于 ORM 实现(例如 Hibernate)。但是我们的 ES + Postgres 组合存储解决方案需要更多的“芭蕾舞”。

    我可以使用哪些技术/选项来解决我的这类问题?

    最佳答案

    好吧,我可能会吸引一些批评者,但让我以我理解的方式向您解释。我的理解是这个问题/关注更多的是架构角度而不是设计/代码角度。

    即时一致性,当然还有最终一致性

    来自应用层

    对于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 或 增量抓取
  • 为此,您需要根据 postgres 行的状态使用 where 子句进行选择查询,例如拉取状态为 0 的记录对于最近更新的文档,或基于 timestamp提取上次更新的记录 30 secs/1 min或根据您的需要。 增量查询
  • 执行增量爬网后,如果您使用 status 实现增量爬网, ,您需要将其状态更改为1 (成功)或'-1'(失败),以便在下一次爬网中不会拾取相同的文档。 后增量查询
  • 基本上安排作业作为索引操作的一部分在查询之上运行。

  • 基本上我们会有GUI --> Application Layer --> Postgres --> Indexer --> Elasticsearch
    概括

    我认为考虑故障证明方式是不明智的,而是我们应该拥有一个可以在尽可能快的时间内恢复的系统,以提供两个不同数据源之间的一致性。

    将系统解耦将极大地有助于扩展和解决与数据正确性/质量相关的问题,同时将帮助您处理频繁的更新以及数据的增长率以及随之而来的更新。

    另外我推荐一个link这可以帮助

    希望能帮助到你!

    关于postgresql - 使用需要同步的两个数据库时如何实现乐观(或悲观)锁定?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53045634/

    相关文章:

    elasticsearch - 让kibana 4发送警报或在特定条件下采取措施的任何方式

    java - 为什么要对两个 volatile 变量进行重新排序?

    PHP MySQL Task API,防止重复记录

    PostgreSQL - 查看或分区?

    SQL如何将 "collect"行合并为一行

    Elasticsearch Query DSL 日期范围问题

    elasticsearch - LXD问题,Elasticsearch的vm.max_map_count

    java - Grahpics2D Draw 和 JPanel 重绘的并发问题

    postgresql - Postgres : Checkpoints Are Occurring Too Frequently

    sql - 将 postgres 主键和外键从 varchar 更改为 uuid