如何在Redis集群中删除与模式匹配的键

13

我尝试了这个问题中的方法,但它无法工作,因为我在集群模式下工作,Redis告诉我:

(error) CROSSSLOT 请求中的键没有哈希到同一个插槽


有些人建议使用Eval作为一种选项;但我没有找到一个使用Eval的好例子。有什么线索吗?最好是一些Golang Redis客户端库的例子。 - rajat
3个回答

21

对于这个问题的答案尝试使用单个DEL删除多个键。然而,匹配给定模式的键可能不在同一个槽中,并且如果这些键不属于同一个槽,则Redis Cluster不支持多键命令。这就是为什么会出现错误消息的原因。

为了解决这个问题,您需要逐个DEL这些键:

redis-cli --scan --pattern "foo*" |xargs -L 1 redis-cli del

xargs 命令的 -L 选项指定删除键的数量。您需要将此选项指定为 1

为了删除所有与模式匹配的键,您还需要在群集中的每个主节点上运行上述命令。

注意

  1. 使用此命令,您必须逐个删除这些键,这可能非常缓慢。您需要考虑重新设计数据库,并使用哈希标记使匹配模式的键属于同一槽。这样,您可以在一个 DEL 中删除这些键。

  2. 无论是 SCAN 还是 KEYS 命令效率都不高,特别是生产环境中不应使用 KEYS。您需要考虑为这些键构建索引。


我遇到了(error) CROSSSLOT Keys in request don't hash to the same slot的错误。我正在使用以下命令从集群中删除模式为hi*的键:redis-cli -u redis://localhost:6379 --scan --pattern 'hi*' | xargs redis-cli -u redis://localhost:6379 DEL - roottraveller
1
@roottraveller,正如我在答案中提到的那样,您需要为xargs命令指定-L 1参数。 - for_stack

3

在借鉴 for_stack的回答 的基础上,如果你使用redis 4或更高版本,可以使用redis-cli --pipe加快批量删除的速度,并使用UNLINK代替DEL以减少性能影响。

redis-cli --scan --pattern "foo*" | xargs -L 1 echo UNLINK | redis-cli --pipe

输出结果将类似于这样:
All data transferred. Waiting for the last reply...
Last reply received from server.
errors: 0, replies: 107003

您仍需要在集群中的每个主节点上运行此操作。如果您有大量节点,则可能可以通过解析CLUSTER NODES的输出来进一步自动化该过程。


1

redis-cli 提供了一个 -c 选项来跟随 MOVED 重定向。然而,应该逐个删除,因为您无法保证两个键位于同一节点。

redis-cli -h myredis.internal --scan --pattern 'mycachekey::*' | \
  xargs -L 1 -d'\n' redis-cli -h myredis.internal -c del

第一部分提供了一个键列表,--scan 防止 Redis 锁定。 xargs -L 1 每次只运行一个条目的命令。 -d'\n' 禁用引号处理,因此您可以将带引号的字符串(如 "SimpleKey[hello world]")传递给命令,否则空格将使其具有两个键。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接