Redis如何高效删除大key

 更新时间:2024年04月03日 15:55:20   作者:3333333_  
这篇文章主要介绍了Redis如何高效删除大key问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

大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 命令,后台线程释放空间。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Redis缓存与数据库一致性的完整指南

    Redis缓存与数据库一致性的完整指南

    某金融平台因缓存数据不一致导致用户余额错乱,损失千万!文中将用银行对账比喻+实战代码,揭秘6大解决方案,让你的数据毫秒级同步,所以本文给大家详细介绍了Redis缓存与数据库一致性的完整指南,需要的朋友可以参考下
    2025-09-09
  • 深度剖析Redis字符串操作指南从入门到实战应用

    深度剖析Redis字符串操作指南从入门到实战应用

    Redis字符串类型二进制安全,支持文本、数字、二进制等数据,涵盖基础操作、数字计算、过期管理及分布式锁等应用,结合优化策略提升系统性能,本文给大家介绍Redis字符串操作指南,感兴趣的朋友一起看看吧
    2025-07-07
  • Redis分布式锁实例分析讲解

    Redis分布式锁实例分析讲解

    分布式锁是控制分布式系统不同进程共同访问共享资源的一种锁的实现。如果不同的系统或同一个系统的不同主机之间共享了某个临界资源,往往需要互斥来防止彼此干扰,以保证一致性
    2022-12-12
  • 深入理解redis删除策略和淘汰策略

    深入理解redis删除策略和淘汰策略

    每隔一段时间就扫描一定数据的设置了过期时间的key,并清除其中已过期的keys,本文主要介绍了深入理解redis删除策略和淘汰策略,感兴趣的可以了解一下
    2024-08-08
  • Redis底层数据结构SkipList的实现

    Redis底层数据结构SkipList的实现

    本文主要介绍了Redis底层数据结构SkipList的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • Redis中的数据一致性问题以及解决方案

    Redis中的数据一致性问题以及解决方案

    这篇文章主要介绍了Redis中的数据一致性问题以及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-05-05
  • Redis配置日志实现过程

    Redis配置日志实现过程

    本文介绍了如何在Redis中配置日志文件, 找到并配置文件,找到logfile项并填入日志路径,建立日志文件夹,并保存配置文件.注意带配置文件启动且指定日志等级. 此外还提供了些注意事项
    2026-05-05
  • Redis Sorted Set 跳表的实现示例

    Redis Sorted Set 跳表的实现示例

    本文详细解析了Redis中SortedSet跳表的实现原理,阐述了跳表的基本概念、结构及其在SortedSet中的应用,同时也指出了跳表在实际使用中的优势和局限,可以更好地运用Redis的SortedSet,优化高并发环境中的数据查询与操作,感兴趣的可以了解一下
    2024-10-10
  • 使用Redis实现实时排行榜功能

    使用Redis实现实时排行榜功能

    排行榜功能是一个很普遍的需求。使用 Redis 中有序集合的特性来实现排行榜是又好又快的选择。接下来通过本文给大家介绍使用Redis实现实时排行榜功能,需要的朋友可以参考下
    2021-07-07
  • Redis集群的实现全过程

    Redis集群的实现全过程

    Redis集群的实现方案主要有客户端分片、代理模式和Cluster模式,其中,Cluster模式是Redis官方推荐的实现方案,它具有高可用性、高性能和自动分片等优点
    2024-12-12

最新评论