大型系统的Redis性能优化
问题描述
系统背景:大型线上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. 居安思危,出了问题要想想将来系统发展更大后是否有类似的隐患,早点进行重构改造,做到长治久安。
大型系统的Redis性能优化的更多相关文章
- redis性能优化、内存分析及优化
redis性能优化.内存分析及优化 1.优化网络延时 2.警惕执行时间长的操作 3.优化数据结构.使用正确的算法 4.考虑操作系统和硬件是否影响性能 5.考虑持久化带来的开销 5.1 RDB 全量持久 ...
- 《吐血整理》Redis 性能优化的 13 条军规!史上最全
Redis 是基于单线程模型实现的,也就是 Redis 是使用一个线程来处理所有的客户端请求的,尽管 Redis 使用了非阻塞式 IO,并且对各种命令都做了优化(大部分命令操作时间复杂度都是 O(1) ...
- 吊打面试官系列:Redis 性能优化的 13 条军规大全
1.缩短键值对的存储长度 键值对的长度是和性能成反比的,比如我们来做一组写入数据的性能测试,执行结果如下: 从以上数据可以看出,在 key 不变的情况下,value 值越大操作效率越慢,因为 Redi ...
- C# 大型电商项目性能优化(一)
经过几个月的忙碌,我厂最近的电商平台项目终于上线,期间遇到的问题以及解决方案,也可以拿来和大家多做交流了. 我厂的项目大多采用C#.net,使用逐渐发展并流行起来的EF(Entity Framewor ...
- redis性能优化——生产中实际遇到的问题排查总结
背景 redis-K,V数据库,因其高性能的操作性和支持丰富的数据结构,目前大量被用于衔接应用层和关系数据库中间的缓存层.随着使用的场景越来越多,和数据量快速的递增,在生产环境中经常会遇到相关的性能瓶 ...
- 大型系统中使用JMS优化技巧–Sun OpenMQ
我们先来看看在Sun OpenMQ系统中 一个持久.可靠的方式传送消息的步骤是怎么样的,如图所示: 查看大图请点击这里 在传送过程中,系统处理JMS消息分为以下两类: ■ 有效负荷消息,由生成方发 ...
- 【转载】大型系统中使用JMS优化技巧
[本文转自:http://www.javabloger.com/article/sun-openmq-jms-large-scale-systems.html] 我们先来看看在Sun OpenMQ系统 ...
- redis性能优化
redis日志截图:
- Redis性能优化之redis.cnf配置参数
redis调优总结 1.相应的参数调优 加内存2.redis使用结构调优3.使用合理的数据类型说明:redis存储的数据为redis hash(字符映射表) 单key多字段结构. 1)调整配置文件中配 ...
随机推荐
- CPU组成
感冒了近一周,这两天最终又能正常活动了,,立即開始增产博客啦~ 近期一直都在做软考题.刚開始还是感觉挺无聊的,坐不住,还是一点一点的写个总结吧.今天先来看下比較重要的CPU内部组成. 图画的比較花.事 ...
- [LeedCode OJ]#28 Implement strStr()
[ 声明:版权全部,转载请标明出处,请勿用于商业用途. 联系信箱:libin493073668@sina.com] 题目链接:https://leetcode.com/problems/implem ...
- openwrt gstreamer实例学习笔记(一.初始化gstreamer)
GStreamer 是一个非常强大而且通用的流媒体应用程序框架. GStreamer所具备的很多优点来源于其框架的模块化: GStreamer能够无缝的合并新的插件. 但是, 由于追求模块化和高效率, ...
- python使用cx_oracle连接oracle数据库
http://www.oracle.com/technetwork/topics/linuxx86-64soft-092277.html---下载instantclient-basic-linux.x ...
- window批处理-5 start
作用 又一次启动一个单独窗体.在新窗体中运行命令 格式 start [/w] FileName demo bat: @echo off echo 在新窗体中打开txt文件.并等待新窗体正常退出(exi ...
- C#高阶与初心:(二)P/Invoke平台调用
最近某个项目要采集交易终端的信息用于监管,主要厂商给出了API,C++版的...开启hard模式!!! C#调用C++的DLL基本就两种方法:加一个VC++项目包一层,或者使用P/Invoke(平台调 ...
- 3531: [Sdoi2014]旅行
3531: [Sdoi2014]旅行 Time Limit: 20 Sec Memory Limit: 512 MB Submit: 1731 Solved: 772 [Submit][Statu ...
- Hadoop提供的reduce函数中Iterable 接口只能遍历一次的问题
今天在写MapReduce中的reduce函数时,碰到个问题,特此记录一下: void reduce(key, Iterable<*>values,...) { for(* v:value ...
- [a,s]=[22,3]
[a,s]=[22,3] Object.assign() - JavaScript | MDN https://developer.mozilla.org/en-US/docs/Web/JavaScr ...
- mongo-java-driver
http://mvnrepository.com/artifact/org.mongodb/mongo-java-driver/3.5.0 <!-- https://mvnrepository. ...