缓存不是越多越好
很多人一听到性能问题,第一反应就是加缓存。但高频数据场景下,盲目缓存反而可能拖慢系统。比如你在做实时股价展示,每秒更新上千条数据,如果每条都往内存里塞,很快就会把内存撑爆,GC(垃圾回收)频繁触发,卡顿就来了。
真正有效的做法是判断数据的“热度”。像用户常访问的股票代码前100名,可以优先缓存,冷门的直接查库。用LRU(最近最少使用)策略自动清理不常用的数据,内存利用率能提升一大截。
选择合适的缓存粒度
缓存一个完整的用户详情可能包含头像、昵称、积分、等级等信息。但如果只是频繁读取积分,每次都拿整个对象,浪费带宽也占内存。
拆细一点,按字段缓存。比如把用户积分单独存成 key: user:1001:score,更新时只刷这部分。这样读取快,更新也轻量。特别是高并发签到场景,每天上百万次积分变更,这种细粒度控制能明显降低缓存压力。
利用本地缓存减少远程调用
Redis 虽好,但每次网络往返至少几毫秒。在服务节点本地加一层缓存,比如用 Caffeine 或 Guava Cache,能把响应时间从 5ms 压到 0.2ms。
举个例子,你做个短视频推荐接口,热门视频ID列表被反复请求。每次都走 Redis?没必要。本地缓存5秒更新一次,既能保证新鲜度,又扛得住突发流量。
Cache<String, List<Long>> localCache = Caffeine.newBuilder()
.expireAfterWrite(5, TimeUnit.SECONDS)
.maximumSize(1000)
.build();避免缓存雪崩:别让系统瞬间崩盘
缓存同时失效,大量请求直奔数据库——这就是雪崩。曾经有电商大促,缓存过期时间全设成1小时,整点一到,数据库被打满,页面打不开。
解决办法很简单:给过期时间加个随机偏移。同样是1小时,实际设置为 3600 ± 300 秒之间。这样请求会分散开来,不会集中冲击底层存储。
异步刷新缓存,保持数据流动
有些数据不能容忍长时间空窗。比如天气App的实时气温,总不能等缓存过期才去查,用户看到的就是旧数据。
这时候可以用“被动过期 + 主动刷新”组合拳。缓存到期后,不等请求来,后台线程提前去拉新数据。或者第一次请求发现快过期了,就异步触发更新,当前请求仍返回旧值,体验更顺滑。
高频场景下,缓存不是一次性配置就完事的事,得持续观察命中率、延迟、内存增长趋势。工具像 Prometheus 配合 Grafana,能帮你盯着这些指标,及时调整策略。