分析您的需求
您正在将事件写入队列。事件有一个唯一的键 K。
在编写时,当前事件可能会取代具有相同键 K 的较旧的、已编写的事件。
您想用键 K 更新旧的、已编写的事件,以告诉裁缝(稍后出现)存在较新的版本。
我认为这是一个非常普遍的要求,一开始看起来很有吸引力,但是(正如我所经历的)它是有缺陷的。原因如下:
假设您正在处理大量事件(例如每秒 100 次)会很有帮助。Chronicle Queue 在适度的硬件上非常有能力。现在我还假设您只是写入队列,您不会在其他任何地方记录有关您的数据的任何内容。
关键点是上面的第 2 点:您正在编写一个事件,并且您意识到您需要更新一个较旧的事件。你需要做什么?您需要扫描整个队列,可能会返回很长时间/很多事件来搜索较旧的事件。只有这样您才能更新它并完成新事件。这不会缩放。
潜在的解决方案:
- 泰勒需要知道一切。
- 基于索引的版本映射。
裁缝需要知道的一切:
我假设您的 Tailer 对数据执行了一些操作 A。您让您的 tailer 运行所有事件并仅在它确定它具有带有 K 的事件的最新版本后才执行 A。 评估:tailer 需要对每个事件的队列进行完整扫描,或者它需要构建一些数据每个事件键 K 的结构/映射。
基于索引的版本图
您的 appender 在写入事件时从 Chronicle Queue 获取索引。在基于内存或文件的地图(例如 Chronicle Map、MapDB...)中,将键 K 与事件的最新索引一起存储。如果密钥已经在地图中,它只是更新它。现在,tailer 不再按顺序处理队列,而是一个组件从映射中获取所有键,查找索引,读取事件并执行 A。然后它继续处理下一个键。
需要考虑的事情
在特定时间范围内,tailer 将处理多少个事件?这将确定地图大小:地图大小:每个时间帧的事件数 *(键长度 + 64 位索引号)
也许连续操作更好:使操作具有幂等性和可重复性:可以根据需要多次运行,旧版本永远不会更新事件的新版本。
恕我直言,Chronicle Queue 的索引是一个非常好的工具,它几乎是免费的 :)