如何以安全的方式修剪redis流

如何以安全的方式修剪redis流,redis,Redis,Redis Xtrim将保留大量记录并删除旧记录 假设我有100张唱片,我想保留最新的10张。(假设java/ScalaAPI) 但是,新记录在执行xlen和xtrim之间到达。例如,现在有105条记录,它将保持95-105,但我想保持从90开始。因此,它也修剪90-95,这是坏的 有什么想法吗?选项1: 如果您始终只想保留10个最新版本,请使用: XADD mystream MAXLEN 10 * field value ... 通过将修剪移动到加法,可以将其始终保持在10。您可以忽略要修剪

Redis Xtrim将保留大量记录并删除旧记录

假设我有100张唱片,我想保留最新的10张。(假设java/ScalaAPI)

但是,新记录在执行
xlen
xtrim
之间到达。例如,现在有105条记录,它将保持95-105,但我想保持从90开始。因此,它也修剪90-95,这是坏的

有什么想法吗?

选项1: 如果您始终只想保留10个最新版本,请使用:

XADD mystream MAXLEN 10 * field value ...
通过将修剪移动到加法,可以将其始终保持在10。您可以忽略要修剪的单独逻辑

在绝地武士中

xadd(String key, StreamEntryID id, Map<String,String> hash, long maxLen, boolean approximateLength)
在这里,如果流已被修改,事务将失败,
EXEC
返回null,然后重试

选项3:

使用调整您的
XTRIM
目标编号。有了它,您可以执行
XLEN
,执行您的逻辑来决定您想要的修剪,然后执行
XTRIM
,所有Redis服务器端都是原子化的,因此您的流不会在这两者之间发生变化

这里有一些绝地武士

更新:

类似下面这样的Lua脚本应该可以做到这一点:原子地计算myStreams条目的当前数量,然后相应地调用XTRIM

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 90
让我们看看Lua脚本:

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

我在

上发布了一个单独问题的更多细节,我想知道是否有可能从最旧的记录删减到最新的记录?例如,修剪流中最早的10条记录。第一种方法将覆盖一些超出我们预期的记录,第二种方法不合理,如果数据连续涌入流,我们希望确保修剪成功,如果失败,我们不能等待。第三个,adjust,似乎只在稳定的数据输入吞吐量下表现良好。这是一个很好的答案。然而,经过我的研究,我想要的方法实际上还没有在Redis中实现。
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 90
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