1、keys 命令问题
问题描述
-
redis有一亿个 key,使用 keys 命令是否会影响线上服务?
解答
-
keys 命令时间复杂度是 O(n),n 即总的 key 数量,n 如果很大,性能非常低
-
redis 执行命令是单线程执行,一个命令执行太慢会阻塞其它命令,阻塞时间长甚至会让 redis 发生故障切换
改进方案
-
可以使用 scan 命令替换 keys 命令,语法
scan 起始游标 match 匹配规则 count 提示数目
,返回值代表下次的起点-
虽然 scan 命令的时间复杂度仍是 O(n),但它是通过游标分步执行,不会导致长时间阻塞
-
可以用 count 参数提示返回 key 的个数
-
弱状态,客户端仅需维护游标
-
scan 能保证在 rehash 也正常工作
-
缺点是可能会重复遍历 key(缩容时)、应用应自己处理重复 key
-
2、过期 key 的删除策略
记录 key 过期时间
-
每个库中都包含了 expires 过期字典
-
hashtable结构,键为指针,指向真正 key,值为 long 类型的时间戳,毫秒精度
-
-
当设置某个 key 有过期时间时,就会向过期字典中添加此 key 的指针和时间戳
过期 key 删除策略
-
惰性删除
-
在执行读写数据库的命令时,执行命令前会检查 key 是否过期,如果已过期,则删除 key
-
-
定期删除
-
redis 有一个定时任务处理器 serverCron,负责周期性任务处理,默认 100 ms 执行一次(hz 参数控制)包括:① 处理过期 key、② hash 表 rehash、③ 更新统计结果、④ 持久化、⑤ 清理过期客户端
-
对于处理过期 key 会:依次遍历库,在规定时间内运行如下操作
① 从每个库的 expires 过期字典中随机选择 20 个 key 检查,如果过期则删除
② 如果删除达到 5 个,重复 ① 步骤,没有达到,遍历至下一个库
③ 规定时间没有做完,等待下一轮 serverCron 运行
-