一个做批发生意的客户,后端系统开发上线三年,系统越用越慢,首页商品列表每次都要查库,高峰期三百多毫秒。加了缓存之后降到二十毫秒以内,页面秒开,客户很满意。但两个月后出了另一件事:改了某款商品的批发价,前台下单还在用旧价格,财务对账对不上。缓存这东西,用得猛不如用得对。
什么数据该进缓存
判断标准很朴素:读得多、写得少、丢了能重新拿到的数据,最适合缓存。商品分类、系统配置、首页推荐位、省市区数据,这些一天改不了一次,全站却要读几万次,进缓存收益最大。反过来,账户余额、实时库存这类每一秒都可能变的数据,缓存了就是给业务埋雷,宁可让数据库扛着,或者用短到几秒的过期时间兜着。
两个听起来吓人的名词
- 缓存穿透:有人拿数据库里根本不存在的编号反复请求,缓存每次都落空,全部压力砸向数据库。对策是把空结果也缓存几分钟;
- 缓存雪崩:一大批缓存设在同一秒过期,数据库瞬间被打满。对策是过期时间加个随机数,让失效时间错开。
这两个问题修起来都是几行代码的事,但没踩过坑的团队常常想不到。上线前让开发方讲一遍他们的缓存策略,答不上细节的,多半是拍脑袋上的缓存。
还有一条铁律:数据一改就删对应缓存。上面那位客户的旧价格问题,根因就是后台改价只写了数据库,没动缓存。规范的做法是改库和删缓存放在同一个事务流程里,或者干脆给缓存设个较短的有效期当保底。二者结合,基本能把不一致的窗口压到秒级,业务上完全够用。
别忘了内存是花钱买的
见过最离谱的案例:有团队把整个商品表一次性塞进缓存,三年积累的数据把十六G内存吃光了,Redis开始丢数据,谁也没发现。给缓存里的东西设过期时间、控制单个值的大小、定期看一眼内存水位,这三件事比什么高级技巧都管用。
缓存不是性能问题的万能药,它是把数据库的压力换成了一致性的管理成本。数据量小的系统,很多场景把SQL写好、索引建对,根本轮不到缓存出场。后端系统开发里技术手段的引入顺序,应该是先榨干数据库的潜力,再考虑加缓存,顺序反了,问题只是被藏起来了。
两条建议:验收系统时让开发方列出哪些数据走了缓存、各自的有效期是多少;系统用了一年的,安排人查一次Redis内存占用和慢日志。比格网络做系统巡检时这两项是必查的,缓存的问题往往在使用半年后才爆发,提前看一眼不亏。