← 中文资源

简体中文版本

安全地缓存否定结果

对确认不存在的查找短暂缓存以抵御重复查询,但保持 TTL 很短,并在用户可见的写入时绕过它。

阅读英文原文

概述

否定缓存用于保护热门缺失键,避免每个请求都用注定失败的查询打数据库。代价是它会在短期内隐藏即将存在的数据,因此 TTL 必须短,并要在创建路径上显式失效。

关键步骤

  1. 对确认不存在的查找写入哨兵值并设置短 TTL。
  2. 创建或更新同一键时立即删除否定条目。
  3. 否定 TTL 远短于正向 TTL。
  4. 区分缓存错误与真实缺失,避免缓存故障变成接口故障。

验证

  • 重复缺失查询不再访问数据库。
  • 创建后键立即可见。
  • 漏掉的失效在短 TTL 后消解。
  • 缓存不可用时接口仍返回正确结果。

注意事项

  • 否定缓存会短暂隐藏即将存在的数据,读后写流程若无失效则不适用。
  • 若键可由攻击者选择且无限流,可能被用来污染查找。

适用范围

本条目围绕「安全地缓存否定结果」给出可复制的步骤、验证方式与常见问题,适合需要按此流程落地的工程团队。执行时请结合自身上下文调整命令与阈值,并在变更前后留存证据,便于后续复核与回滚。

const cached = await cache.get(key);
if (cached === '__absent__') return null;
if (cached) return cached;
const row = await db.find(id);
await cache.set(key, row ?? '__absent__', { ttl: row ? 600 : 30 });
return row;