当前位置:首页 > 问答 > 正文

Redis磁盘空间满了,命令行怎么快速清理才靠谱呢?

综合参考了Redis官方文档、阿里云开发者社区的技术博客以及多位资深运维工程师的经验分享)

当你收到Redis磁盘空间告警或者发现服务因磁盘满而异常时,第一步绝对不能是慌乱地直接执行FLUSHALL命令(这个命令会清空整个Redis的所有数据,相当于数据全丢,是核武器,只能在万不得已或明确可以丢失全部数据时使用),靠谱的清理应该是一个有步骤、有重点的排查和清理过程,以下是如何通过命令行快速且相对安全地操作。

第一步:立即诊断,搞清楚是什么占用了空间

Redis磁盘空间满了,命令行怎么快速清理才靠谱呢?

盲目清理就像生病了乱吃药,必须先诊断,Redis提供了强大的诊断命令。

  1. 连接上Redis实例:使用redis-cli命令连接到你的Redis服务器。
  2. 查看全局信息:执行INFO memory命令,这个命令会返回大量内存相关的信息,你需要重点关注这几行:
    • used_memoryused_memory_human:这是Redis当前使用的总内存字节数和一个人类易读的格式(如MB、GB),这能让你立刻知道大概用了多少。
    • used_memory_rss:这个是操作系统视角下Redis进程占用的总内存量,通常比used_memory大,因为它包含了进程本身的开销等,如果这个值远大于used_memory,可能意味着内存碎片化比较严重。
    • maxmemory:这是Redis配置的最大内存限制,如果设置为0,表示没有限制,这可能是导致磁盘空间被写满的原因之一(因为数据会一直往磁盘上持久化)。
  3. 深入分析具体键的类型和大小:光知道总量不够,要知道是哪些“大块头”占地方,这里有几个关键命令:
    • redis-cli --bigkeys:这是首选的最快命令,它会扫描整个数据库(默认扫描当前DB),并统计出每种数据类型(string, hash, list, set, zset)中最大的那个键,执行后,你能立刻看到比如“最大的string键是XXX,大小是YYY”、“最大的hash键有ZZZ个字段”这样的信息,这能帮你快速定位到嫌疑最大的几个键。
    • redis-cli --memkeys:这个命令需要Redis 4.0及以上版本,它更强大,可以扫描并列出所有键的近似内存占用,并且支持模式匹配和排序,你可以用redis-cli --memkeys -n 0 -s 102400来扫描数据库0,并只显示大于100KB的键(102400字节),这比--bigkeys更全面。
    • DEBUG OBJECT key_name:当你通过上面命令找到某个可疑的大键后,可以用这个命令查看该键的详细内部信息,包括序列化长度(serializedlength),这近似等于该键在内存中占用的字节数。注意:生产环境慎用DEBUG命令,因为它可能会阻塞Redis,最好在业务低峰期对个别键使用。

第二步:根据诊断结果,进行针对性清理

知道了“元凶”之后,就可以开始清理了,清理的核心原则是:清理无用数据,保留核心数据。

Redis磁盘空间满了,命令行怎么快速清理才靠谱呢?

  1. 清理过期但未删除的键:Redis的过期键删除是惰性+定期的,有可能很多键已经过期但还没来得及被删除,它们仍然会占用磁盘空间(如果开启了持久化),你可以尝试手动触发一下主动清理:

    • 执行redis-cli CONFIG SET activedefrag yes开启自动内存碎片整理(如果版本支持),它也有助于清理过程。
    • 更直接的方法是,执行一个SCAN命令遍历所有键,这个遍历过程本身会触发Redis的惰性删除逻辑,可以简单执行一个redis-cli --scan,虽然不返回键,但能促进清理。
  2. 删除特定的大键或模式键:这是最有效的腾空间方法。

    • 删除单个已知的大键:使用DEL key_name命令,比如DEL my_big_hash_key
    • 批量删除符合模式的键这是非常危险的操作,务必先在测试环境练习,并在生产环境谨慎确认模式! 使用如下命令:
      # 先预览一下会删除哪些键,确保不会误删重要数据!
      redis-cli --scan --pattern "cache:temp:*" | head -10
      # 确认无误后,再执行删除,使用管道符一次删除,避免频繁网络往返。
      redis-cli --scan --pattern "cache:temp:*" | xargs redis-cli del

      上面的例子会删除所有以cache:temp:开头的键,这通常用于清理临时缓存数据,常见的模式还有session:*(会话数据)、tmp:*等。

      Redis磁盘空间满了,命令行怎么快速清理才靠谱呢?

  3. 处理大数据类型的优化:如果最大的键是一个包含百万字段的Hash或者一个巨大的List,而这些数据又不能全删,可以考虑裁剪

    • 对于List,可以使用LTRIM key start stop命令,只保留最后一部分元素,例如LTRIM my_big_list 0 999,只保留前1000个元素。
    • 对于Sorted Set,可以使用ZREMRANGEBYRANK key start stop移除排名范围外的成员。
    • 对于Set,可以使用SPOP key count随机弹出并删除指定数量的成员(如果不关心顺序)。

第三步:治本之策,防止问题复发

临时清理只是救火,更重要的是防火。

  1. 设置合理的最大内存限制:在Redis配置文件redis.conf中,必须设置maxmemory参数,例如maxmemory 4gb,这样当内存达到上限时,Redis会根据maxmemory-policy(内存淘汰策略)来删除旧数据,防止内存和磁盘无限增长。
  2. 配置合适的内存淘汰策略:通过maxmemory-policy配置,对于缓存场景,常用allkeys-lru(从所有键中淘汰最近最少使用的)或volatile-lru(只从设置了过期时间的键中淘汰最近最少使用的),选择合适的策略能让你在达到内存上限时自动清理。
  3. 为键设置过期时间:在写入缓存数据时,务必使用SET key value EX seconds或后续用EXPIRE key seconds命令为其设置合理的过期时间(TTL),让数据有生命周期的概念,自动失效。
  4. 定期检查与监控:将Redis的内存使用量、键数量等指标纳入监控系统,设置告警阈值(如80%),做到提前预警,而不是等满了再处理。

总结一下命令行快速清理流程:

  1. 连上去redis-cli
  2. 看概况INFO memory
  3. 找元凶redis-cli --bigkeysredis-cli --memkeys
  4. 针对性删除
    • 删过期键:扫描触发或重启(最后手段)。
    • 删无用大键:DEL key_name
    • 批量删模式键:redis-cli --scan --pattern "pattern" | xargs redis-cli del极度小心!)。
    • 裁剪大键:使用LTRIM等命令。
  5. 长远配置:设置maxmemorymaxmemory-policy,并为键添加TTL。

任何时候在执行删除命令前,尤其是批量删除,一定要先预览(用--scan不带xargs),确认输出的键确实是你可以接受的损失,数据无价,操作需谨慎。