高并发场景下有哪些常见缓存问题,对应解决方案是什么?
2 个回答
勇敢一点吧!我们不会比今年更年轻了。澜夜师兄# 高并发常见缓存问题及解决方案 ## 1. 缓存穿透 - **作用**:防止查询不存在的数据时,请求绕过缓存直接打到数据库。 - **原理**: - 问题原因是数据库和缓存中都没有对应数据,每次请求都会查库,恶意构造不存在的 ID 时风险更明显。 - 可缓存空结果,并设置较短过期时间,例如缓存 `null` 值 5 分钟。 - 可使用布隆过滤器,在请求进入缓存或数据库前拦截明显不存在的数据。 ## 2. 缓存雪崩 - **作用**:避免大量缓存同一时间失效,导致数据库瞬间承受全部流量。 - **原理**: - 问题原因通常是大量 key 设置了相同过期时间,或缓存节点整体故障。 - 设置过期时间时增加随机偏移,例如在统一时间基础上增加 `±10 分钟`。 - 使用多级缓存提高可用性。 - 结合缓存高可用、限流降级、数据库读写分离和监控告警,降低数据库过载风险。 ## 3. 缓存击穿 - **作用**:保护热点数据在缓存失效瞬间不被大量并发请求同时回源。 - **原理**: - 某个热点 key 过期时,大量并发请求同时查询数据库并重建缓存。 - 对热点数据设置逻辑不过期,由后台任务异步更新。 - 使用互斥锁或分布式锁,保证同一时间只有一个请求查询数据库并重建缓存,其他请求等待后读取新缓存。 ## 4. 缓存与数据库数据不一致 - **作用**:避免更新过程中应用从缓存读到旧数据。 - **原理**: - 问题通常由缓存和数据库更新顺序不当、并发写读交错或删除缓存失败引起。 - 采用 **Cache-Aside** 策略:更新时先更新数据库,再删除缓存;下次查询时再从数据库加载最新数据并写入缓存。 - 对一致性要求更高的场景,可结合消息队列进行延迟双删或失败重试。 ## 5. 缓存污染 - **作用**:避免大对象或冷数据长期占用缓存空间,挤出高频热点数据。 - **原理**: - 大量一次性访问的冷数据或超大对象进入缓存后,会降低热点数据命中率。 - 使用 LRU 等淘汰策略控制缓存空间。 - 对大对象进行拆分存储,避免单个 key 占用过多内存。 - 持续监控缓存命中率、内存占用和数据库负载,及时调整缓存策略。发布于 2026-10-29 07:24 •IP属地 天津举报评论收藏
浪漫的灵魂从不向平淡的日子妥协。秦尘## 作用 高并发缓存场景主要要防范三类问题: - **缓存穿透**:查询不存在的数据,缓存和数据库都没有,请求持续绕过缓存打到数据库。 - **缓存击穿**:某个热点 key 恰好过期,瞬间大量并发同时访问数据库。 - **缓存雪崩**:大量 key 同时失效,或缓存集群宕机,导致数据库承受流量洪峰。 ## 原理与解决方案 ### 1. 缓存穿透 - **空值缓存** - 数据库查不到数据时,在缓存中写入一个短 TTL 的空标记,例如 30~60 秒。 - 后续相同请求会被空值缓存拦截。 - 优点是简单有效,缺点是会占用少量缓存空间。 - **布隆过滤器** - 在缓存前增加布隆过滤器,并预热全量合法 key。 - 如果布隆过滤器判断 key 一定不存在,则直接拒绝请求。 - 适合 key 集合相对固定的场景,如商品 ID、用户 ID。 - 注意布隆过滤器存在误判率,且删除困难,需要提前设计重建方案。 - **请求侧风控** - 在网关层限制单 IP、单用户的高频缓存 miss 请求。 - 适合防范恶意扫描或遍历 ID 段造成的穿透。 ### 2. 缓存击穿 - **逻辑过期** - 热点 key 物理上不设置 TTL,在 value 中保存逻辑过期时间。 - 发现逻辑过期后,只让一个线程异步重建缓存,其他线程继续返回旧值。 - 可以牺牲少量实时性,避免热点 key 被瞬时击穿。 - **互斥重建** - 热点 key 过期后,通过 Redis `SETNX` 等分布式锁保证只有一个请求访问数据库并重建缓存。 - 其他请求可以短暂等待、自旋重试,或直接返回旧值。 - 需要设置锁过期时间,避免锁未释放导致请求死等。 - **热点探测与预热** - 通过访问统计识别 Top 热点 key,提前预热并延长 TTL。 - 大促前可对爆款商品等已知热点进行人工预热。 ### 3. 缓存雪崩 - **TTL 加随机抖动** - 批量写入缓存时,在统一 TTL 基础上增加随机偏移,例如 0~300 秒。 - 避免大量 key 在同一时刻集中失效。 - **多级缓存** - 使用本地缓存和分布式缓存组成双层缓存,例如 Caffeine + Redis。 - Redis 抖动或不可用时,本地缓存可以承接部分读流量。 - **数据库限流兜底** - 在数据库前设置连接池上限和限流策略。 - 缓存整体故障时,宁可让部分请求失败,也不能让数据库被打垮而导致全站不可用。 - **缓存集群高可用** - 使用 Redis 主从、哨兵或集群模式,实现故障自动切换。 - 切换期间应准备降级方案,例如读取旧数据或返回静态兜底页。 ## 验证方式 防护方案上线后应通过故障演练验证: - 模拟大量查询不存在的数据,验证缓存穿透防护。 - 删除热点 key,验证缓存击穿防护。 - 重启 Redis 或模拟缓存集群故障,验证雪崩兜底和恢复能力。 缓存防护的核心是提前假设缓存会未命中、会过期、也会宕机,并分别为这些故障设计兜底方案。发布于 2026-10-29 00:51 •IP属地 河南举报评论收藏
公众号进入网站体验更佳

