缓存键怎么设计
键要能唯一定位一份数据,且随依赖变化。常见错误是键里漏了版本或租户,导致串数据。
TTL 不是越大越好
TTL 越长越可能读到旧值;越短命中率越低。按数据可变频率设:配置类可长,库存类要短或主动失效。
三种典型故障
| 问题 | 现象 | 对策 |
|---|---|---|
| 穿透 | 查不存在的 key 打到库 | 缓存空值 / 布隆过滤器 |
| 击穿 | 热点 key 失效瞬间洪峰 | 互斥重建 / 逻辑过期 |
| 雪崩 | 大量 key 同时失效 | TTL 加随机抖动 |
更新还是删除
写后优先删除缓存(lazy 重建),比立即写回更简单、不易不一致。
把失效做成可验证的流程
缓存问题的根源往往不是技术选型,而是缺少一套可验证的失效流程。以下做法能在实践中显著降低脏数据与雪崩的概率。
- 明确每一份数据的权威来源:先确定哪个系统是唯一事实来源,缓存只是它的投影。一旦出现两个都可写的存储,一致性就只能靠运气。写入必须只走权威来源,缓存仅被动更新。
- 键的命名要能“批量失效”:设计键时按“业务对象 + 维度 + 版本”组织,例如把租户与对象类型放在前缀里。这样需要清理某类数据时可以按前缀批量删除,而不必逐个枚举键,生产环境里无法批量失效是缓存事故的常见放大器。
- 失效失败要能被发现:删除缓存的调用可能因网络抖动而失败。应记录失败次数并在超过阈值时告警,同时准备兜底手段,例如提高该键的读取频率或临时把读流量绕过缓存。
- 为热点键单独设策略:访问量极高的键一旦过期,重建压力会集中打到数据库。可以对这类键采用逻辑过期,即缓存中保留过期标记,由一个并发受限的协程负责重建,其余请求先拿到旧值。
- 压测失效路径:发布前模拟“大量键同时失效”和“数据库短暂不可用”两种场景,确认系统仍能提供降级内容而不是直接报错。这条验证常常能提前发现最严重的问题。
与业务语义对齐
技术上的失效策略还要与业务可接受的陈旧程度对齐。商品库存通常要求秒级一致,而文章正文可以容忍分钟级延迟。把这些要求明确写进接口说明,缓存时长就不再是凭感觉设定的数字,而是有业务依据的约定。