当前位置: 代码网 > it编程>数据库>Redis > Redis如何高效删除大key

Redis如何高效删除大key

2024年05月15日 Redis 我要评论
大key的删除问题大key(bigkey)是指 key 的 value 是个庞然大物,例如 hashes, sorted sets, lists, sets,日积月累之后,会变得非常大,可能几十上百m

大key的删除问题

大key(bigkey)是指 key 的 value 是个庞然大物,例如 hashes, sorted sets, lists, sets,日积月累之后,会变得非常大,可能几十上百mb,甚至到gb。

如果对这类大key直接使用 del 命令进行删除,会导致长时间阻塞,甚至崩溃。

因为 del 命令在删除集合类型数据时,时间复杂度为 o(m),m 是集合中元素的个数。

redis 是单线程的,单个命令执行时间过长就会阻塞其他命令,容易引起雪崩。

解决方案

不可靠方案:

  • 空闲时间删除,如凌晨3-4点删除

可靠方案:

  • 渐进式删除
  • unlink (4.0版本以后)

1.渐进式删除

思路:

分批删除,通过 scan 命令遍历大key,每次取得少部分元素,对其删除,然后再获取和删除下一批元素。

示例:

  • 删除大 hashes

步骤:

(1)key改名,相当于逻辑上把这个key删除了,任何redis命令都访问不到这个key了

(2)小步多批次的删除

伪代码:

# key改名
newkey = "gc:hashes:" + redis.incr( "gc:index" )
redis.rename("my.hash.key", newkey)
 
# 每次取出100个元素删除
cursor = 0
loop
  cursor, hash_keys = redis.hscan(newkey, cursor, "count", 100)
  if hash_keys count > 0
    redis.hdel(newkey, hash_keys)
  end
  if cursor == 0
    break
  end
end
  • 删除大 lists

伪代码:

# key改名
newkey = "gc:hashes:" + redis.incr("gc:index")
redis.rename("my.list.key", newkey)
 
# 删除
while redis.llen(newkey) > 0
  redis.ltrim(newkey, 0, -99)
end
  • 删除大 sets

伪代码:

# key改名
newkey = "gc:hashes:" + redis.incr("gc:index")
redis.rename("my.set.key", newkey)
 
# 每次删除100个成员
cursor = 0
loop
  cursor, members = redis.sscan(newkey, cursor, "count", 100)
  if size of members > 0
    redis.srem(newkey, members)
  end
  if cursor == 0
    break
  end
end
  • 删除大 sorted sets

伪代码:

# key改名
newkey = "gc:hashes:" + redis.incr("gc:index")
redis.rename("my.zset.key", newkey)
 
# 删除
while redis.zcard(newkey) > 0
  redis.zremrangebyrank(newkey, 0, 99)
end

2.unlink

redis 4.0 推出了一个重要命令 unlink,用来拯救 del 删大key的困境。

unlink 工作思路:

(1)在所有命名空间中把 key 删掉,立即返回,不阻塞。

(2)后台线程执行真正的释放空间的操作。

unlink 基本可以替代 del,但个别场景还是需要 del 的,例如在空间占用积累速度特别快的时候就不适合使用unlink,因为 unlink 不是立即释放空间。

总结

使用 del 删除大key可能会造成长时间阻塞,甚至崩溃。

可以使用渐进式删除,对 hashes, sorted sets, lists, sets 分别处理,思路相同,先逻辑删除,对key改名,使客户端无法使用原key,然后使用批量小步删除。

4.0版本以后可以使用 unlink 命令,后台线程释放空间。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com