尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Caffeine内存溢出、Redis超maxmemory限制?L2Cache两大生产事故复盘与优化方案

Caffeine内存溢出、Redis超maxmemory限制?L2Cache两大生产事故复盘与优化方案 Caffeine内存溢出、Redis超maxmemory限制L2Cache两大生产事故复盘与优化方案【免费下载链接】l2cacheL2Cache 是一个基于 Caffeine Redis 的二级缓存框架。让缓存的使用在业务开发中更加简单、高效。项目地址: https://gitcode.com/gh_mirrors/l2/l2cacheL2Cache 是一个基于Caffeine Redis的分布式二级缓存框架L1 本地内存 L2 集中式缓存。本文复盘两类真实生产事故Caffeine 本地缓存内存溢出 OOM与Redis 超出 maxmemory 限制并给出可落地的优化方案与避坑清单帮你在接入二级缓存前把风险想清楚。快速认识 L2Cache 二级缓存架构L2Cache 没有重复造轮子而是把 Caffeine、Redis、Spring Cache 这些成熟组件组合封装屏蔽了复杂的缓存操作细节。核心是可通过配置灵活组合缓存类型L1 一级缓存本地内存缓存支持 Caffeine / Guava Cache目标是降低对 L2 的读取次数省掉网络 IO 开销L2 二级缓存集中式缓存Redis避免应用重启导致 L1 数据丢失组合缓存compositeL1 L2 同时工作即典型的二级缓存模式。只需在配置中调整cacheTypecaffeine/redis/composite等即可切换架构相关模块位于l2cache-core/与l2cache-spring-boot-starter/。但请注意二级缓存不是万能药。下面两个事故恰恰发生在用错了场景和踩了集群细节上。事故一Caffeine 本地缓存 OOM内存溢出场景用户维度缓存 极低命中率某电商平台用户服务使用 L2Cache 二级缓存缓存用户信息本地 Caffeine 配置为最大元素 5000、过期时间 30 分钟。业务上有个致命点——不同用户只能查自己的信息命中率极低几乎每个请求都是一个新 key。症状频繁 GC 最终 OOM线上监控发现服务频繁 YoungGC、FullGC最终抛出 OOM。表面上看缓存才 5000 个元素怎么会吃光内存根因低命中率场景下异步淘汰追不上写入结合 Caffeine 源码BoundedLocalCache.scheduleDrainBuffers→PerformCleanupTask分析完整链路是大量未命中请求不断写入新缓存项迅速突破maximumSize5000限制Caffeine 的基于大小的淘汰是异步的由线程池执行清理任务高并发下淘汰任务堆积、清理不及时缓存对象不断累积经历几次 YoungGC 后这些对象被晋升到Old 区老年代飙升 → 频繁 FullGC →OOM。 结论Caffeine 不适用于数据量大 命中率极低的场景如用户维度缓存。优化方案按命中率选择缓存架构高命中率场景如商品维度不同用户看同一个商品放心使用composite二级缓存享受 L1 的速度低命中率场景如用户维度去掉本地缓存直接用 Redis 即可l2cache: config: cacheType: redis一行配置规避整个 OOM 风险。事故二Redis 超出 maxmemory 限制场景5 天压测、3 亿 订单压在 7 个商品上重构下单主流程后的压测中订单集中在 7 个商品典型热点 key库存服务又把订单 ID 缓存到了 Redis。第 5 天扣减库存时全线报错整个 Redis 集群无法对外服务org.redisson.client.RedisOutOfMemoryException: command not allowed when used memory maxmemory.误判的坑客户端框架差点背锅诡异的是集群控制台上 CPU、内存、连接数等指标全部正常。排查中甚至发现一个现象同样的超限场景 Jedis 不报错、Redisson 却报错一度怀疑是客户端框架的坑准备大动干戈替换实现。⚠️ 教训集群版的指标是平均值单节点瓶颈会被淹没。坚持逐节点排查后终于发现其中一个节点内存使用率打满 100%根因Hash 结构 热点 key 单节点瓶颈集群版 Redis 中单个数据结构只会被固定路由到某个槽位/节点。订单 ID 用 Hash 结构缓存后热点订单的压力全部压在单一节点上该节点先于其他节点触达 maxmemory。关键定位指标evicted_keys分析 maxmemory 超限问题evicted_keys是最直观的指标——表示因达到内存上限而被驱逐的键数量。只要它大于 0说明已经出现超限客户端极可能开始报command not allowed when used memory maxmemory也可以通过INFO命令直接查看evicted_keys与expired_keys的数值Redis INFO命令输出显示evicted_keys键驱逐计数定位缓存内存溢出优化方案清单措施作用清理 Redis 存量数据立即释放内存恢复服务缩短订单 ID 缓存过期时间减少单节点数据堆积速度Hash 结构换为 String 结构让 orderId 均匀分散到不同节点消除单点热点 key 路由到不同数据分区分散单节点压力如 Redisson PRO 的热 key 路由补充复盘高并发下的另一种 OOMrefresh 消息风暴L2Cache 通过缓存同步消息保证集群各节点 L1 一致性。一次双十二压测中120 个 pod 对同一个 key 并发加载缓存每次 put 都广播一条 refresh 消息其他 119 个 pod 都会消费并执行 refresh——单个 key 的 refresh 日志高达 63 亿条。Caffeine 的refresh()是异步的任务不断涌入 ForkJoinPool 的无界队列消费跟不上生产队列堆积最终 OOM。多级缓存各节点的过期时间并不天然一致需要配合同步/刷新机制来对齐这也正是事故温床双向优化发送侧refresh 消息改异步发送并对同一 key 加分布式锁保证 500ms 内只发送一次消费侧基于原子计数器过滤重复 refresh 消息——同一 key 有正在执行或等待执行的 refresh 任务时直接丢弃高并发下可过滤掉绝大部分重复消息。避坑清单二级缓存内存事故自查 ✅先问命中率低命中率用户维度不要上本地缓存cacheType: redis更安全必设上限Caffeine 必须配置maximumSize与过期时间杜绝无界缓存盯紧指标把evicted_keys、节点级内存使用率纳入告警集群平均值会骗人警惕集群路由Hash 等单数据结构受槽位约束热点 key 会形成单节点瓶颈必要时换 String 结构打散控制消息放大集群广播的刷新/失效消息要做去重与限流防止无界队列堆积看 GC 曲线老年代持续攀升 频繁 FullGC 是缓存对象堆积的早期信号别等 OOM 才发现。参考资料事故一手记录doc/实战-l2cache-caffeine之内存溢出分析.mdRedis 超限排查实录doc/实战-Redis超过maxmemory限制的问题.md高并发 OOM 完整分析doc/实战-l2cache高并发场景下出现OOM的分析和优化方案.md更多问题与方案doc/关于缓存的几个常见问题分析和处理方案.md同步策略配置样例doc/缓存同步策略配置样例.md核心框架源码l2cache-core/Spring Boot 集成l2cache-spring-boot-starter/缓存是性能利器但每一次省掉的 DB 压力都可能在某个高并发瞬间以内存的形式讨回来。选对架构、配好上限、盯住指标二级缓存才能稳稳地成为系统的加速器。【免费下载链接】l2cacheL2Cache 是一个基于 Caffeine Redis 的二级缓存框架。让缓存的使用在业务开发中更加简单、高效。项目地址: https://gitcode.com/gh_mirrors/l2/l2cache创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表