记一次redis连接建立超时的问题解决


背景:

1.系统由多个进程组成,几乎每个进程都需要访问redis。

2.所有进程都部署在一台机器,包括redis/mysql。

3.redis驱动程序使用的是jedis 2.8。

4.每个进程配置的redis连接池数量都较大,最大大概几百个连接。

5.现场人员报告,页面某功能偶现不可用的情况,经查相关进程日志,是由于redis连接建立失败导致的。

排查过程:

1.搭建压力测试环境,模拟现网压力,同样出现了redis建立连接失败,异常显示socket connection timeout。

2.尝试修改连接池配置,将idl调成和total一致,均为200,问题并未解决。

3.尝试加大连接池数量,问题并未解决。

4.后来想到,redis服务器是单线程的,即同一时刻,仅处理一个连接发出的指令,那么连接池中的多个连接,虽然将指令发送至redis,但redis并未立即处理,而是在排队。那么,与其将指令发送给redis,在redis端排队,不如在本进程内排队,暂不将指令发送至redis,即将redis连接池idl/total均设为1,仅维持一条与redis的连接,如果业务量过大,本进程内排队超时,也就是等待从连接池获取连接超时,那么可以通过加大连接池的maxwait值来解决。想到此点之后,将连接池idl/total调整为1,开始压力测试,未再出现连接建立超时。

5.问题解决。

经验:redis服务器是单线程模型,加大连接池,只是加大排队的队列数,但是,redis是多进程共用,压力较大,在处理大量的redis指令的同时,还要维护大量的连接,是很耗资源的。所以,每个进程仅维持一条与redis的连接,通过加大maxwait,来控制在本进程内排队,可以降低redis的压力。redis和mysql等不同,mysql是可以多个连接的指令并行执行的,所以连接池设置过大没有意义。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM