redis清理key方法总结
02维护-redis清理key方法总结
redis长期使用,不规范使用,就会导致内存越来越大,而内存中存在大量的无用的key,那么如何清理key? 批量清理key?
Redis DEL key命令用于删除单个Key。是立刻执行的。如果是大key,unlink key_name 该命令能够以非阻塞的方式缓慢逐步的清理。可以安全的删除大Key甚至特大Key。
如需批量删除Key,可以组合使用Linux的cat、xargs命令和Redis的DEL命令。如需模糊删除具有相同前缀或后缀的Key,推荐使用Redis的SCAN和DEL命令。
一、清理过期key
Redis版存在以下三种自动清除过期Key的默认策略:
主动过期(定期清除):系统后台会周期性地检测,若发现已过期的Key,会将其清除。
被动过期(惰性清除):当用户访问某个Key时,若该Key已过期,系统会将其清除。
强制逐出:当Redis内存达到Maxmemory参数定义的上限时,将会引发操作阻塞或重要Key被逐出,甚至引发内存溢出(Out Of Memory),这里跟淘汰策略有关。建议设置:lru或者lfu
volatile-lru(默认):从已设置过期时间(Expire)的Key中,删除最近最少使用的Key(LRU算法),且不会考虑Key是否已经过期。
volatile-lfu:从已设置过期时间(Expire)的Key中,删除最不常用的Key(LFU算法)。且不会考虑Key是否已经过期。
volatile-random:从已设置过期时间(Expire)的Key中,随机删除一些Key。且不会考虑Key是否已经过期。
volatile-ttl:从已设置过期时间(Expire)的Key中,根据存活时间(TTL)从小到大排序进行删除。且不会考虑Key是否已经过期。
allkeys-lru:从所有Key中,删除最近最少使用的Key(LRU算法)。且不会考虑Key是否已经过期。
allkeys-lfu:从所有Key中,删除最不常用的Key(LFU算法)。且不会考虑Key是否已经过期。
allkeys-random:从所有Key中,随机删除一些Key。且不会考虑Key是否已经过期。
noeviction:不删除任何Key,当内存达到上限时,将无法写入新数据,数据库会返回错误信息。
(1)如果是云数据库,一般控制台都提供了功能。去帮助清理过期key。 内部实现其实就是scan遍历key即可,被动过期策略就会清除掉key。
(2)调高hz参数(Redis后台执行清除过期Key的频率).
重要,该值越大,CPU资源消耗越多,请谨慎操作。
建议以10为阶梯,逐步增加该参数的值,并实时观察实例CPU的使用率,避免一次性调整过大造成CPU负载过高。
二、清理指定key(非设置过期key)
(1)删除指定的多个Key
执行命令前,您需要把待删除的Key列表写入至文件。
通过cat命令从指定文件中读取每一行作为Redis的Key,然后使用 redis-cli 连接到 Redis 服务器,并使用DEL命令删除这些Key。命令语法如下:
cat file | xargs redis-cli -h host -a password DEL
(2)模糊匹配key批量删除
2种方式,方式1:使用scan+del方式。 这种方式也是阻塞redis,但每次删除的数量限制,影响较小。推荐
方式2:keys+del方式。注意这种方式是阻塞redis的,执行过程中无法响应客户端请求。性能影响较大,删除的key大或者key太多,可能导致redis崩溃。
方式1:通过循环逐步遍历并删除符合条件的Key。示例代码如下所示。
import redis
import sys
def main(argv):
if len(argv) < 4:
print("Usage: python scan_and_del.py host port password match")
sys.exit(-1)
host = argv[1]
port = argv[2]
password = argv[3]
match = argv[4]
print("host: %s, port: %s, password: %s, match: %s\n" % (host, port, password, match))
redis_cli = redis.StrictRedis(host=host, port=port, password=password)
cursor = 0
rnd = 1
while rnd == 1 or cursor != 0:
result = redis_cli.scan(cursor=cursor, match=match, count=1000)
ret_cursor = result[0]
ret_keys = result[1]
num_keys = len(ret_keys)
print("del %d keys in round %d, cursor: %d" % (num_keys, rnd, ret_cursor))
if 0 != num_keys:
ret_del = redis_cli.delete(*ret_keys)
print("ret_del: %d, ret_keys: %s" % (ret_del, ret_keys))
cursor = ret_cursor
rnd += 1
print("")
if __name__ == '__main__':
main(sys.argv)
执行:
python scan_and_del.py host port password "key"
参数说明:
key:某个数据库中符合指定要求的Key,例如"test*"标识以test为前缀的Key,如test1、test2、test3等。
关于通配符匹配的更多说明:
w?rld:匹配以w开头,以rl结尾,且长度为5个字符的字符串,例如world,warld和wxrld等。
w*rld:匹配以w开头,以rl结尾的任意字符串,例如wrld和woooorld。
w[ae]rld:匹配warld和werld,但是不匹配world等。
w[^e]rld:匹配world和warld等,但是不匹配werld。
w[a-b]rld:匹配warld和wbrld。
方式2:
通过KEYS命令,使用通配符模糊匹配所有符合条件的Key,再通过DEL命令删除这些Key。
redis-cli -h host -a password KEYS "key" | xargs redis-cli -h host -a password DEL
验证指定Key是否成功删除
redis-cli -h host -a password KEYS "key"
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?