Home  >  Article  >  Database  >  redis的一个诡异问题排查

redis的一个诡异问题排查

不言
不言Original
2018-05-26 09:47:462358browse

前段时间,由于线上redis服务器的内存使用率达到了机器总内存的50%以上,导致内存数据的dump持久化一直失败。扩展到多台redis后,应用系统访问redis时, 在业务量较少时,时不时会出现以下异常,当业务量较大,redis访问频率很高时,却不会发生这个异常 ,一

前段时间,由于线上redis服务器的内存使用率达到了机器总内存的50%以上,导致内存数据的dump持久化一直失败。扩展到多台redis后,应用系统访问redis时,在业务量较少时,时不时会出现以下异常,当业务量较大,redis访问频率很高时,却不会发生这个异常,一时觉得很诡异。

redis.clients.jedis.exceptions.JedisConnectionException:?It?seems?like?server?has?closed?the?connection.
at?redis.clients.util.RedisInputStream.readLine(RedisInputStream.java:90)?~[jedis-2.1.0.jar:na]
at?redis.clients.jedis.Protocol.processInteger(Protocol.java:110)?~[jedis-2.1.0.jar:na]
at?redis.clients.jedis.Protocol.process(Protocol.java:70)?~[jedis-2.1.0.jar:na]
at?redis.clients.jedis.Protocol.read(Protocol.java:131)?~[jedis-2.1.0.jar:na]
at?redis.clients.jedis.Connection.getIntegerReply(Connection.java:188)?~[jedis-2.1.0.jar:na]
at?redis.clients.jedis.Jedis.sismember(Jedis.java:1266)?~[jedis-2.1.0.jar:na]

看提示,应该是服务端主动关闭了连接。查看了新上线的redis服务器的配置,有这么一项:

# Close the connection after a client is idle for N seconds (0 to disable)
timeout 120

这项配置指的是客户端连接空闲超过多少秒后,服务端主动关闭连接,默认值0表示服务端永远不主动关闭。而op人员把服务器端的超时时间设置为了120秒。这就解释了发生这个异常的原因。客户端使用了一个连接池管理访问redis的所有连接,这些连接是长连接,当业务量较小时,客户端部分连接使用率较低,当两次使用之间的间隔超过120秒时,redis服务端就主动关闭了这个连接,而等客户端下次再使用这个连接对象时,发现服务端已经关闭了连接,进而报错。

解决方案有两种:

1. 在redis-cli下直接修改redis 的配置,把timeout改回为0,无需重启redis即可直接生效。

2. 修改应用系统代码,设置连接的最大空闲时长(超出此时长将断开空闲连接)小于120秒。

出于改动成本考虑,采用了第一种方案,修改后,报错不再出现。

这里有一个问题,为何服务器端主动关闭空闲连接后,客户端没有报错呢,系统依赖的是jedis-2.1.0,这块需要细看下jedis连接池那块的实现,jedis连接池主要是基于commons-pool写的,下来再研究研究,写一篇文章总结一下。

(本文已被阅读18次)

redis的一个诡异问题排查前段时间,由于线上redis服务器的内存使用率达到了机器总内存的50%以上,导致内存数据的dump持久化一直失败。扩展到多台redis后,应用系统访问redis时,在业务量较少时,时不时会出现以下异常,当业务量较大,redis访问频率很高时,却不会发生这个异常,一时觉得很诡异。 redis.clients.jedis.exceptions.JedisConnectionException:?It?seems?like?server?has?closed?the?connection. at?redis.clients.util.RedisInputStream.readLine(RedisInputStream.java:90)?~[jedis-2.1.0.jar:na] at?redis.clients.jedis.Protocol.processInteger(Protocol.java:110)?~[jedis-2.1.0.jar:na] at?redis.clients.jedis.Protocol.process(Protocol.java:70)?~[jedis-2.1.0.jar:na] at?redis.clients.jedis.Protocol.read(Protocol.java:131)?~[jedis-2.1.0.jar:na] at?redis.clients.jedis.Connection.getIntegerReply(Connection.java:188)?~[jedis-2.1.0.jar:na] at?redis.clients.jedis.Jedis.sismember(Jedis.java:1266)?~[jedis-2.1.0.jar:na] 看提示,应该是服务端主动关闭了连接。查看了新上线的redis服务器的配置,有这么一项: # Close the connection after a client is idle for N seconds (0 to disable) timeout 120 这项配置指的是客户端连接空闲超过多少秒后,服务端主动关闭连接,默认值0表示服务端永远不主动关闭。而op人员把服务器端的超时时间设置为了120秒。这就解释了发生这个异常的原因。客户端使用了一个连接池管理访问redis的所有连接,这些连接是长连接,当业务量较小时,客户端部分连接使用率较低,当两次使用之间的间隔超过120秒时,redis服务端就主动关闭了这个连接,而等客户端下次再使用这个连接对象时,发现服务端已经关闭了连接,进而报错。 解决方案有两种: 1. 在redis-cli下直接修改redis 的配置,把timeout改回为0,无需重启redis即可直接生效。 2. 修改应用系统代码,设置连接的最大空闲时长(超出此时长将断开空闲连接)小于120秒。 出于改动成本考虑,采用了第一种方案,修改后,报错不再出现。 这里有一个问题,为何服务器端主动关闭空闲连接后,客户端没有报错呢,系统依赖的是jedis-2.1.0,这块需要细看下jedis连接池那块的实现,jedis连接池主要是基于commons-pool写的,下来再研究研究,写一篇文章总结一下。 (本文已被阅读18次)redis的一个诡异问题排查

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Previous article:Redis Conf live streamingNext article:Muse CC