代码之家  ›  专栏  ›  技术社区  ›  DougN

在计算机(C++)中同步对象列表的模式?

  •  0
  • DougN  · 技术社区  · 15 年前

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

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

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

    有没有一个好的设计模式可以遵循?更好的是,是否有(基于模板的?)这个库可以处理询问容器自客户机x出现以来发生了什么变化,并让delta发送出去?

    现在我想每个对象类型容器都有一个更新计数器。当添加/更改/删除某些内容时,更新计数器将递增,更改的对象将用该值进行标记。每个客户机在收到更新时都会保存更新计数器的值。稍后,它将返回并请求任何更改,因为它是更新计数器值。最后,删除作为墓碑记录保存(尽管我不确定何时清除它们)。

    有一件事使这变得更困难,那就是客户机可以来来去去去,而中央服务器不必知道,尽管我猜可能有一个超时概念(如果服务器在5分钟内没有收到客户机的消息,那么它假定客户机已经不在了)。

    这是一种众所周知的模式吗?还有什么建议吗?

    2 回复  |  直到 15 年前
        1
  •  1
  •   larsmoa    15 年前

    如何实现同步在很大程度上取决于您的需要。是否需要将更改发送到客户机,或者客户机在每次使用对象时都检查对象是否是最新的?用这个怎么样 Proxy pattern 是吗?此模式允许您创建对象的代理实现,以检查对象是否是最新的,如果不是,则进行更新,然后返回结果。我可以通过在master上的对象上使用lastchanged时间戳和在client对象上使用lastupdated时间戳来实现这一点。如果延迟是一个问题,那么在每次调用时检查对象是否是最新的可能不是一个好主意。考虑使用一个单独的线程来查询主控形状中已更改的对象并将其标记为“脏”。这也可以显著减少网络流量。

    你也可以看看 Observer pattern Publish/Subscribe .

        2
  •  0
  •   divegeek    15 年前

    一个可能实现起来很简单但仍然相当有效的选项是将一堆对象视为不透明的blob,并使用librsync来同步它们。听起来所有的更新都是朝一个方向流动的,从主服务器到客户机,客户机上的对象可能有一些持久的表示——一个文件或其他东西。我假设它是这个答案的其余部分的一个文件,尽管可以使用任何字节序列。

    它的工作方式是,每个客户机将生成其blob本地副本的librsync“签名”,并将该签名发送给主服务器。签名大约是blob大小的1%。然后,master将使用librsync计算该签名和当前数据之间的增量,并将增量发送给客户机,客户机将使用librsync将增量应用于其blob的本地副本。

    librsync API简单,签名/增量数据传输相对高效。

    如果这不可行,那么采取更为手动的“基于增量”方法可能仍然有用,以避免必须对每个对象进行版本控制。每次主控形状进行更改时,它都应该将更改记录到日志中,记录所做的操作和对象。版本控制是在整个数据库级别完成的,因此实际上,每个日记条目都分配了一个版本号。

    当一个客户机连接时,它应该发送整个对象集合的版本,然后服务器可以在客户机版本和最新条目之间用日志的内容进行响应。如果对给定对象的更新是通过完全替换对象内容来完成的,那么可以通过筛选出每个对象的所有最新版本来优化此更新。如果主服务器还跟踪它发送到哪个客户机的版本,那么它可以知道何时可以安全地丢弃旧的日志条目。即使它没有跟踪到这一点,您仍然可以根据一些启发式(可能只是年龄)丢弃旧的日志条目,并且如果您从一个客户端接收到一个连接,该客户端的最后版本比最旧的日志条目早,那么您只需将整个对象集发送到该客户端即可。