同步常见分布式数据的最佳实践

chu*_*ubs 15 database distributed synchronization offline

我有一个支持离线模式的互联网应用程序,用户可能会在用户重新联机时创建将与服务器同步的数据.如此,因为这个我使用UUID的身份在我的数据库,所以断开的客户端可以不用担心使用其他客户端使用的ID等,但产生的新对象,而这个伟大工程由该用户有拥有的对象是多个用户共享的对象.例如,用户使用的标记可能是全局的,远程数据库无法保存Universe中所有可能的标记.

如果脱机用户创建对象并向其添加一些标记.假设用户的本地数据库中不存在这些标记,因此软件会为它们生成UUID.现在,当这些标签同步时,需要通过解决过程来解决任何重叠.某种方法可以将远程数据库中的任何现有标记与本地版本进行匹配.

一种方法是使用一些进程,通过自然键(在标记的情况下为名称)解析全局对象,并且本地数据库必须用全局数据库中的对象替换现有对象.当与其他对象有许多连接时,这可能会很混乱.有些东西告诉我要避免这种情况.

处理此问题的另一种方法是使用两个ID.一个全局ID和一个本地ID.我希望使用UUID可以帮助避免这种情况,但我会在使用单个UUID和使用两个拆分ID之间来回切换.使用这个选项让我想知道我是否让问题失控.

另一种方法是通过非共享对象跟踪所有更改.在此示例中,用户分配标记的对象.当用户同步其脱机更改时,服务器可能会将其本地标记替换为全局标记.下次此客户端与服务器同步时,它会检测到非共享对象的更改.当客户端拉下该对象时,他将收到全局标记.该软件将简单地重新保存非共享对象,将其指向服务器的标签并孤立其本地版本.这方面的一些问题是完全同步的额外往返,以及刚刚孤立的本地数据库中的额外数据.当系统处于同步状态之间时,是否还会出现其他问题或错误?(即尝试与服务器通信并向对象发送本地UUID等).

另一种选择是避免常见物体.在我的软件中,这可能是一个可接受的答案.我没有在用户之间进行大量的对象共享,但这并不意味着我将来不会这样做.这意味着如果我需要添加这些类型的功能,选择此选项可能会在将来使我的软件瘫痪.这个选择有后果,我不确定我是否已经完全探索过它们.

所以我正在寻找任何类型的最佳实践,处理此类系统的现有算法,选择指南等.

Ove*_*ked 5

根据您要为用户提供的应用程序语义,您可以选择不同的解决方案.例如,如果您实际上是在谈论使用关键字标记离线用户创建的对象,并希望在不同用户创建的多个对象之间共享标记,那么根据您的建议使用标记的"text"就可以了.一旦合并了每个人的更改,就会共享具有相同"文本"的标签,例如"说这太棒了".

还有其他方法可以处理对共享对象的断开连接更新.SVN,CVS等版本控制系统尝试自动解决冲突,何时不能,只会告诉用户存在冲突.您也可以这样做,只需告诉用户有并发更新,用户必须处理解决方案.

或者,您也可以将更新记录为更改单位,并尝试将更改组合在一起.例如,如果您的共享对象是画布,并且您的应用程序语义允许在同一画布上共享绘图,那么从A点到B点绘制一条线的断开连接更新,以及从C点到点绘制一条线的另一个断开连接的更新D,可以组成.在这种情况下,如果将这两个更新保留为两个操作,则可以订购这两个更新,并且在重新连接时,每个用户都会上载其所有断开连接的操作,并应用其他用户的缺失操作.您可能需要某种排序规则,可能基于版本号.

另一种选择:如果无法自动协调对共享对象的更新,并且您的应用程序语义不支持通知用户并要求用户解决由于断开连接更新而导致的冲突,那么您还可以使用版本树来处理此问题.对共享对象的每次更新都会创建一个新版本,并将过去的版本作为父版本.当来自两个不同用户的共享对象的断开连接更新时,两个单独的子版本/叶节点来自相同的父版本.如果应用程序的内部状态表示形式是此版本树,那么尽管断开连接更新,应用程序的内部状态仍保持一致,您可以通过其他方式处理版本树的两个分支(例如,让用户知道分支并为其创建工具)合并分支,如源控制系统).

只是几个选项.希望这可以帮助.


Skl*_*vvz 4

您的问题与 SVN 等版本控制系统非常相似。你可以从中举个例子。

每个用户都会拥有一组个人对象以及他们需要的任何共享对象。在本地,他们将像拥有所有对象一样工作。

在同步期间,客户端将首先下载对象中的任何更改,并自动同步明显的内容。在您的示例中,如果有来自服务器的同名新标签,那么它将在本地系统上相应地更新 UUID。

这也是检测和处理诸如从另一个客户端但由同一用户提交的数据之类的情况的好地方。

一旦客户端有了数据的更新和合并版本,您就可以进行上传。

将会有往返,但我认为没有办法在不使数据结构过于复杂并且在同步方式上存在潜在陷阱的情况下做到这一点。