如何从 Redis 流中删除或移除给定数量的条目? [英] How to delete or remove a given number of entries from a Redis stream?

查看:102
本文介绍了如何从 Redis 流中删除或移除给定数量的条目?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Redis XTRIM 命令允许您声明要保留的条目数,但是如果我想说明要删除多少个条目呢?

Redis XTRIM command allows you to state how many entries to keep, but what if I want to state how many entries to delete instead?

例如,如果我有一个不断接收新条目的流,我想删除最旧的 100 个条目,我不能简单地执行 XLEN myStream 然后调用 XTRIM myStream MAXLEN <xlen result - 100>,因为在这两个命令之间添加了新条目,它将删除100多个条目.

For example, if I have a stream that is constantly receiving new entries, I want to delete the oldest 100 entries, I cannot simply do XLEN myStream and then call XTRIM myStream MAXLEN <xlen result - 100>, as new entries are added between the two commands, and it will delete more than 100 entries.

如何实现这一目标?

推荐答案

你需要使用 Lua 脚本,以原子方式评估 myStreams 条目的当前数量,然后相应地调用 XTRIM.

You need to use a Lua Script, to atomically evaluate the current number of myStreams entries and then call XTRIM accordingly.

EVAL "local streamLen = redis.call('XLEN', KEYS[1]) \n if streamLen >= tonumber(ARGV[1]) then \n return redis.call('XTRIM', KEYS[1], 'MAXLEN', streamLen - tonumber(ARGV[1])) \n else return redis.error_reply(KEYS[1]..' has less than '..ARGV[1]..' items') end" 1 myStream 100

我们来看看 Lua 脚本:

Let's take a look at the Lua script:

local streamLen = redis.call('XLEN', KEYS[1])
if streamLen >= tonumber(ARGV[1]) then 
    return redis.call('XTRIM', KEYS[1], 'MAXLEN', streamLen - tonumber(ARGV[1]))
else
    return redis.error_reply(KEYS[1]..' has less than '..ARGV[1]..' items')
end

这将流的长度放入streamLen,然后通过计算差异并将其传递给XTRIM 来删除所需数量的条目.由于 Lua 脚本以原子方式运行,因此 XLENXTRIM 命令之间不会添加新条目.

This gets the length of the stream into streamLen, and then deletes the desired number of entries by calculating the difference and passing it to XTRIM. As Lua scripts run atomically, there will be no new entries added between the XLEN and the XTRIM commands.

Lua 脚本以及 EVAL 命令返回已删除条目的数量,并且它应该与作为参数传递的数量匹配,除非流中的条目较少,在这种情况下它返回(错误)myStream 的项目少于 100 个.

The Lua script, and therefore the EVAL command, returns the number of deleted entries, and it should match the number passed as argument unless there are fewer entries in the stream, in which case it returns (error) myStream has less than 100 items.

如果您想删除最多 n 个条目,如果流中的条目较少,则删除更少,请对 Lua 脚本进行简单更改:

If you want to remove up to n entries, removing less if there are fewer entries in the stream, make a simple change to the Lua script:

local streamLen = redis.call('XLEN', KEYS[1])
if streamLen >= tonumber(ARGV[1]) then 
    return redis.call('XTRIM', KEYS[1], 'MAXLEN', streamLen - tonumber(ARGV[1]))
else
    return redis.call('XTRIM', KEYS[1], 'MAXLEN', tonumber(ARGV[1]))
end

两个 Lua 脚本的时间复杂度都是 O(N),其中 N 是被驱逐条目的数量,因为 XLEN 是 O(1) 而 XTRIM 是 O(N).

The time complexity of both Lua scripts is O(N), with N being the number of evicted entries, because XLEN is O(1) and XTRIM is O(N).

这篇关于如何从 Redis 流中删除或移除给定数量的条目?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆