【发布时间】:2019-01-14 10:43:29
【问题描述】:
我有一个向多个订阅者发送消息的发布者应用程序。每条消息都被分配一个递增的序列号。假设 A、B 和 C 是三个订阅者,Publisher 已将消息编号 1 发送给 A,将 2,3,4,7 发送给 B,将 5,6 发送给 C。
消息编号 x 将发送给 A、B 还是 C 订阅者是消息的某些不可变属性(不是编号)的函数,即消息编号 7 被路由到 B,因为它可能与符号以开头的股票有关'b'。
发布者有一个映射,其中包含发送给每个订阅者的最大序列号。目前的地图将如下所示:
{"A" -> 1, "B" ->7, "C" ->6}
此时我们不知道这些消息是否成功传递给各自的订阅者。但是,保证消息将按顺序传递。
如果我们遇到需要重启发布者的灾难,我们需要重播可能已经丢失给订阅者的消息。
重要提示:为了向订阅者重播消息,发布者需要向另一个上游服务器发送重播请求,并且它没有持久存储之前看到的所有消息。所以这里的发布者更像是一个路由器。从上游服务器重播消息是有成本的,所以我想尽量减少需要重播的消息数量。
我使用的当前算法是找到每个订阅者收到的最大消息序列。假设我们返回如下内容:
{"A"->1, "B" ->7, "C" ->6}
当前算法只是假设我们需要从订阅者恢复的最小消息数(在本例中为 1)重播。而实际上,只有在这种情况下,我们才需要担心数量大于 7 的消息。
我可以在发布者端定期保存每个订阅者发送的最高消息数的映射。
所以我可以每 5 分钟保存一次地图的状态。如果重新启动后我看到所有订阅者都收到了高于上次保存值的消息号,我可以从最大恢复的序列号(在本例中为 7)重播。这减少了要重播的消息数量。
我认为这个问题可能有一个标准算法,但是网络搜索并没有产生任何有用的东西。如果有人可以向我指出非常有用的相关算法。
请假设:
- 保存发送给每个订阅者的每个消息号不是一种选择。
- 订阅者可以很好地处理重复消息,因此我们希望在重播超过所需消息方面犯错。
【问题讨论】:
-
也许我在这里误解了一些东西,但是如果每个订阅者都有一个单独的频道来接收消息,那么每个频道不应该单独处理吗?
-
为什么不保留每个订阅者最后发送的消息号,因为在您的情况下订阅者似乎是独立的(他们都可以接收完全不同的消息)?还是我错过了什么?
-
Paul - 是的,订阅者是独立的。假设订阅者 A 看到了 5 号消息,所以我们只需要从发布者的当前状态中判断它是否应该发送高于 5 的任何内容,然后只发送这些消息。这里的问题是发布者在缓存中没有这些消息(它必须从另一个外部 FIX 服务器请求它们)。所以这里的想法是尽量减少我们请求重播的次数。很抱歉没有早点澄清这一点。
-
为什么不保留每个订阅者最后发送的消息号,因为在您的情况下订阅者似乎是独立的 ----- 是的,它们是独立的,实际上我正在尝试保留最后发送的消息对于每个订阅者,问题是在给定此状态的情况下确定从哪里开始重播。基本上假设发布者突然重新启动,因此它保存在持久存储中的最后发送消息的值可能不是最新的。为每条消息发送更新此状态的成本很高。
-
好的,那么您有两种情况: 1. 订阅者是完全独立的,在这种情况下,您不能最小化请求,因为您需要请求所有不同的消息; 2.订阅者不是完全独立的,在这种情况下,有时一条消息需要重新发送给多个订阅者。在第 2 种情况下,您需要找到要重新发送给订阅者的常见消息并保留它们,直到它们不再有用为止。
标签: algorithm disaster-recovery