实战-商品中心-Redis集群版超出最大内存限制异常

本文记录了一次在高并发环境下Redis出现OutOfMemory异常的过程。通过对各个节点的细致排查,最终定位到内存溢出的原因,并给出了相应的解决方案。

1、环境配置

环境: 压测环境

版本: 阿里云Redis版(4.0 社区版)

规格: 128G集群版(32节点)

最大连接数: 320,000

客户端: Redisson

2、业务场景

前提: 重构下单主流程,涉及活动、优惠券、订单、商品、库存等业务的拆分和优化。

压测工具: 阿里云 - 性能测试PTS

压测场景: 测试人员连续**5天下单接口 进行压测,初步估算有产生3亿+**的订单量,并且这些订单集中在7个商品上。

注:库存服务为了提升吞吐量,将订单ID缓存到了Redis中。

3、具体错误

在扣减库存时,报如下错误,导致整个Redis不能对外提供服务。

org.redisson.client.RedisOutOfMemoryException: command not allowed when used memory > 'maxmemory'.   

上面的错误信息很明显意思是redis的使用内存超出了最大内存限制。

4、分析

一个很蛋疼的历程,特此记录。

发现该错误并结合这几天的压测情况,第一直觉就是Redis服务端内存不够了,因为下单存在热点key的情况。

于是通过阿里云Redis管理控制台的性能监控查看Redis的各项指标,发现CPU、Memory、连接数等各项指标均为正常,甚至负载都非常低。也单独查看了前面几个节点的监控信息,也正常。这就奇怪了。

于是怀疑是Redisson的问题,在官网还真找到了 RedisOutOfMemoryException 相关的Issues,并且有一个JedisRedisson的对比案例,说是Jedis不报错误,而Redisson就是报这个错误,经过本地验证,确实如此。

https://github.com/redisson/redisson/issues/1955

内心一阵独白MMP,临近上线,Redisson出现这么个巨坑。于是准备把涉及的多个服务和自研的二级缓存组件中相关Redisson的实现全部给替换掉。

但是时间和风险成本太高,于是拉上另一个架构师一起来分析,一个一个Redis节点排查,最终发现其中有一个节点内存使用率达到100%,具体如下:

memory_usage

在这里插入图片描述

evicted_keys

另外,分析超出maxmemory限制的问题,可以通过 evicted_keys 这个指标直观的分析出来。

evicted_keys 表示因达到maxmemory限制而被驱逐的键的数量。
若 evicted_keys > 0,则说明已经出现了超过maxmemory限制的情况,那么客户端极有可能会报 command not allowed when used memory > 'maxmemory'. 这个错误。

在这里插入图片描述

info

通过Info命令查看Redis状态。
在这里插入图片描述

由此可见,除了要了解redis的实现原理外,还要对其各项运维指标有深入的了解,这样才能更好的去应对各种突发问题。

5、方案

1、清理掉Redis数据

2、减小库存服务中订单ID缓存的过期时间

单个数据结构只被保存在一个固定的槽内,所以存在单节点瓶颈

3、将Hash数据结构换为String数据结构 ,达到将orderId均匀分布到不同的节点上的目的。

4、采用Redisson PRO版本来解决热点key数据路由到不同的数据分区进行存储,分散单节点的压力。

Redisson PRO 为收费版本。

6、总结

从上面的这个坎坷历程可以发现几个点

1、不够细心,没有一个一个节点去排查分析

2、不够坚定,没有坚持自己最初的判断

3、对Redis的各项指标了解不够深入,其实可以很快定位到问题

4、技术选型一定要慎重,除了它的特性外,更多的要关注它有什么坑

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白云coy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值