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