实时数据缓存,多个订阅者和实时更新

3
我有一个设计问题。我有一个应用程序,它订阅实时系统以显示数据。基本上,客户端连接到服务器,在当前时间下载数据快照,并订阅实时更新,这些更新立即显示在UI上。
我们遇到的一个问题是,我们可以打开多个实时报告,这意味着我们有多个连接和不必要的数据复制。因此,我们想建立一个中央数据存储库来保存所有数据并为报告提供服务,这样我们只使用一个套接字连接和一组数据通过网络传输。
我的问题是这样的。当报告订阅我的数据存储库时,它检索当前时间的快照,然后接收实时更新。这意味着我的存储库正在使用来自服务器的实时更新更新其内部缓存,并将这些更新发送给订阅的报告。
当另一个报告连接到存储库时,它也需要下载当前数据并订阅更新。但是,如果在下载快照时出现更新,报告将会错过这些更新。我也不能在下载快照时锁定缓存,因为这会导致报告1停止更新,而报告2获取其快照。
如何确保报告1继续获取其更新,而报告2下载未被篡改的快照,然后开始接收其错过的所有更新以及未来的更新?
抱歉,如果这不清楚。我并不总是能描述清楚我的问题 :) 进来的数据本质上是表中的行,然后我将其总结为树形结构。它们可以通过“行”中的关键字段进行标识,我的缓存将存储每个“行”的最新副本。
提前感谢!
2个回答

0
为什么不让每个缓存状态都有一个哈希值。所有的订阅者必须向管理者确认当前哈希值,如果我们的哈希值与之不同,则触发下载更新。
我建议您保存更新并允许客户端在订阅更新之前自行更新到最新版本。您可以调整存储更新的时间跨度。

0

如果我理解正确,您的系统有三个部分:

  1. 实时系统,用于编写报告信息
  2. 缓存服务器,用于存储信息
  3. 客户端,用于获取此信息

是这样的吗?

如果是这样,如果我是您,我会为缓存服务器开发一个管理器,并为实时系统和客户端制作两个API,以便它们可以与缓存服务器一起使用。我会遵循一个规则:一次只写入一个,没有人读取或全部读取没有人写入。我会制作队列。一个用于客户端请求,一个用于实时请求。我们需要同步机制来处理这些队列。

我看到下面的工作方式:

如果实时系统编写新信息:

  1. 当前有为报告更新而设计的客户端阅读器

    1.1 缓存管理器将这些报告的所有信息写入第二个存储区

    如果管理器发现有新的信息,它会停止新的读取请求并将它们放入队列中等待,直到已经开始读取的所有线程完成,并从第二个存储库向第一个存储库做出更新。

  2. 没有读者

    2.1 将信息放入主存储区并阻塞正在被修改的报告上的读者

如果您的实时系统真正是实时(在实时处理器上运行)且每次都进行写操作,您应该为合并两个存储区添加超时时间并在此期间停止读取器。


嗨Eugene,感谢您的回复。问题之一是报告可以随时打开,并且必须赶上到目前为止发布的所有数据,但还必须订阅进一步的更新,而不会停止对其他已订阅报告的更新。您的解决方案可以工作,但它会导致现有报告停止更新,而新连接的报告“赶上”,对吗?这是我最初解决方案的一部分,但现在我正在寻找一种方法,在我赶上新报告的同时保持现有报告的进行,并且然后像其他报告一样成为观察者。 - Greg Olmstead
是的,你理解我的想法了。我认为你需要找到阻止报告更新的位置,因为你不能同时在同一份报告中进行写入和读取。这样会导致用户受到错误的信息。 - Eugene Petrov
如果我们把获取新信息的责任不放在客户端程序上,而是放在缓存服务上会怎样呢?当您的实时系统生成新信息时,通过API将其放入缓存服务中。缓存服务更新缓存中的报告,并制作一个包(您可以发明自己的协议),其中包含报告的新信息,并将其放入队列中,然后机制获取此信息并发送给客户端。因此,我们得到了一个系统,当不是客户端请求更新,而是客户端连接并仅侦听新信息时。在这种情况下,我们不必阻止任何东西。 - Eugene Petrov
除非您的客户第一次要求报告,当然。 - Eugene Petrov
我喜欢你的想法。如果你指定的实时性能够允许一些向过去的偏移,那么你可以始终将足够追赶数据放入“下载”包中。这样只要你能保证下载持续时间,就不需要新的协议。 - Bamboo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接