最初,我们使用Google Pub / Sub进行免疫的流程如下:


应用程序接受消息
检查它在idempotencyStore中不存在
3.1如果不存在-将其放入幂等存储(键是唯一标头的值,值是当前时间戳记)
3.2如果存在-请忽略此消息
处理完成后-发送确认
在确认成功的回调中-从元数据存储中删除此消息


第5点是错误的,因为从理论上讲,即使消息已处理,我们也可以得到重复的消息。此外,我们发现有时即使调用成功的回调也可能无法删除消息(Message is received from Google Pub/Sub subscription again and again after acknowledge[Heisenbug]),所以我们决定在处理消息后更新值,并用“ FiNISHED”字符串替换时间戳记

但是迟早我们会遇到这个桌子人满为患的情况。因此,我们必须清理MetaDataStore中的消息。我们可以删除已处理的消息,这些消息已处理了1天以上。

https://stackoverflow.com/a/51845202/2674303的注释中所述,我可以在metadataStore表中添加其他列,在其中可以标记是否处理了消息。这根本不是问题。但是,如何在清洁器中使用此标志? MetadataStore只有键和值

最佳答案

在确认成功的回调中-从元数据存储中删除此消息


我完全看不出这一步的原因。

由于您说要在value中存储一个时间戳,这意味着您可以不时分析此表,以删除绝对旧的条目。

在我的某些项目中,我们每天都有数据库工作来存档表,以提高主流程性能。是的,只是因为我们不再需要旧数据了。因此,我们肯定会检查原始数据中的一些时间戳,以确定是否应将其记入存档。我不会在处理后立即删除数据,只是因为有机会从外部系统重新传送数据。

另一方面,为了获得更好的性能,我会在该元数据表中添加带有timestamp类型的额外索引列,并在每次更新或插入时通过触发器填充值。好吧,MetadataStore只需从MetadataStoreSelector插入一个条目:

return this.metadataStore.putIfAbsent(key, value) == null;


因此,您需要一个on_insert触发器来填充该日期列。这样,您将在一天结束时知道是否需要删除条目。

09-26 05:48