Nik*_*sik 5 algorithm list data-synchronization
问题
我有两个对象列表。每个对象包含以下内容:
GUID (允许确定对象是否相同 - 从业务角度来看)Timestamp (每次对象更改时更新到当前 UTC)Version (正整数;每次对象改变时递增)Deleted (布尔标志;切换到“真”而不是实际删除对象)Data (一些有用的有效载荷)接下来,我需要根据这些规则同步两个列表:
GUID仅出现在一个列表中,则应将其复制到另一个列表中GUID两个列表中都出现了一些对象,Version则应将具有较少的实例替换为具有较大的实例Version(如果版本相同,则无关紧要)实际要求:
解决方案#1(目前已实施)
T)Timestamp> T(即最近修改过的对象;在生产中它是 ... > ( T- day ) 以获得更好的健壮性)Version's 进行比较并保存到专用列表(如果需要)过程:
缺点:
T,这使算法变得脆弱:同步上次更新很容易,但很难确保列表完全同步(使用T1970-01-01 之类的最小化只是挂起同步过程)我的问题:
PS 已查看,不重复:
所有答案都有一些有价值的点。总而言之,这是我正在寻找的编译答案,基于最终实现的工作同步系统:
\n\n一般来说,使用默克尔树。它们在比较大量数据方面非常高效。
如果可以的话,每次需要时都从头开始重建哈希树。\n检查重建哈希树所需的时间。最有可能的是它非常快(例如,在我的例子中,在 Nexus 4 上重建 20k 项的树大约需要 2 秒:从数据库获取数据需要 1.8 秒 + 构建树需要 0.2 秒;服务器的执行速度大约快 20 倍),所以您不需要将树存储在数据库中并在数据更改时维护它(我的第一次尝试是仅重建相关分支 \xe2\x80\x94 它实现起来不太复杂,但非常脆弱)。
尽管如此,如果根本没有进行数据修改,缓存和重用树是可以的。一旦发生修改,使整个缓存失效。
0000\xe2\x86\x92 (具有 GUID 的项目的哈希值0000*)0001\xe2\x86\x92 (具有 GUID 的项目的哈希值0001*)ffff\xe2\x86\x92 (具有 GUID 的项目的哈希值ffff*);000\xe2\x86\x92 (哈希值的哈希值000_)00\xe2\x86\x92 (哈希值的哈希值00_)_)因此,树有 65536 个叶子,需要 2 Mb 内存;每片叶子覆盖 ~N/65536 数据项。二叉树在内存方面的效率会提高两倍,但实现起来却更困难。
\n\n我必须实现这些方法:
\n\ngetHash()\xe2\x80\x94 返回根哈希值;用于主要检查(如上所述,\nin 96% 这就是我们需要测试的全部);getHashChildren(x)\xe2\x80\x94 返回哈希值列表x_(最多 16 个);用于有效的、单一请求发现数据差异;findByIdPrefix(x)\xe2\x80\x94 返回带有 GUID 的项目x*,x 必须恰好包含 4 个字符;用于请求叶子项目;count(x)\xe2\x80\x94 返回具有 GUID 的项目数x*;当相当小时,我们可以取消逐个分支地检查树并通过单个请求传输一堆项目;就每个分支传输少量数据而言,它的响应非常灵敏(您可以随时检查进度)+对于意外终止(例如,由于网络故障)非常稳健,并且可以轻松地从如果需要的话最后一点。
version_1= version_2,但是hash_1!= hash_2}:在这种情况下,您必须做出一些决定(也许需要用户的帮助或比较时间戳作为最后的手段)并用另一个项目重写某些项目来解决冲突,否则你最终会得到不同步和不可同步的哈希树。(GUID, Version)针对轻量化请求实现无负载的传输对。