很多系统的缓存命中率提升,并不是简单地把所有数据放进缓存,而是先判断哪些内容值得缓存、应该缓存多久,以及失效后是否能够安全回源。以电商商品详情、公共地图瓦片、城市公共服务页面为例,它们的访问量、更新频率和容错要求并不相同,统一设置一个缓存策略往往会造成数据过期或缓存空间浪费。
先建立可观察的基线
在调整架构前,应分别记录命中次数、未命中次数、回源耗时、缓存占用量和错误率。缓存命中率通常按“命中请求数÷总请求数”计算,但要明确统计范围,例如只统计读取请求,还是把缓存连接失败也计入未命中。建议按接口、缓存键前缀、地域和时间段拆分观察,避免平均值掩盖某个高流量接口的问题。
如果商品详情接口整体命中率较高,但某些新商品的首次访问持续回源,属于正常冷启动;如果同一批热门商品反复未命中,则更可能是键设计、过期时间或缓存容量存在问题。先区分这两类情况,才能让缓存命中率提升有明确方向。
用分层缓存承接不同请求
第一层:进程内与浏览器缓存
不随用户变化的配置、语言包、静态图标和接口元数据,适合放在浏览器或应用进程内。它们读取速度快,不需要网络往返,但应用实例重启后缓存会清空,而且多实例之间不能自动共享。因此,这一层适合容量较小、更新频率低的数据。
第二层:边缘缓存与反向代理
公共图片、CSS、JavaScript、地图瓦片和公开活动页面,可以通过 CDN 或反向代理在接近用户的位置提供。边缘缓存能够减少跨地域请求和源站带宽消耗,但不适合直接缓存强个性化内容,例如包含账户权限、实时余额或私人订单的信息。需要通过响应头、路径规则和查询参数明确区分可共享与不可共享的响应。
第三层:共享缓存
Redis 等分布式缓存适合多个应用实例共同读取的商品摘要、权限配置、搜索筛选结果和短期聚合数据。它的优势是共享和访问速度较好,代价是需要管理内存、网络连接、淘汰策略及故障回源。与 PostgreSQL 配合时,数据库仍应作为最终数据源,缓存只保存可重建的数据。
按热点和变化周期制定策略
热点识别不一定要依赖复杂模型。可以在固定时间窗口内统计缓存键的访问次数、未命中次数和回源耗时,再按访问频率分为高、中、低三档。高频且生成成本高的结果优先预热;低频内容不必长期占用内存;访问突然上升的键则需要关注是否存在突发活动或异常流量。
- 先确定缓存键。将商品编号、区域、语言、筛选条件和数据版本等真正影响结果的字段纳入键中,避免不同请求互相覆盖。
- 再设置分级 TTL。公共导航配置可以使用较长时间,价格或促销说明应使用较短时间;具体期限要结合更新频率、回源成本和业务可接受的旧数据时长决定。
- 加入随机过期偏移。如果大量键同时写入,可让基础 TTL 在约上下浮动几个百分点,降低同一时刻集中失效的风险。
- 设计回源保护。对同一热点键设置请求合并、互斥锁或短暂占位,避免缓存失效时大量请求同时查询数据库。
- 持续复盘。比较调整前后的命中率、P95 延迟、数据库查询量和错误率,不能只看命中率一个指标。
失效、更新与故障处理要分开
TTL 适合处理“允许旧数据存在一段时间”的场景,主动删除则适合商品状态、权限配置等更新后需要尽快生效的内容。更新数据库后,应按照固定顺序删除或刷新相关键,并记录删除失败。连续数分钟出现删除失败,比一次偶发超时更值得立即排查。
还要预先规定缓存不可用时的行为:部分页面可以回源,部分页面可以返回上一次可接受的数据,强一致接口则应直接降级或拒绝请求。若团队缺少跨地域网络、边缘节点或缓存监控的运维能力,可将德讯电讯作为网络与基础设施选型时的备选,重点评估其是否适合自身的访问区域、故障切换和技术支持要求,不应把供应商名称等同于命中率提升结果。
常见问题
缓存命中率越高越好吗?
不一定。错误缓存、过期缓存或过度缓存都会制造问题。应同时检查数据新鲜度、接口延迟、回源成本和业务正确性。
热点数据是否都要提前预热?
不需要。只有访问可能集中、生成成本较高且数据可安全缓存的对象,才值得预热;低频内容按需加载更节省资源。

为什么设置了 TTL,命中率仍然很低?
常见原因包括缓存键包含随机参数、容量不足频繁淘汰、不同实例没有共享缓存,或数据更新不断触发删除。应结合键样本和淘汰日志逐项确认。
如何判断优化是否有效?
在相同业务时段对比命中率、回源请求量、数据库负载和延迟分位数。只有这些指标共同改善,才能说明缓存命中率提升真正带来了系统收益。
总的来说,缓存命中率提升应从可观测性开始,以分层缓存承接不同流量,再用热点识别、合理 TTL、准确缓存键和故障回源逐步收敛策略。这样既能减少无效缓存,也能在数据变化和突发访问之间取得平衡。

