Redis数据类型
Redis数据文件类型
Redis大key问题
如果一个key对应的value超过1M,或者对于于hash、list、set、zset等集合类型,元素个数超过5000,那么这个key就被称为大key。
发现大key
- SCAN + MEMORY USAGE 命令
- 例如,执行 SCAN 0 MATCH user:* COUNT 100,其中 MATCH user:* 表示只匹配以 user: 开头的键,COUNT 100 表示每次返回最多 100 个键。然后,对于返回的每个键,执行 MEMORY USAGE {key} 命令,就可以得到该键的内存占用字节数。
- 使用 Redis - RDB - Tools 工具
热点key
cpu过载:大量请求集中到一台机器上,导致其他服务不可用 请求阻塞:大量请求热点key,其他key青丘北阻塞 缓存雪崩: 缓存穿透、缓存击穿
热点 Key 的排查方法
- 通过内置统计信息(INFO keyspace)
- 代码层面记录key访问次数
Redis 大 Key 和热点 Key 的优化策略
大 Key 的优化策略
- 分拆大 Key:将大 Key 拆分成多个小 Key,例如将一个大的字符串拆分成多个小的字符串。例:一个key存储了商品的全部信息,可以拆分成多个key,每个key存储商品的一部分信息。
- 压缩数据:使用压缩算法对数据进行压缩,例如使用 GZIP 压缩算法。
- 使用数据结构:使用 Redis 的数据结构,例如使用 Hash 结构来存储多个字段,而不是使用字符串来存储多个字段。
- 渐进式删除 / 更新:如果大 Key 需要删除或更新,可以采用渐进式删除或更新,例如使用 Redis 的 SCAN 命令来遍历大 Key 的所有元素,然后逐个删除或更新。
- 定期清理:设定合理的过期时间对于自动清除不再需要的大 Key
热点 Key 的优化策略
- 使用 Redis 的缓存淘汰策略:例如使用 LRU(最近最少使用)策略,将最近最少使用的 Key 从缓存中淘汰掉。
- 使用 Redis 的分布式锁:例如使用 Redis 的 SETNX 命令来实现分布式锁,保证同一时间只有一个线程可以访问热点 Key。
- 使用 Redis 的分片:例如使用 Redis 的 Cluster 模式,将热点 Key 分布到不同的节点上,避免单个节点过载。
- 流量整型:使用限流、熔断等手段
- 使用缓存预热:例如在应用启动时,预先加载热点 Key 到缓存中,避免在应用启动时出现缓存冷启动的问题。
解决redis的大key问题 参考
一、多大的key算大key
- 按数据大小判断
| 数据结构 | 大key阈值 | 实例场景 |
|---|---|---|
| String | >10MB | 缓存大文件(图片/HTML)、超大JSON |
| Hash | >100MB | 存储百万级字段的用户属性表 |
| List | >100MB | 消息队列积压大量未消费的数据 |
| Set/Zset | >100MB | 存储全网用户id的集合 |
- 按元素数量判断
| 数据结构 | 大key阈值 | 实例场景 |
|---|---|---|
| Hash | >5000字段 | HGETALL阻塞时间超过10ms |
| Set/Zset | >10000成员 | smembers/zrange高延迟 |
| List | >1000元素 | lrange 0 -1网络传输慢 |
二、大key的危害
- 阻塞请求与延迟高
- redis单线程模式下,操作大key(读取10MB的String)会长时间占用主线程,阻塞后续请求。
- 例:HGETALL一个包含100万字段的Hash,可能会导致其他请求延迟飙升(从1ms到数百ms)。
- 内存分配不均
- 集群模式下,大key会导致数据分片不均匀,某个节点内存过高引发OOM。
- 极端场景:一个200MB的key分配到某个slot而其他节点内存空闲。
- 网络阻塞
- 读取大key时(如GET big_key),单次响应数据量过大,占用宽带资源。
- 影响:可能导致从库复制延迟、客户端超时。
- 持久化与备份问题