小服务的缓存策略:先想清楚失效,再谈加速
给小服务加缓存,很多人第一反应是“哪里慢就缓存哪里”。这个顺序反了。缓存真正的难点从来不是怎么存、存多快,而是数据变了之后,旧的缓存什么时候失效、失效不干净会出什么问题。没想清楚失效就上缓存,省下来的响应时间,最后都会以脏数据、用户投诉和深夜排障的方式还回来。
先说一个最常见的坑:缓存了不该缓存的东西。用户个人的信息、权限判断的结果、实时性很强的库存和价格,一旦被缓存复用,就会出现“明明改过了,页面还是旧的”或者更严重的“张三看到了李四的数据”。我的原则是:先给缓存划边界——只有读多写少、所有人看到的结果一致、短时间陈旧可接受的数据,才值得缓存。凡是带用户身份、带权限、带实时状态的,默认不缓存,宁可慢一点,也不要错。
边界划好之后,再定失效策略,而且要按数据分级,不要一把梭。变化极少的基础数据,比如分类、字典、配置,可以设较长的过期时间,改动时主动清掉;变化较频繁但允许短暂延迟的数据,比如文章列表、商品信息,用较短的过期时间兜底,哪怕主动清理漏了,最多几分钟也就自动纠正了;变化频繁且必须实时的数据,就不要硬套缓存,改用别的办法,比如只缓存计算成本高的中间结果,而不是最终结果。过期时间不是越长越好,长过期配主动清理、短过期配自动兜底,这两层配合起来,才不容易出现长时间脏数据。
第三个容易被忽略的点,是缓存穿透和雪崩。小服务的缓存层一旦被击穿,数据库会瞬间扛下全部请求。防穿透最省事的做法是:对查不到的数据也缓存一个短时间的空结果,避免同一个不存在的键被反复打到数据库;防雪崩则是不要让大量键在同一时刻过期,过期时间加一点随机抖动,或者对热点数据用后台异步刷新代替到期删除。这些措施都不复杂,关键是在上线缓存之前就装上,而不是等数据库被打垮了再补。
还有一个实操建议:缓存的键名要一眼能看懂,并且带上版本号或业务标识。比如不要只写一个含糊的键,而要写清楚它是什么业务、哪个维度、哪一版结构。键名混乱的直接后果,就是清理时不敢清、排障时找不到、改结构时旧数据还在被误读。缓存的键名规范,写的时候多花一分钟,排障的时候能省一小时。
最后说一句:缓存是加速手段,不是正确性手段。先保证不缓存错数据、失效策略分级、穿透和雪崩有兜底,再谈命中率和响应时间。小服务的缓存策略,做到这四点就已经超过了大多数实现:边界清晰、分级失效、兜底齐全、键名可读。加速是结果,不是目标;把失效想清楚,加速自然就来了。
- 点赞
- 收藏
- 关注作者
评论(0)