在多个实体之间同步数据最聪明,最简单的方法是什么?

时间:2010-01-19 09:12:53

标签: database algorithm mobile synchronization

在当今世界,许多计算机,移动设备或Web服务共享数据或充当集线器,同步变得更加重要。众所周知,同步的解决方案并不是最舒适的解决方案,最好不要同步。

我仍然很好奇如何实现同步解决方案以在多个实体之间进行同步。已经存在许多不同的方法,例如比较更改的日期字段或散列并使用最新数据或让用户在冲突的情况下选择他想要使用的内容。另一种方法是尝试自动合并冲突的数据(在我看来,这并不是那么聪明,因为机器无法猜出用户的意思)。

无论如何,在开始实施同步之前,我们应该回答一些与同步相关的问题:

  • 最新数据是什么?我想如何表示它?
  • 如果发生冲突,我该怎么办?合并?我是否提示并询问用户该做什么?
  • 当我遇到不一致的状态(例如由于移动网络连接导致断开连接)时该怎么办?
  • 当我不想陷入不一致的状态时,我该怎么做?
  • 如何恢复被中断的当前同步?
  • 如何处理数据存储(例如,网络服务上的MySQL数据库,iPhone上的核心数据;以及如何在没有大量胶水代码的情况下合并/同步数据)?
  • 如何处理同步期间发生的用户编辑(在后台运行,因此不会阻止用户界面)?
  • 我如何以及在哪个方向传播更改(例如,用户在他的计算机上创建“Foo”条目并且不同步;然后他在旅途中创建另一个“Foo”条目;当他尝试时会发生什么同步两个设备)?用户是否会有两个具有不同唯一ID的“Foo”条目?用户是否只有一个条目,但是哪个条目?
  • 当我有分层数据时,我该如何处理同步?自顶向下?自下而上?我是否以原子方式处理每个条目,还是仅查看超级节点?在过度简化事物和投入太多时间进行实施之间进行权衡有多大?
  • ...

还有很多其他问题,我希望我能给你足够的启发。同步是一个相当普遍的问题。一旦找到一个好的,多功能的同步方法,它应该更容易应用于具体的应用程序,而不是从头开始思考。我意识到已经有很多应用程序试图解决(或成功解决)同步,但它们已经相当具体,并且一般都没有给同步方法提供足够的答案。

3 个答案:

答案 0 :(得分:47)

在我工作的地方,我们开发了主要(网络)应用程序的“离线”版本,以便用户能够在他们无法访问互联网的地方使用他们的笔记本电脑(我不确定其中有多少这些日子确实存在,但我被告知他们这样做;))。当用户返回主站点时,他们需要将他们离线输入的数据与我们的主应用程序同步。

所以,回答你的问题:

  
      
  • 最新数据是什么?我想如何表示它?
  •   

我们在每个表上都有一个LAST_UPDATED_DATE列。服务器会跟踪同步发生的时间,因此当脱机应用程序请求同步时,服务器会说“嘿,只给我自此日期以来的数据更改”。

  
      
  • 如果发生冲突,我该怎么办?合并?我提示并问   用户该怎么做?
  •   

在我们的案例中,离线应用程序只能更新所有数据的相对较小的子集。当每个记录同步时,我们检查它是否是这些情况之一,如果是,那么我们比较在线和离线记录的LAST_UPDATED_DATE。如果日期不同,那么我们也会检查这些值(因为如果它们都更新为相同值,则不会发生冲突)。如果存在冲突,我们会记录差异,设置一个标志,表示至少存在一个冲突,并继续检查其余的细节。一旦完成该过程,则如果设置了“isConflict”标志,则用户能够转到显示差异的特殊页面并确定哪个数据是“正确”版本。然后将此版本保存在主机上,并重置“isConflict”标志。

  
      
  • 当我不想陷入不一致时,我该怎么办?   状态?
  •   
  • 如何恢复被中断的当前同步?
  •   

好吧,我们试图避免首先陷入不一致的状态。如果同步因任何原因而中断,则last_synchronisation_date不会更新,因此下次启动同步时,它将从与上一次(中断)同步的开始日期相同的日期开始。

  
      
  • 如何处理数据存储(例如,Web服务上的MySQL数据库,Core   iPhone上的数据;我该怎么做   合并/同步数据没有太多   胶水代码)?
  •   

我们在两个应用程序上使用标准数据库,在两者之间使用Java对象。对象被序列化为XML(并进行gzip以加速传输)以进行实际的同步过程,然后在每一端进行解压缩/反序列化。

  
      
  • 我应该如何处理同步期间用户所做的编辑   (在后台运行,所以   UI未被阻止)?
  •   

这些编辑将在同步开始日期之后进行,因此在下次同步之前不会在另一侧进行拾取。

  
      
  • 我如何以及在哪个方向传播更改(例如,用户创建   他的电脑上有一个“Foo”条目   不同步;然后他就在旅途中   创建另一个“Foo”条目;什么   当他试图同步两者时发生   设备)?用户会有两个“Foo”   具有不同唯一ID的条目?   用户是否只有一个条目,但是   哪一个?
  •   

由你决定如何处理这个特殊的Foo ...即取决于Foo的主键是什么以及你如何确定一个Foo是否与另一个相同。

  
      
  • 当我有分层数据时,我该如何处理同步?自顶向下?   自下而上?我会对待每一个条目吗?   原子地或我只看一个   超级节点?
  •   

同步是原子的,因此如果一条记录失败,则整个过程被标记为不完整,类似于subversion提交事务。

  
      
  • 过度简化事物和投资之间的权衡有多大   太多时间进入实施?
  •   

我不确定您的意思,但我会说这完全取决于您的情况以及您要同步的数据类型/数量。设计和实施过程可能需要很长时间,但这是可能的。

希望能帮助您或者至少为您提供一些想法! :)

答案 1 :(得分:4)

可能“不是一个真正的问题”,这不是一个真正的答案:

我认为分布式版本控制系统(例如Mercurial或git)已经找到了很大一部分。但是,它们要求人们接受可能存在多个“最新”版本,并且有时冲突的更新需要手动解决才能解决。此外,如果您对保留整个更改历史记录不感兴趣,那么这些系统中会有相当多的开销(但当然,最近的历史记录对于找到共同的祖先以确定两个版本的相关性是必要的。)

但我同意你的观点,在每个人都有数据分布在多个设备和服务的世界中,自动跟踪和分发更新的需求将变得非常迫切,以至于应用程序使用的常见文件格式将包含足够的元数据 - 数据促进某种智能合并行为。但是这种行为可能必须在应用程序级别上发生,因为没有通用的方法来解决冲突的更新。

同时,iTunes-iPod方法最简单:您只有一个主库,每个设备都从那里拉出来。显然,单主同步在所有情况下都不是很令人满意(特别是当涉及多个用户时),但是,如果有更多的应用程序提供这样的工作选项,我将不胜感激(烦恼:我有三台Mac)有三个iPhoto安装。如果它们从一个专用主​​机自动同步,就像照片同步到我的iPod一样,那将是一个改进。)

答案 2 :(得分:-1)

虽然它在微软生态系统中非常有用,但您可以学习Mobile Application Blocks