Redis 大Key删除策略
问题背景
一个 key 的 value 特别大,由于 Redis 是单线程模型,当对该 key 进行查询或者删除时,会造成 Redis 阻塞,阻塞期间所有的请求都有可能超时
如何解决
怎么发现大key
1. String 类型
可以使用命令 --bigkeys
该命令对于 String 类型是统计的 value 的字节数,而对于 list 等类型是统计的元素的个数
我们使用
--bigkeys
可以直观的判断出 String 的大key
--bigkeys
是采用 scan 延迟计算的方式扫描所有 key,因此执行过程中不会阻塞 redis
2. 其他类型
Redis 4.0 之后,采用 memory 命令查询 key 的大小 (memory 命令统计的是一个预估值)
如何删除大key
低峰期删除
这种方法无法避免阻塞期间的请求,一般适用执行期间 qps 非常小
分批删除
对于 list
、set
、 zset
等数据类型可以采用分配删除,取一批数据然后删除
异步删除
redis 4.0 后,官方对支持了 Lazy Free 功能,专门用于删除大key
-
主动删除
采用
UNLINK keyName
UNLINK 是 DEL 的异步版本,当使用 UNLINK 时,redis 会首先检查集合元素的个数,如果小于64,直接同步删除,如果大于64个的时候,会先将 key 删除,真正的 value 会交给异步线程来操作
-
被动删除
被动删除指当一个key过期或者被淘汰,redis主动去删除。在4.0版本之前,自动删除也是需要阻塞线程的。
在4.0 之后,可以选择被动删除策略,可以手动选择以 Lazy Free 的方法进行删除
lazyfree-lazy-expire on # 过期惰性删除 replica-lazy-flush on # slave 异步 flush 数据 lazyfree-lazy-eviction on # 超过最大内存惰性删除 lazyfree-lazy-server-del on # 服务端被动惰性删除