大型系统的Redis性能优化
本文为转载:
https://blog.csdn.net/vcbin/article/details/53941682
问题描述
系统背景:大型线上Java服务集群(活跃用户数上千万),业务重度使用Redis存储个管理Session,业务并发量>1WQPS,基本上每个请求都需要访问Redis(可能是多次),使用了AWS的Redis服务
Redis在平时正常流量下平均响应时间是1-2ms,但是在系统峰值流量上来后Redis在这种情况下平均响应延时会超过20ms,在130万的并发现会延时达到30ms左右,严重影响了整个系统的吞吐量和性能,系统会卡死甚至最严重的情况下会JVMCrash
问题排查
- 第一步:快速缓解问题
因为线上业务严重受到影响,首先采用了最快速可以缓解问题的办法:升级AWS中Redis的实例,从m3.2xlarge升级到了r3.2xlarge,高峰时平均响应延时从20ms降到了18ms,但只是简单缓解了问题,系统在高峰期的卡死现象还是偶尔会出现(只是次数减少了)
- 第二步:排查问题根源,彻底解决问题
展开对Redis的详细的问题排查,排查的方向分为以下三个:
1. 业务端是否有很多不合理的Redis请求
研究发现Redis在服务器端 new connection/s: 100左右, new commands/s 70000 左右,commands/per connection 700左右,研究发现使用pipeline比较多,可以考虑使用mget命令。发现这并不是问题的根源。
2. Redis服务器本身有性能问题
可以参考以下链接(蘑菇先生的博客):https://www.cnblogs.com/mushroom/p/4738170.html
- 我们查询Redis的slowlog get,没有特别大的发现(只有一个17ms的慢查询)
- 进一步查看,发现Redis响应慢时,Redis服务器的网络输出带宽接近1G。怀疑这个是瓶颈,分析发现我们用的AWS实例支持10G的上线,也排除了这个可能性
3. 业务集群中用到的Redis客户端:Jedis
- JedisShardedPool maxConnection只设置为128, 怀疑并发比较大Jedis连接不够用了,调整为256试试看结果,发现结果并不明显(Redis服务器本身并不是多线程去相应服务的,一味的加大客户端的并发并不会有效解决的问题),只要自己Jedis连接数能和业务最大并发匹配就可以了
- 网上找中文文章没什么可以参考的经验,最后索性开始看Jedis的英文文档,看看是不是哪些性能相关的参数,我们主要设置的参数有:MaxTotal 96, MaxIdle=64, testOnBorrow=true。 testOnBorrow是指每次Jedis在跟Redis服务器发起请求之前会先发一个test命令去检查Redis是否准备就绪,主要来应对网络和服务器不稳定性的,这平白无故的把Jedis对后台的并发翻了个倍。我们用的是成熟的AWS Redis服务,而且是内网访问,这些testOnBorrow请求完全是多余的。所以果断的改成testOnBorrow=false。见证奇迹的时刻,修改后观察系统在业务高峰情况下稳稳当当,Redis的响应最多也就5ms,平均恢复到2ms。问题搞定
- 同时居安思危,我们也发现了系统性能瓶颈的隐患,如果我们的业务再翻个倍,redis这块会继续成为瓶颈。所以我开始着手后续第三部的改造。
- 第三步:长治久安:引入RedisCluster方案,把系统的缓存提升到>15WQPSLevel
这里我们主要进行了两个大的改造:
1. 首先从业务上把Redis进行拆分,根据业务类型把需要存储在之前一个Redis库的数据拆分成了4个Redis库。这样每个库都可以抗接近7W的QPS了
2. 针对负载最重的Redis库(Session库),在AWS上升级为集群方案,也把我们客户端的Jedis改造成JedisCluster客户端。最后验证下来AWS的Redis集群可以最少支持15W+的QPS,平均响应时间能保证在2ms左右
3. 把一些批量的Redis操作,使用Jedis的pipeline方式减小并发度
最后的胜利:经过这一轮改造,我们的缓存模块一直平稳运行了快2年了,系统的流量最少也翻了6-7倍,这个Redis方案依然稳稳的。老板再也不用担心宕机问题了。
经验总结
1. 遇到线上问题,不能慌了手脚,要先快速的缓解问题,帮组正式分析和正式方案上线争取宝贵时间(那段时间高峰期经常宕机重启,确实捏了一把冷汗啊)
2. 解决问题时(特别是当没有头绪时),还是要从全局出发,理清楚思路,从各个可能出问题的模块逐一去分析排查,抽丝剥茧总能找出根源并制定解决方案
3. 居安思危,出了问题要想想将来系统发展更大后是否有类似的隐患,早点进行重构改造,做到长治久安。