简体   繁体   English

PouchDB / CouchDB冲突解决服务器端

[英]PouchDB/CouchDB Conflict Resolution Server Side

I'm new to pouch/couch and looking for some guidance on handling conflicts. 我是新手,需要一些有关处理冲突的指导。 Specifically, I have an extension running pouchdb (distributed to two users). 具体来说,我有一个运行pouchdb的扩展(分发给两个用户)。 Then the idea is to have a pouchdb-server or couchdb (does it matter for this small a use case?) instance running remotely. 然后的想法是让一个pouchdb-server或couchdb(对于这么小的用例来说重要吗?)实例远程运行。 The crux of my concern is handling conflicts, the data will be changing frequently and though the extensions won't be doing live sync, they will be syncing very often. 我关心的问题是处理冲突,数据将经常更改,尽管扩展程序不会进行实时同步,但它们将非常频繁地进行同步。 I have conflict handling written into the data submission functions, however there could still be conflicts when syncing occurs with multiple users. 我已将冲突处理写入数据提交功能,但是当与多个用户进行同步时,仍然可能存在冲突。

I was looking at the pouch-resolve-conflicts plugin and see immediately the author state: 我正在查看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". “冲突解决最好在服务器端完成,以避免当多个客户端解决同一文档上的冲突时难以调试循环”。

This makes sense to me, but I am unsure how to implement such conflict resolution. 这对我来说很有意义,但是我不确定如何实施这种冲突解决方案。 The only way I can think would be to place REST API layer in front of the remote database that handles all updates/conflicts etc with custom logic. 我能想到的唯一方法是将REST API层放置在使用自定义逻辑处理所有更新/冲突等的远程数据库的前面。 But then how could I use the pouch sync functionality? 但是,我该如何使用邮袋同步功能? At that point I may as well just use a different database. 到那时,我还可以使用其他数据库。

I've just been unable to find any resources discussing how to implement conflict resolution server-side, in fact the opposite. 我只是找不到任何资源来讨论如何在服务器端实现冲突解决,实际上相反。

With your use case, you could probably write to a local pouchdb instance and sync it with the master database. 对于您的用例,您可能可以写入本地pouchdb实例,并将其与master数据库同步。 Then, you could have a daemon that automatically resolve conflicts on your master database. 然后,您将拥有一个守护程序,可以自动解决您的master数据库上的冲突。

Below is my approach to solve a similar problem. 下面是我解决类似问题的方法。


I have made a NodeJS daemon that automatically resolve conflicts. 我已经制作了一个NodeJS守护程序来自动解决冲突。 It integrates deconflict , a NodeJS library that allows you to resolve a document in three ways: 它集成了deconflict (一个NodeJS库),该库使您可以通过三种方式解析文档:

  • Merge all revisions together 合并所有修订
  • Keep the latest revisions (based on a custom key. Eg: updated_at) 保留最新修订(基于自定义键。例如:updated_at)
  • Pick a certain revision (Here you can use your own logic) 选择某个修订版(您可以在此处使用自己的逻辑)

Revision deconflict 修订版冲突

The way I use CouchDB, every write is partial. 我使用CouchDB的方式,每次写入都是局部的。 We always take some changes and apply them to the latest document. 我们始终会进行一些更改,并将其应用于最新文档。 With this approach, we can easily take the merge all revision strategy. 通过这种方法,我们可以轻松地采用merge all revision策略。

Conflict scanner 冲突扫描器

When the daemon boot, two processes are executed. 守护程序启动时,将执行两个进程。 One that go through all the changes. 经历所有变化的一种。 If a conflict is detected, it's added to a conflict queue . 如果检测到冲突,则会将其添加到conflict queue

Another process is executed and remain active: Continuous changes scanner. 另一个过程被执行并保持活动状态:连续更改扫描仪。 It listen to all new changes and add conflicted documents to the conflict queue 它侦听所有新更改并将冲突的文档添加到conflict queue

Queue processing 队列处理

Another process is started and keeps polling the queue for new conflicted documents. 启动另一个过程,并继续轮询队列以查找新的冲突文档。 It gets conflicted documents in batch and resolve them on by one. 它批量获取有冲突的文档,并一一解决。 If there's not documents, it just wait a certain period and starts the polling again. 如果没有文档,则只需等待一段时间,然后重新开始轮询。

Having worked a little bit with Redux I realized that the same concept of unidirectional flow would help me avoid the problem of conflicts altogether. 与Redux一起工作了一段时间后,我意识到单向流的相同概念将帮助我完全避免冲突问题。

Redux flows like this... Redux像这样...

Redux流

So, my clientside code never write definitive data to the master database, instead they write insert/update/delete requests locally which PouchDB then pushes to the CouchDB master database. 因此,我的客户端代码永远不会将确定的数据写入master数据库,而是在本地写入插入/更新/删除请求 ,然后PouchDB将其推送到CouchDB master数据库。 On the same server as the master CouchDB I have PouchDB in NodeJS replicating these requests. 在与主CouchDB相同的服务器上,NodeJS中有PouchDB复制这些请求。 "Superviser" software in NodeJS examines each new request, changes their status to "processing" writes the requested updates, inserts and deletes, then marks the request "processed". NodeJS中的“ Superviser”软件检查每个新请求,将其状态更改为“处理中”,写入请求的更新,插入和删除,然后将请求标记为“已处理”。 To ensure they're processed one at time the code that receives each request, stuffs them into a FIFO. 为了确保在接收到每个请求的代码时对它们进行一次处理,请将它们填充到FIFO中。 The processing code pulls them from the other end. 处理代码将它们从另一端拉出。

I'm not dealing with super high volume, so the latency is not a concern. 我没有处理超大音量,因此延迟不是问题。

I'm also not facing a situation where numerous people might be trying to update exactly the same record at the same time. 我也没有遇到很多人可能试图同时更新完全相同的记录的情况。 If that's your situation, your client-side update requests will need to specify the rev number and your "supervisors" will need to reject change requests that refer to a superseded version. 如果这是你的情况,你的客户端的更新请求将需要指定的数,你的“上司”需要拒绝指被取代的版本变更请求。 You'll have to figure out how your client code would get and respond to those rejections. 您必须弄清楚您的客户端代码将如何获得并响应这些拒绝。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM