Redis连接错误的情况总结分析
前言
最近由于流量增大,redis出现了一连串错误,比如:
- LOADINGRedisisloadingthedatasetinmemory
- useofclosednetworkconnection
- connectionpoolexhausted
- connectionrefusebypeer
一个个来分析。
LOADINGRedisisloadingthedatasetinmemory
这里至少有2种可能
- 可用内存太小,修改redis.conf中的maxmemory即可解决
- redis在启动时正在加载dump.rdb文件,由于加载比较慢导致redis在启动时不可用
我遇到的就是第2种情况,AWS在自动扩容的时候,每个新产生的EC2实例都报错,原因就是redis在启动时发现有个dump.rdb,然后就去加载它,导致服务器里的服务都报错,然后就退出了,并且redis加载这个要好久(不知道为什么),supervisord自动重启了新的服务后依然报错。
后来把镜像中的dump.rdb文件删了,服务才能正常启动。
dump.rdb文件产生的原因可能是之前redis出现了某种错误,然后在制作镜像时也做进去了,导致新生成的实例个个都报错。
这次吸取了教训,下次制作镜像之前都要先stop掉redis然后删掉dump.rdb。
其他3种错误
一开始也是各种找资料,然后各种改配置,导致这3种错误都先后出现。
一开始我认为是golang代码没有正确处理redis连接异常的情况,于是各种升级redigo,改golang中的timeout、max_active、wait等的配置,发现都没有用。
这样来来回回折腾了大概一周,终于从pool.Active和pool.MaxActive中发现了猫腻。
因为我MaxActive设置的是10000,于是我开了10000个goruntine去测试它,发现当前连接数pool.Active老是才4000左右,然后就各种报错。
那段时间也是脑子短路了,老是认为redigo没有正确处理redis的连接才导致pool.Active不能上到最大。老是想着改redigo的代码……
后来实在没办法,想着去改一改ulimit,旧的是500000,改到990000,发现还是报连接错误,pool.Active还是上不去,我想这不可能啊,这才想到会不会是redis本身有最大连接数的配置。上网一查,果然,redis-server有一个maxclients的配置……默认是4000多,改到10000后,整个世界都清静了……
其实也不能怪我,因为redigo也有个max_active参数,鬼知道redis-server还要设置呢[笑哭]?
Redis用于高并发服务的配置
Redis客户端(即golang代码)
Wait:true如果连接池满了,就等待,Redis处理很快的,等个几微秒用户也感觉不出来什么
IdleTimeout:5s一个业务逻辑5s都处理不完,那你应该优化你的代码了。如果设置为0,万一这个连接失踪了服务端就收回不了了,会产生僵尸连接的。
MaxActive:10000相当于这个服务器能处理每秒10000并发了。
Redis服务器(即redis-server)
maxclients要设置得比MaxActive大
附加题:一台服务器的最大文件数怎么算?
linuxkernel-Needto“calculate”optimumulimitandfs.file-maxvaluesaccordingtomyownserverneeds-StackOverflow
thisendsupbeingabout100forevery1MBofram.
例,如果是4G内存,那么打开文件数最大可以设置为:4*1024*100=409600
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。