Redis 热 Key(Hot Key)指的是访问频率极高的 Key,通常会造成以下问题:
要优化 Redis 热 Key 问题,首先需要找到这些 Key。可以使用以下方法:
`monitor`(不推荐线上使用):
redis-cli monitor
该命令会实时输出所有 Redis 操作日志,可以用来观察哪些 Key 被频繁访问。
`hotkeys`(适用于 Redis 7.0+)
redis-cli hotkeys
该命令直接列出热点 Key,是 Redis 7.0 之后的新功能。
`info commandstats`
redis-cli info commandstats
该命令可以查看 Redis 命令的执行统计,比如 `get`、`set` 命令的执行次数,可以间接推测哪些 Key 访问频率较高。
CONFIG SET slowlog-log-slower-than 10000 # 记录执行时间超过 10ms 的命令
然后查看慢查询日志:SLOWLOG GET 10
观察是否有特定 Key 被频繁查询。在业务代码中增加访问日志,例如使用 AOP 记录 Redis 访问日志,或者在 Redis 代理层(如 Twemproxy)收集 Key 的访问情况。
问题类型 | 影响 |
---|---|
CPU 负载高 | 单 Key 访问过多,Redis 线程 CPU 使用率高 |
网络流量大 | Redis 可能面临巨大的请求流量,影响网络性能 |
数据库压力高 | 如果热点 Key 失效,可能导致数据库访问量暴增 |
业务响应变慢 | Redis 请求延迟增加,影响业务体验 |
针对 Redis 热 Key 的问题,可以采取以下几种优化策略:
适用于 热点 Key 访问频繁且数据变动不频繁 的场景。
示例:
LoadingCache<String, String> localCache = CacheBuilder.newBuilder()
.expireAfterWrite(10, TimeUnit.SECONDS)
.maximumSize(1000)
.build(new CacheLoader<String, String>() {
@Override
public String load(String key) throws Exception {
return redisClient.get(key); // 从 Redis 加载
}
});
当数据更新时,主动删除本地缓存:
localCache.invalidate("hot_key");
适用于分布式集群环境,缓解单点压力:
示例流程:
适用于 Redis 读流量过高的场景
slaveof <master-host> <master-port>
适用于 Redis Key 访问不均衡的场景
适用于热点 Key 频繁访问但过期后可能引发缓存击穿
EXPIRE hot_key $((60 + RANDOM % 30))
适用于 缓存数据实时性要求不高,但访问量极大 的情况:
适用于 系统启动或热点数据突增的场景
示例:
redis-cli -x set hot_key < hot_data.json
方案 | 适用场景 | 优缺点 |
---|---|---|
本地缓存 | 访问频繁但数据变动少 | 低延迟,但数据一致性问题 |
多级缓存 | 访问量大,数据库访问量大 | 读性能高,但增加复杂度 |
读写分离 | 读多写少的场景 | 读性能提升,但架构复杂 |
数据分片 | 访问集中在部分 Key | 负载均衡好,但实现复杂 |
Key 过期策略 | 缓存击穿风险高 | 减少缓存穿透,但不适合频繁变更数据 |
异步更新 | 低实时性需求场景 | 减少 Redis 负担,但一致性受影响 |
预热 | 业务启动或热点突增 | 预防热点 Key 失效,但维护麻烦 |