Lease 模式:给回填缓存发一张许可证
旁路缓存有个经典竞态:A 查库拿到旧值,还没写进缓存;这时 B 改了库、删了缓存;A 再把旧值写进去。缓存里就是脏的了。
Lease 的做法(来自 Facebook 的论文 Scaling Memcache at Facebook):
- 缓存未命中时,发一张绑在这个 key 上的短时 token,回填时必须带上它。
- 中途有人删除这个 key,token 随之作废,带着旧 token 的回填会被拒绝。
- 同一段时间里只发一张 token,没领到的人原地等一会儿,防止一千个请求同时冲到数据库(缓存击穿)。
打个比方:给去仓库抄账本的人发一张「抄写许可证」。老板改账本、撕掉便签时,顺手把许可证作废;拿着旧数据慢慢走回来的人,验票不过,不准往便签上写。
Redis 没有现成的 lease 命令,可以用一个 lease key 加 Lua 脚本近似实现。