在两个不同的系统之间同步对象,最好的方法?

Posted

技术标签:

【中文标题】在两个不同的系统之间同步对象,最好的方法?【英文标题】:Syncing objects between two disparate systems, best approach? 【发布时间】:2009-03-11 22:50:03 【问题描述】:

我正在使用基于 XML 的有效负载在 iPhone 和网站之间同步两个业务对象,并且很想征求一些关于最佳例程的想法。

虽然这个问题的性质相当笼统,但我可以看到它适用于需要在 Web 实体和客户端(台式机、手机等)之间同步业务对象的各种不同系统。

可以在双方编辑、删除和更新业务对象。双方都可以在本地存储对象,但同步仅在 iPhone 端启动,以便断开连接查看。所有对象都有一个 updated_at 和 created_at 时间戳,并由双方的 RDBMS 支持(iPhone 端的 SQLite 和 Web 上的 mysql ......我认为这再次无关紧要)并且手机确实记录了最后一次已尝试同步。否则,不会存储其他数据(目前)。

您会使用什么算法来最大程度地减少系统之间的网络干扰以进行同步?如果“软删除”不是一个选项,您将如何处理删除?您会添加哪些数据模型更改来促进这一点?

【问题讨论】:

【参考方案1】:

最简单的方法:同步时,传输所有记录where updated_at >= @last_sync_at。缺点:这种方法根本不能很好地容忍时钟偏差。

保留每次更新行时递增的版本号列(这样时钟偏差不会影响您的同步过程)和最后同步的版本号(这样可能会发生冲突的更改)可能更安全确定)。为了提高带宽效率,请在发送到每个复制对等方的最后一个版本的每个数据库中保留一个缓存,以便只需要传输修改的行。如果这将是星型拓扑,则叶子可以使用简化的模式,其中最后同步的版本存储在每个表中。

为了支持删除同步,需要某种形式的软删除,但这可以是仅包含已删除行的键的“墓碑”记录的形式。只有当您确定所有副本都已处理了墓碑后,才能安全地删除它们,否则一个散乱的副本可能会恢复您认为已删除的记录。

【讨论】:

感谢您的反馈。我认为您提出的有关时间偏差的问题很重要。我最初的希望是在服务器上的 NTP 和 iPhone/Touch 自己的时间同步服务与运营商/计算机之间 - 时间偏差问题将得到缓解。这种假设是否太危险了? 它在很多方面都很脆弱——例如,时钟向后重置也会导致错过更新,错过更新会导致未检测到的编辑冲突。多主复制是一项不平凡的任务。 感谢您的友好建议。希望在几周内,您将能够看到智慧的果实。相关网站已经上线 (www.ayenotes.com),但 iPhone 应用程序尚未上线。 我现在什至不认识那个域中有什么。【参考方案2】:

所以我认为总的来说,您的问题与断开的同步有关。

所以这是我认为应该发生的事情:

初始同步 您检索数据和与之相关的任何信息(行版本、文件校验和等)。重要的是您存储此信息并使其保持原始状态,直到下一次成功同步。应在此数据的副本上进行更改。

跟踪更改 如果您正在处理数据库行,那么您基本上必须跟踪插入、更新和删除操作。如果您正在处理像 xml 这样的文本文件,那么它会稍微复杂一些。如果可能有多个用户同时编辑此文件,那么您将必须有一个 diff 工具,以便可以在更精细的级别(而不是整个文件)检测冲突。

检查冲突 如果您只是处理数据库行,那么很容易检测到冲突。每当更新行时,您可以有另一列递增(我认为 mssql 有这个内置函数不确定 mysql)。因此,如果您拥有的副本的编号与服务器上的编号不同,那么您就会发生冲突。对于文件或字符串,校验和将完成这项工作。我想你也可以使用修改后的日期,但要确保你有一个非常精确和准确的测量来防止错过。例如:假设我检索了一个文件,并且您在我检索到它后立即保存它。可以说时间差是 1 毫秒。然后我对文件进行更改,然后尝试保存它。如果记录的最后修改时间仅精确到 10 毫秒,那么我检索到的文件很有可能与您保存的文件具有相同的修改日期,因此程序认为没有冲突并覆盖您的更改。所以为了安全起见,我一般不会使用这种方法。另一方面,小修改后校验和/哈希冲突的可能性几乎为零。

解决冲突 现在这是棘手的部分。如果这是一个自动化过程,那么您必须评估情况并决定是否要覆盖更改、丢失更改或再次从服务器检索数据并尝试重做更改。幸运的是,似乎会有人际互动。但是编写代码仍然很痛苦。如果您正在处理数据库行,您可以检查每个单独的列并将其与服务器中的数据进行比较并将其呈现给用户。这个想法是以非常精细的方式向用户呈现冲突,以免压倒他们。大多数冲突在许多不同的地方都有非常小的差异,因此一次向用户呈现一个小的差异。因此,对于文本文件,它几乎相同,但要复杂一百倍。所以基本上你必须创建或使用一个差异工具(文本比较是一个完全不同的主题,这里太宽泛了),让你知道文件中的小变化以及它们在哪里以类似的方式在一个数据库:插入、删除或编辑文本的位置。然后以相同的方式将其呈现给用户。所以基本上对于每个小的冲突,用户必须选择是丢弃他们的更改、覆盖服务器中的更改还是在发送到服务器之前执行手动编辑。

因此,如果您做对了事情,则应该为用户提供一份冲突列表(如果有的话)。这些冲突应该足够细化,以便用户快速做出决定。因此,例如,冲突是拼写更改,与给用户整个段落并告诉他有更改并且他们必须决定做什么相比,用户从单词拼写中选择会更容易,然后用户将不得不寻找这个小的拼写错误。

其他注意事项:数据验证 - 请记住,您必须在解决冲突后执行验证,因为数据可能已更改文本比较 - 就像我说的,这是一个大主题。所以谷歌它!断开同步 - 我认为那里有几篇文章。

来源:https://softwareengineering.stackexchange.com/questions/94634/synchronization-web-service-methodologies-or-papers

【讨论】:

以上是关于在两个不同的系统之间同步对象,最好的方法?的主要内容,如果未能解决你的问题,请参考以下文章

怎么在一个 mysql 服务的两个不同数据库 database或者是表 之间作同步

linux系统编程--线程同步

打造私人搜书系统之系统设计

React 两个组件之间的状态同步或两个不同事物之间的更改同步

在 C++ 中的两个线程之间同步变量的正确方法是啥?

当唯一的区别是标签时,如何在两个s3桶之间同步对象