根据散列键名批量删除redis散列值
Posted
技术标签:
【中文标题】根据散列键名批量删除redis散列值【英文标题】:delete redis hash values in bulk based on the hash key name 【发布时间】:2013-06-17 23:16:15 【问题描述】:与此类似,但需要哈希而不是普通键的解决方案:How to atomically delete keys matching a pattern using Redis
我有一堆带有前缀的哈希,例如:“前缀:”
在每个散列下是一堆键,例如:“cc_XX”,其中“XX”是一个 2 个字母的代码。
我需要一些方法来遍历我所有的 redis 哈希,并以某种方式删除每个 cc_XX 子键,并且正在寻找一种 cli/lua 方法来执行此操作(两者都不是很好)。
任何建议将不胜感激。
【问题讨论】:
【参考方案1】:以下EVAL script 应该做你想做的事:
local keys = redis.call('KEYS',KEYS[1])
for i,k in ipairs(keys) do
local res = redis.call('HKEYS',k)
for j,v in ipairs(res) do
if string.find(v,ARGV[1]) then
redis.call('HDEL',k,v)
end
end
end
您需要通过提供以下参数来调用它:
EVAL <script> 1 prefix:* cc_..
请注意,它会阻塞 Redis 事件循环,直到脚本完成,因此如果您有大量键,它可以冻结 Redis 一段时间。原子性是有代价的。
更新:
如果你不需要原子性,那么下面的脚本将避免阻塞 Redis 太长时间(但请注意,如果你有大量的全局键或者你的哈希对象之一很大,它仍然会阻塞:没有办法避免这种情况)。
./redis-cli keys 'prefix:*' | awk '
BEGIN
script = "local res = redis.call('\''HKEYS'\'',KEYS[1]); \
for j,v in ipairs(res) do \
if string.find(v,ARGV[1]) then \
redis.call('\''HDEL'\'',KEYS[1],v); \
end \
end"
printf "EVAL \"%s\" 1 %s cc_..\n", script, $1
' | ./redis-cli
(用 bash 测试)
【讨论】:
我应该澄清一下,我不需要原子操作。有没有简单的方法让它在运行时允许其他呼叫通过? 只是为了我的理解,脚本正在执行以下操作? 对不起,我在手机上写东西...我会试一试,并尝试了解您如何/为什么以这种方式编写脚本。我可能会向您发送另一个问题。 :) 我终于试了一下,似乎它删除了所有包含“cc_”的东西,而不是所有以“cc_”开头的东西。例如,我试图删除所有这些“cc_XX”键,同时保留所有新的键,例如“metadata_cc_XX”和“metadata_cc_XX_ts”,但在运行“cc_..”时它们都被删除了。任何建议将不胜感激。 啊哈,更多的正则表达式风格,我以为它只是带了一个通配符。谢谢!【参考方案2】:我们在 Redis 中存储哈希的方式是,我们通过哈希中的对象类型为哈希元素 ID 键添加后缀。有时在数据模型中,我们更新一个对象,我们需要在部署时删除给定对象类型的所有哈希元素。我们希望在不删除整个哈希的情况下完成此操作。
例如:
127.0.0.1:6379> keys client*
1) "client"
127.0.0.1:6379> type client
hash
127.0.0.1:6379> hkeys client
1) "123-obj1"
2) "123-obj2"
3) "123-obj3"
4) "123-obj4"
5) "123-obj5"
6) "456-obj1"
7) "456-obj2"
8) "456-obj3"
9) "456-obj4"
10) "456-obj5"
如果我们在应用程序中向 obj5 添加一个新字段并设置为默认值,我们将需要运行“HDEL client *-obj5”的等效项。但是,这在 redis-cli 中不起作用。
我通过 BASH 找到了以下作品:
redis-cli HKEYS 'client' | grep obj5 | awk ' printf "HDEL client %s\n", $1 ' | redis-cli
如果您在您的环境中使用不同的 Redis 数据库,请添加“-n X”开关,相当于 redis-cli 中的“select X”。在这种情况下,选择数据库 4:
redis-cli -n 4 HKEYS 'client' | grep obj5 | awk ' printf "HDEL client %s\n", $1 ' | redis-cli -n 4
【讨论】:
以上是关于根据散列键名批量删除redis散列值的主要内容,如果未能解决你的问题,请参考以下文章