我有一个包含大约 10 种对象类型的应用程序。每种类型可能有几千个对象实例。这些对象列表需要在不同计算机上运行的应用程序之间保持同步。如果添加、更改或删除对象,则需要传播到其他计算机。

这将是一个星形拓扑——有一个中央主机,其余的是客户端。

我确实有会话的概念,因此可以存储有关每个客户端的数据。

有没有一个好的设计模式可以遵循?更好的是,是否有一个(基于模板的?)库可以处理询问容器自客户端 X 到来以来发生了什么变化并发送该增量?

现在我认为每个对象类型容器都有一个更新计数器。当添加/更改/删除某些内容时,更新计数器会递增,并且更改的对象会用该值进行标记。每个客户端在获得更新时都会保存更新计数器的值。稍后它会返回并要求进行任何更改,因为它更新了计数器值。最后,删除保留为逻辑删除记录(尽管我不确定何时清除它们)。

让这变得更困难的一件事是,客户端可以在中央服务器不一定知道的情况下来来去去,尽管我猜可能存在超时概念(如果服务器在 5 分钟内没有收到客户端的消息,则假设客户端已经离开)

这是一个众所周知的模式吗?还有其他建议吗?

有帮助吗?

解决方案

如何实现同步很大程度上取决于您的需求。是否需要将更改发送给客户端,或者客户端在使用对象时检查对象是否是最新的就足够了吗?如何使用 代理模式?此模式允许您创建对象的代理实现,该实现可以检查它们是否是最新的,如果不是最新的则进行更新,然后返回结果。我将通过在主服务器上的对象上设置lastChanged 时间戳并在客户端对象上设置lastUpdated 时间戳来实现此目的。如果延迟是一个问题,则在每次调用时检查对象是否是最新的可能不是一个好主意。考虑使用一个单独的线程来查询主服务器是否有已更改的对象并将它们标记为“脏”。这也可以显着减少网络流量。

您还可以查看 观察者模式发布/订阅.

其他提示

这可能是实现简单,还是相当有效的方法是治疗对象的桩作为不透明BLOB和使用librsync他们同步。这听起来像所有更新流的一个方向,由主到客户,大概有客户端上的某些对象持久性陈述 - 文件或东西。我假设它是这个答案的其余部分文件,但任何字节序列可以使用。

它的工作方式是,每个客户端会产生的本地团块的副本librsync“签名”,并发送签名的主人。签名是块大小的约1%。然后,主会使用librsync以计算签名和当前数据之间的增量,并发送增量到客户端,这将使用librsync到增量施加到其本地团块的副本。

在librsync API是简单,并且签名/增量的数据传输是相对高效的。

如果这不是可行的,它仍可能采取更手册“基于增量的”的方法,以避免必须做每个对象的版本是有用的。每次主进行了更改,应该日志变化到日记,记录这事和哪些对象。版本是在整个数据库级别完成的,因此在效果的版本号分配给每个日记条目。

当一个客户端连接,它应该发送它的整个对象集合的版本,然后服务器可以与客户端版本和最新的项目之间的期刊的内容作出回应。如果给定对象上的更新被完全替换对象的内容做了,那么你可以过滤掉所有,但最新版本的每个对象的优化这个。如果主还跟踪哪个版本的已发送到客户端,就可以知道什么时候是安全的废旧日记帐分录。即使不跟踪,你可以根据一些启发式(可能只是年龄)还是丢弃旧日志条目,如果你从客户端接收其最后的版本比最古老的日记条目年长的连接,那么你只需要发送的整组对象的该客户端。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top