极简工具箱

免费在线工具 · 本地计算 · 无需上传

Redis 键怎么设计:命名、大 key 与过期策略

`KEYS *` 一执行,Redis 卡住三秒;一个 500MB 的 Hash 删除时把主线程堵死。键设计不当,问题往往在流量上来之后才爆发。

广告位(百度联盟)

一、命名用冒号分层

user:1001:profile
user:1001:follows
order:20261103:count
cache:article:8821
lock:order:1001

好处:一看就知道业务域、对象、ID;SCAN 时能按前缀过滤;监控工具能按前缀聚合。避免 u1001p 这种无分隔的写法,也别用中文和空格(转义麻烦)。

统一在团队文档里约定前缀,比每个人自由发挥强得多。

二、控制单个 key 的大小

经验阈值:

类型建议上限
String10KB(超过考虑拆或换存储)
Hash / List / Set / ZSet元素数 5000 以内
整体单 key 不超过 10MB

超过就是「大 key」。危害有三:

拆分方式:按时间分桶(order:202611:count)、按字段拆 Hash、分页存 List。

三、一定要设 TTL

缓存类 key 不设过期,内存只会一直涨,最后触发淘汰策略把有用的数据挤掉。规范:

SET cache:article:8821 "{...}" EX 3600

四、不要用 KEYS *

KEYS 会遍历所有键并阻塞主线程,生产环境等同于一次小型故障。用 SCAN 游标迭代:

SCAN 0 MATCH "user:1001:*" COUNT 100

SCAN 是渐进式的,不保证一次返回全部,也不保证元素不重复,要循环直到游标回到 0。删除大量 key 时配合 UNLINK 或 SCAN + 批量 UNLINK。

Redis 4.0+ 还支持 UNLINK(后台线程释放内存),比 DEL 温和。

五、热 key 与缓存穿透

热 key:某个 key 的 QPS 远高于其他(如首页配置、爆款商品)。单节点可能被打满,解决方式是本地缓存 + 多副本(key 加随机后缀分散到多个节点,读时随机选一个)。

缓存穿透:查询不存在的数据,每次都打到数据库。解决:

缓存击穿:热点 key 过期的瞬间大量请求同时回源。解决:互斥锁重建,或逻辑过期(值里带过期时间,异步刷新)。

缓存雪崩:大批 key 同时失效。解决:TTL 加随机、多级缓存、Redis 集群高可用。

六、内存与淘汰策略

CONFIG GET maxmemory
CONFIG GET maxmemory-policy

常见策略:

策略行为
noeviction不淘汰,写满报错(默认,危险)
allkeys-lru所有 key 里淘汰最久未用的(纯缓存推荐)
volatile-lru只在设了 TTL 的 key 里淘汰
allkeys-lfu按访问频率淘汰(更抗突发)

纯缓存场景用 allkeys-lru;如果 Redis 同时存了不能丢的数据(如队列),用 volatile-* 并确保持久化配置正确。

七、排查命令

redis-cli --bigkeys                 # 找大 key(抽样)
redis-cli --hotkeys                 # 找热 key(需 LFU 策略)
redis-cli --scan --pattern "user:*" | head
redis-cli info memory               # 内存分布
redis-cli slowlog get 10            # 慢命令

--bigkeys 是抽样扫描,不是精确统计,但足够发现明显问题。slowlog 能抓到耗时超过阈值的命令(slowlog-log-slower-than 默认 10000 微秒)。

小结

键名用冒号分层;单 key 控制在 10MB / 5000 元素内;缓存必须设 TTL 且加随机抖动;禁用 KEYS *,用 SCAN;大 key 用 UNLINK 删;热点与穿透分别用多副本和空值缓存应对。

本文相关工具(本地计算,无需上传)

更多使用教程