PouchDB/CouchDB 冲突解决服务器端

PouchDB/CouchDB Conflict Resolution Server Side

我是 pouch/couch 的新手,正在寻找有关处理冲突的指导。具体来说,我有一个扩展 运行 pouchdb(分发给两个用户)。然后想法是远程拥有一个 pouchdb-server 或 couchdb(这对这个小用例重要吗?)实例 运行。我关心的关键是处理冲突,数据会频繁更改,虽然扩展不会进行实时同步,但它们会经常同步。我在数据提交函数中写入了冲突处理,但是当与多个用户发生同步时仍然存在冲突。

我正在查看 pouch-resolve-conflicts 插件并立即看到作者状态:

"Conflict resolution should better be done server side to avoid hard to debug loops when multiple clients resolves conflicts on the same documents".

这对我来说很有意义,但我不确定如何实现这种冲突 解析度。我能想到的唯一方法是放置 REST API 层 在使用自定义逻辑处理所有 updates/conflicts 等的远程数据库前面。 但是我怎么能使用 pouch 同步功能呢?那时我 也可以使用不同的数据库。

我一直找不到任何讨论如何在服务器端实施冲突解决的资源,实际上恰恰相反。

在使用 Redux 后,我意识到单向流的相同概念将帮助我完全避免冲突问题。

Redux 流程是这样的...

因此,我的客户端代码从不将确定的数据写入主数据库,而是在本地写入 insert/update/delete requests,PouchDB 然后将其推送到 CouchDB 主数据库。在与主 CouchDB 相同的服务器上,我在 NodeJS 中有 PouchDB 复制这些请求。 "Superviser" NodeJS 中的软件检查每个新请求,将它们的状态更改为 "processing" 写入请求的更新、插入和删除,然后标记请求 "processed"。为确保它们一次处理一个,接收每个请求的代码将它们填充到 FIFO 中。处理代码从另一端拉取它们。

我不处理超高音量,所以延迟不是问题。

我也没有遇到许多人可能试图同时更新完全相同的记录的情况。如果这是您的情况,您的客户端更新请求将需要指定 rev 编号,并且您的 "supervisors" 将需要拒绝引用被取代版本的更改请求。您必须弄清楚您的客户端代码将如何获得并响应这些拒绝。

对于您的用例,您可能可以写入本地 pouchdb 实例并将其与主数据库同步。然后,您可以拥有一个自动解决主数据库冲突的守护进程。

下面是我解决类似问题的方法。


我制作了一个自动解决冲突的 NodeJS 守护进程。它集成了 deconflict,一个 NodeJS 库,允许您以三种方式解析文档:

  • 将所有修订合并在一起
  • 保留最新版本(基于自定义密钥。例如:updated_at)
  • 选择某个版本(这里可以使用你自己的逻辑)

修订消除冲突

我使用 CouchDB 的方式,每次写入都是部分的。我们总是进行一些更改并将其应用到最新文档中。通过这种方法,我们可以轻松采取 merge all revision 策略。

冲突扫描器

守护进程启动时,会执行两个进程。一个经历了所有变化的人。如果检测到冲突,则会将其添加到 conflict queue.

另一个进程已执行并保持活动状态:连续更改扫描程序。 它侦听所有新更改并将冲突的文档添加到 conflict queue

队列处理

另一个进程启动并不断轮询队列以查找新的冲突文档。批量获取冲突文档,逐个解决。如果没有文件,它只是等待一段时间,然后重新开始轮询。