1

我有两个微服务,我需要在它们之间实现可靠的通知。我考虑过使用 redis 流 - serviceA 将使用标识符 X 向 serviceB 发送请求。一旦 serviceB 完成 serviceA 要求的工作,它将创建/添加到流(流特定于 X)一个新项目让它知道它已经完成了。

ServiceA 可以发送多个请求,每个请求可能有不同的标识符。所以它会阻止不同流中的新元素。

我的问题是如何根据年龄删除不再需要的流。例如,我想删除一天前创建的流。这可能吗?

如果不是,我很想听听您关于如何在 redis 中不使用不需要的流的任何想法。

谢谢

4

1 回答 1

1

没有直接的方法可以根据 TTL/年龄删除旧条目。您可以结合XTRIM/XDEL使用其他命令来修剪流。

让我们看看我们如何使用XTRIM

XTRIM 流 MAXLEN ~ SIZE

XTRIM 将流修剪为给定数量的项目,如果需要,驱逐较旧的项目(具有较低 ID 的项目)。

您每天或根据您的删除策略定期生成流大小,并使用XLEN命令将其存储在某处

运行将调用 XTRIM 的定期作业

XTRIM x-stream MAXLEN ~ (NEW_SIZE - PREVIOUS_SIZE)

例如,昨天流大小是 500 现在是 600,那么我们需要删除 500 个条目以便我们可以运行

XTRIM x-stream MAXLEN ~ 100

您可以使用不同的策略进行删除,例如每天、每周、每周两次等。


XDEL 流 ID [ID...]

从流中删除指定的条目,并返回删除的条目数,如果某些 ID 不存在,这可能与传递给命令的 ID 数不同。

因此,您可以做的是,只要服务 B 使用事件,服务本身就可以删除流条目,因为服务 B 知道流 ID,但是一旦您开始使用消费者组,这将不起作用。所以我会说使用 Redis set 或 Redis map 来跟踪确认流 id 并运行定期扫描作业来清理流。

例如

服务 A 向服务 B 发送一个 ID1 的流项目 服务 B 在消费地图 ack_stream = { ID1: true } 中的项目后确认流项目,您可以跟踪其他数据,例如在消费者组的情况下计数。

扫描作业将定期运行,例如每天凌晨 1 点,它读取 ack_stream 的所有元素并过滤掉所有需要删除的项目。现在您可以使用一组流 id 批量调用XDEL命令。

于 2020-08-05T10:57:41.863 回答