背景描述:
(1) 某项目,使用redis作存储,用redis的set性质来作实时统计,同时也存放其余统计数据;
(2) 用到的key很多,value集合量较多;
(3) 天天零点的时候,回清理当前redis中全部的数据;
(4) 异常都出如今 零点清理以后;java
异常现场:
2018/03/13 00:00:20 OSS INFO [com.xxx.RedisDAO] - error
redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out
at redis.clients.util.RedisInputStream.ensureFill(RedisInputStream.java:202)
at redis.clients.util.RedisInputStream.readByte(RedisInputStream.java:40)
at redis.clients.jedis.Protocol.process(Protocol.java:151)
at redis.clients.jedis.Protocol.read(Protocol.java:215)
at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:340)
at redis.clients.jedis.Connection.getIntegerReply(Connection.java:265)
at redis.clients.jedis.Jedis.sadd(Jedis.java:1109)
at com.xxx.RedisDAO.setXXXKPI(RedisDAO.java:66)
at com.xxx.xxxRunnable.run(xxxRunnable.java:69)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:171)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at java.net.SocketInputStream.read(SocketInputStream.java:127)
at redis.clients.util.RedisInputStream.ensureFill(RedisInputStream.java:196)
... 9 more
2018/03/13 00:00:20 OSS INFO [com.xxx.RedisDAO] - error
java.lang.ClassCastException: java.lang.Long cannot be cast to [B
at redis.clients.jedis.Connection.getStatusCodeReply(Connection.java:239)
at redis.clients.jedis.Jedis.set(Jedis.java:121)
at com.xxx.RedisDAO.setXXXXXKPI(RedisDAO.java:100)
at com.xxx.xxxRunnable.run(xxxRunnable.java:70)
at java.lang.Thread.run(Thread.java:745)
2018/03/13 00:00:20 OSS INFO [com.xxx.RedisDAO] - error
java.lang.ClassCastException: [B cannot be cast to java.lang.Long
at redis.clients.jedis.Connection.getIntegerReply(Connection.java:265)
at redis.clients.jedis.Jedis.sadd(Jedis.java:1109)
at com.xxx.RedisDAO.setXXXXXKPI(RedisDAO.java:167)
at com.xxx.xxxRunnable.run(xxxRunnable.java:71)
at java.lang.Thread.run(Thread.java:745)git
(1) 若当前redis中的数据不少,FLUSHDB 操做,须要花费必定的时间,阻塞了redis的响应,因而先出现了SocketTimeoutException;
(2) 链接出现异常后,从日志看,接着出现了ClassCastException,且后续一直报这个异常错误;
(3) 经搜索查询, 找到以下两个网页:
ClassCastException - [B cannot be cast to java.lang.Long #186:
https://github.com/xetorthio/jedis/issues/186github
Jedis使用过程当中踩过的那些坑:
http://bert82503.iteye.com/blog/2184225redis
综上, 查项目代码,发现几处问题:
a. redis链接操做出现异常后,应该关闭close, 归还资源,从新去一个redis链接使用。程序写的是:出了异常,记录日志,接着用这个redis链接,一直出异常。
b. 链接池设置过大,重启项目的时候,本次初始化的加上以前未释放的链接(直接kill的进程,关闭时未释放),瞬间连接过大;
c. 程序设计不合理, 因为数据天天是实时统计展现,能够天天的key前缀不同,设置key的过时时间,这样就不用天天FLUSHDB。socket