别再猜了,结论很简单:91大事件为什么有人用得很顺、有人总卡?分水岭就在缓存管理(一条讲透)

在流量爆发或高并发场景下,大家经常把问题归咎于“服务不够强”“数据库慢”“网络波动”。但针对“91大事件”这种以海量事件聚合、实时查询、复杂聚合为特点的系统,真正把体验拉出天壤之别的,往往只是缓存管理做得好不好——不是单纯“有缓存就行”,而是“怎么用缓存”。
先说现象
- 顺畅方:响应稳、P99 有保障、后端压力稳定、线上波动可控。
- 卡顿方:偶发延迟飙升、单点热点压垮后端、频繁缓存穿透或雪崩、更新后数据不一致。
根因拆解(一句话版) 缓存不是万能药,错用反而放大问题。核心问题在于:缓存策略(过期/预热/失效)、热点防护、并发控制、与持久层的一致性策略四项没打通。
四大要点(技术落地) 1) 缓存策略要分级
- 热点只读:长TTL或永久缓存 + 异步刷新(后台定时更新或事件驱动刷新)。
- 高频变更:短TTL + 后台延迟重建或版本化缓存(key 带版本号)。
- 低频小众:按需缓存(cache-aside),避免占用内存。
2) 防止穿透/雪崩/击穿
- 穿透(非法/不存在数据频繁打DB):用 Bloom Filter 或对空结果做短期负缓存(negative cache)。
- 雪崩(大量 key 同时过期):错开 TTL、加随机抖动、预热关键 key 或使用“永不过期 + 背景刷新”策略。
- 击穿(同一热门 key 首次失效):加分布式锁(如 Redis SETNX)或 double-check 缓存重建,限制仅一台机器去重建。
3) 一致性与写时策略
- 最简单:Cache-Aside(读时先查缓存,缓存未命中去 DB 并回写缓存)。适合读多写少场景。
- 写多场景:考虑写穿(write-through)或异步 invalidate + 版本号/消息队列保证最终一致。避免“先写缓存再写库”带来的数据丢失。
- 更新策略:优先用幂等、带版本的更新逻辑;复杂事务尽量走 DB,缓存只做读优化与快照。
4) 监控与自愈
- 关键指标:cache hit ratio、P50/P95/P99 响应时长、miss后端QPS、Redis evictions、latency spikes。
- 告警规则示例:hit ratio 下降 > 10% 且后端 QPS 上升 -> 自动限流或切换降级策略。
- 自动化:热门 key 热点探测并自动加入预热池;发现雪崩趋势自动延长 TTL 并启动限流。
实战小技巧(可直接落地)
- 使用版本化 key:user:123:v42,更新时只改版本号,旧缓存自然失效,避免逐条删除。
- 缓存重建用双写保护:
1) 读到 miss 后先 setnx(lock), 成功者去 DB 构建并写缓存;失败者短等待后重读缓存。
2) 如果构建慢,先返回旧数据并异步触发刷新(soft-expire + background refresh)。 - 对于极热的统计/聚合,先做逐步汇总到时序库或预计算表,再缓存最终结果,避免每次实时聚合打穿下游。
- Redis 配置:合理设置 maxmemory 与 eviction policy(一般用 LRU 或 LFU)、打开慢查询日志、启用 latency-monitor。
验收清单(改完后看这些)
- P99 降低且稳定;后端 QPS 明显下降;cache hit ratio 达标(按业务目标设定);evictions 受控;关键 key 命中稳定。