缓存生成成本高、读取频繁且变化很少的数据 — 这就是缓存最有价值的地方。TTL(生存时间)是新鲜度(数据必须有多当前)与容忍过期(数据可以多久保持不准确)之间的权衡。
缓存什么
一个好的缓存候选在以下三个方面都得分很高:
- 昂贵 — 重型数据库联接、聚合、外部 API 调用、渲染的 HTML。
缓存生成成本高、读取频繁且变化很少的数据 — 这就是缓存最有价值的地方。TTL(生存时间)是新鲜度(数据必须有多当前)与容忍过期(数据可以多久保持不准确)之间的权衡。
一个好的缓存候选在以下三个方面都得分很高:
不要缓存计算廉价、写入频繁或每用户机密数据,其新鲜度必须完全准确(例如交易时刻的账户余额)。
Staleness tolerance → TTL:
config / static reference data → long (hours to days)
product listings, article body → medium (minutes)
prices, stock, leaderboards → short (seconds)
must always be exact → don't cache, or use explicit invalidation
对于数据变化难以预测的正确性,将 TTL 与显式失效相结合:写穿通或删除写入,使缓存在源变化的那一刻就被清除,而不是等待过期。
on update(record):
db.save(record)
cache.delete(key(record)) // invalidate now, don't serve stale until TTL
hit ratio = hits / (hits + misses)
high (>90%) → cache is doing its job
low → TTL too short, keys too granular, or data not cacheable
观察缓存命中率来调整 TTL:低命中率意味着你几乎没有缓存;高命中率但有过期投诉意味着 TTL 设置过长。
正确选择缓存什么和 TTL 是有效缓存的核心。缓存错误的东西会增加复杂性而没有收益;设置 TTL 过长会提供过期数据;设置过短则失去缓存的好处。通过使用过期容忍度来选择 TTL、添加显式失效以确保正确性、观察命中率,您可以获得一种原则性的、可衡量的缓存方法。