北京公司网站设计价格,做一个简单的网站要多少钱,竞价是什么工作,互联网线上推广目录 **如何解决 Redis 的热 Key#xff08;Hot Key#xff09;问题#xff1f;****解决方案** **1. 使用多级缓存****方案** **2. 进行 Key 预分片#xff08;Key Sharding#xff09;****方案** **3. 使用 Redis 复制机制#xff08;主从复制或集群#xff09;****方案… 目录 **如何解决 Redis 的热 KeyHot Key问题****解决方案** **1. 使用多级缓存****方案** **2. 进行 Key 预分片Key Sharding****方案** **3. 使用 Redis 复制机制主从复制或集群****方案** **4. 采用批量 Key 轮换Consistent Hash****方案** **5. 采用异步更新策略****方案** **6. 限流和降级****方案** **7. 结合 MQ 做异步削峰****方案** **总结****面试标准回答** 如何解决 Redis 的热 KeyHot Key问题
热 KeyHot Key是指访问频率极高的键在高并发场景下可能会造成
单个 Redis 节点压力过大大量请求命中一个 Key。CPU 过载响应变慢甚至影响整个 Redis 集群。缓存失效后大量请求直接打到数据库导致数据库崩溃缓存击穿。
解决方案
针对不同场景解决方案主要包括 “分散请求” 和 “降低 Redis 负载” 两个方向。 1. 使用多级缓存
核心思路在 Redis 之前增加一级缓存减少 Redis 访问压力。
方案 本地缓存L1 Cache 在应用服务器上存储热点数据如 Guava Cache, Caffeine。优点访问速度更快避免 Redis 过载。缺点如果多个应用服务器同时缓存相同 Key可能会有数据一致性问题。 CDN 缓存L0 Cache 适用于静态资源或热点数据如商品详情页。优点减少数据库、Redis 访问压力。
示例使用 Guava 本地缓存
LoadingCacheString, String localCache CacheBuilder.newBuilder().maximumSize(1000).expireAfterWrite(10, TimeUnit.MINUTES).build(new CacheLoaderString, String() {public String load(String key) throws Exception {return redis.get(key); // 从 Redis 取数据}});// 读取缓存
String value localCache.get(hot_key);2. 进行 Key 预分片Key Sharding
核心思路将单个热 Key 拆分成多个 Key让不同的 Redis 节点存储不同的副本从而分散压力。
方案
存储时写入多个不同的 Key例如 hot_key_1, hot_key_2, hot_key_3。查询时随机访问 hot_key_n或使用一致性 Hash 计算 Key。
示例
// 写入时分片
for (int i 0; i 3; i) {redis.set(hot_key_ i, value);
}// 读取时随机选一个
String key hot_key_ (rand() % 3);
String value redis.get(key);适用场景
高并发计数如热点直播间点赞。高 QPS 的热点数据如秒杀商品库存。 3. 使用 Redis 复制机制主从复制或集群
核心思路通过 Redis 读写分离多个节点分担读取压力。
方案
主节点Master处理写请求多个从节点Slave处理读请求。结合 客户端负载均衡将 get 请求分发到不同的从节点。
示例配置 Redis 读从库
slaveof master_ip master_port适用场景
适用于 Redis 集群模式大规模热 Key 分布式缓存场景。 4. 采用批量 Key 轮换Consistent Hash
核心思路通过一致性哈希Consistent Hashing降低热 Key 访问压力。
方案
将一个 Key 拆分成多个时间窗口 Key。访问时随机选择一个 Key确保热点数据均匀分布。定期清理过时的 Key。
示例
String key hot_key: (time(nullptr) % 5); // 轮换 Key
redis.set(key, value);适用场景
防止缓存击穿热点数据定期轮换。适用于短周期热点数据如秒杀、短时间访问高峰。 5. 采用异步更新策略
核心思路缓存失效后先返回旧值同时异步更新缓存避免大量请求瞬间打到数据库。
方案
采用 双缓存Double Cache 机制 用户查询时返回旧缓存。后台异步更新新数据。
示例
String value redis.get(hot_key);
if (value null) {value localCache.get(hot_key); // 先从本地缓存读取asyncUpdateRedis(); // 后台线程更新 Redis
}
return value;适用场景
避免缓存击穿问题如商品价格、秒杀库存。 6. 限流和降级
核心思路如果 Redis 无法支撑高并发请求可以限制请求频率或者直接返回默认值。
方案 限流使用令牌桶 / 滑动窗口 限制相同 Key 的访问频率。避免短时间内 Redis 负载过高。 降级请求超时时返回默认值 如果 Redis 繁忙则返回本地默认值减少 Redis 压力。
示例限流
local key KEYS[1]
local limit tonumber(ARGV[1])
local current redis.call(incr, key)if current 1 thenredis.call(expire, key, 60) -- 60s 过期
endif current limit thenreturn 0 -- 限流失败
end
return 1适用场景
API 访问频率控制如抢购、直播点赞。 7. 结合 MQ 做异步削峰
核心思路将高并发请求写入消息队列如 Kafka / RabbitMQ异步处理降低 Redis 访问压力。
方案
将请求写入 Kafka批量处理。后端定期刷新缓存避免 Redis 承担高并发压力。
示例
// 生产者将查询请求写入 MQ
kafkaProducer.send(hotKeyTopic, hot_key);// 消费者异步更新缓存
kafkaConsumer.onMessage(msg - {String value queryDatabase(hot_key);redis.set(hot_key, value);
});适用场景
适用于秒杀、短时热点数据如抢购、热点新闻。 总结
方法核心思路适用场景多级缓存L1本地缓存 L2Redis 缓存低延迟读取热点数据Key 预分片拆分热 Key分散访问压力高并发计数直播点赞、热点商品主从复制读写分离提高读性能Redis 集群读多写少轮换 Key使用 Hash 轮转 Key秒杀库存、短时间热点数据异步更新先返回旧缓存后台更新价格、秒杀商品库存限流和降级限制访问频率防止 Redis 过载高 QPS 接口秒杀抢购MQ 削峰通过 Kafka / RabbitMQ 处理请求高并发订单、热点数据
面试标准回答 解决 Redis 热 Key 主要有 3 类方法 减少 Redis 访问压力本地缓存、CDN、读写分离。分散 Key 访问Key 预分片、轮换 Key。限制并发限流、降级、MQ 削峰。 最推荐的方案是本地缓存 Key 预分片 Redis 读写分离结合业务需求选择最优方案