Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 同步两个对象列表_Algorithm_List_Data Synchronization - Fatal编程技术网

Algorithm 同步两个对象列表

Algorithm 同步两个对象列表,algorithm,list,data-synchronization,Algorithm,List,Data Synchronization,问题 我有两个对象列表。每个对象包含以下内容: GUID(允许从业务中确定对象是否相同 (观点) 时间戳(每次 对象(已更改) 版本(正整数;每次递增 对象已更改) 已删除(布尔标志;改为切换为“true”) (实际对象的删除) 数据(一些有用的负载) 如果需要,还有其他字段吗 接下来,我需要根据以下规则同步两个列表: 如果具有某些GUID的对象仅显示在一个列表中,则应将其复制到另一个列表中 如果两个列表中都显示了具有某些GUID的对象,则Version较少的实例应替换为具有较大Versi

问题

我有两个对象列表。每个对象包含以下内容:

  • GUID
    (允许从业务中确定对象是否相同 (观点)
  • 时间戳
    (每次 对象(已更改)
  • 版本
    (正整数;每次递增 对象已更改)
  • 已删除
    (布尔标志;改为切换为“true”) (实际对象的删除)
  • 数据
    (一些有用的负载)
  • 如果需要,还有其他字段吗
接下来,我需要根据以下规则同步两个列表:

  • 如果具有某些
    GUID
    的对象仅显示在一个列表中,则应将其复制到另一个列表中
  • 如果两个列表中都显示了具有某些
    GUID
    的对象,则
    Version
    较少的实例应替换为具有较大
    Version
    的实例(如果版本相同,则无需执行任何操作)
现实世界的要求:

  • 每个列表有50k+个对象,每个对象大约1KB
  • 列表放置在通过互联网连接的不同机器上(例如,移动应用程序和远程服务器),因此,算法不应该浪费太多的流量或CPU
  • 大多数时间(比如96%)列表在同步过程之前已经同步,因此,算法应该以最小的努力来确定它
  • 如果存在任何差异,大多数情况下差异都很小(更改/添加了3-5个对象)
  • 如果一个列表为空(而另一个列表仍有50k+项),则应继续确定
解决方案#1(目前已实施)

  • 客户端存储上次同步成功的时间(例如
    T
  • 这两个列表都要求所有具有
    时间戳
    T
    (即最近修改的;在生产中是…>(
    T
    -day)的对象具有更好的稳健性)
  • 这些最近修改过的对象的列表会自动同步:
    • 仅在第一个列表中显示的项目将保存到第二个列表中
    • 仅在第二个列表中显示的项目将保存到第一个列表中
    • 其他项目比较其
      版本
      ,并保存到专用列表(如果需要)
  • 过程:

    • 小改动效果好
    • 几乎符合要求
    缺点:

    • 依赖于
      T
      ,这使得算法很脆弱:很容易同步上一次更新,但很难确保列表完全同步(使用最小的
      T
      ,如1970-01-01只是挂起同步过程)
    我的问题:

  • 是否有任何通用/最佳实践/经验证的方法来同步对象列表
  • 有什么比我的情况更好的解决方案吗
  • 已查看的p.S.,不重复:


      • 我想到两个建议,第一个可能是你已经在做的事情:

        1) 不要发送时间戳>t的整个项目列表。相反,发送时间戳>t的(UUID,Version)对象元组列表。然后另一方可以确定需要从中更新哪些对象。将这些对象的UUID发送回请求实际对象。如果完整对象的timestamp>T,但在另一端已经更新了(或者已经有了最新版本),则可以避免发送完整对象

        2) 不要一次处理完整列表,而是分块处理,即先同步10%,然后是下一个10%,以此类推,以避免在大型同步中一次传输过多数据(并允许在连接中断时重新启动点)。这可以通过以下方式实现:例如,从校验和等于1模10的所有UUID开始,然后是1模10等


        另一种可能是主动同步,例如异步发布机会,可能通过UCP(与TCP相反不可靠)。当您需要当前信息时,您仍然需要同步,但大多数信息都是当前信息。

        您需要存储的不是上次同步的时间,而是上次同步时对象的状态(例如对象数据的哈希)。然后将每个列表与存储的列表进行比较,找出每一侧的对象都发生了变化

        这比依赖时间要可靠得多,因为时间要求双方都有同步计时器,以提供精确的时间(大多数系统并非如此)。出于同样的原因,基于时间+版本检测更改的想法可能比最初看起来更容易出错

        此外,最初不传输对象数据,只传输guid

        顺便说一句,我们已经制作了一个框架(源代码免费),它正好解决了您的问题。我没有给出链接,因为有些人才会抱怨

        总结 所有答案都有一些价值。总而言之,以下是我根据最终实现的工作同步系统寻找的编译答案:

      • 通常,使用。它们在比较大量数据时非常有效

      • 如果可以,在每次需要时从头开始重建哈希树。 检查重建哈希树所需的时间。最有可能的情况是速度相当快(例如,在我的Nexus 4上,为20k个项目重建树需要2秒:从数据库获取数据需要1.8秒,构建树需要0.2秒;服务器执行速度要快20倍),因此您不需要将树存储在数据库中,并在数据更改时维护它(我的第一次尝试是只重建相关的分支——实现起来不太复杂,但非常脆弱)

      • 然而,如果根本没有进行任何数据修改,缓存和重用树是可以的。一旦发生修改,将使整个缓存失效

      • 技术细节
        • GUID长度为32个字符,不带任何连字符/大括号,小写
        • 我使用高度为4的16元树,其中每个分支都与GUID的字符相关