Redis 3.0.5
Spring Data Redis 1.3.6
jedis 2.6.3
- Our is web application which receives data from redis over pub/sub.
- Also performs read/write of data on redis as key/value pairs.
- read/write happens on listener thread, independent monitoring thread and http request threads.
- We have used a same connection factory for Listener and redis template
- Our redis server has "timeout=30" configured
<bean id="jedisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="nnnn"></property>
<property name="port" value="nnnn"></property>
<property name="password" value="****"></property>
</bean>
<bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory" />
</bean>
<bean id="redisContainer"
class="org.springframework.data.redis.listener.RedisMessageListenerContainer">
<property name="connectionFactory" ref="jedisConnectionFactory" />
<property name="messageListeners">
<map>
<entry key-ref="messageListener">
<bean class="org.springframework.data.redis.listener.ChannelTopic">
<constructor-arg value="topic_name" />
</bean>
</entry>
</map>
</property>
<property name="taskExecutor" ref="redisTaskExecutor" />
<property name="subscriptionExecutor" ref="redisSubTaskExecutor" />
</bean>
<bean id="redisTaskExecutor"
class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="threadNamePrefix" value="RedisListenerThread"></property>
<property name="corePoolSize" value="1" />
<property name="maxPoolSize" value="1" />
</bean>
<bean id="redisSubTaskExecutor"
class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="threadNamePrefix" value="RedisSubscribeThread"></property>
<property name="corePoolSize" value="1" />
<property name="maxPoolSize" value="1" />
</bean>
<bean id="messageListener"
class="org.springframework.data.redis.listener.adapter.MessageListenerAdapter">
<constructor-arg index="0">
<bean class="my.data.Receiver" />
</constructor-arg>
<constructor-arg index="1"><value>receive</value></constructor-arg>
</bean>
occasionally we face below problem on production during data read.
org.springframework.data.redis.RedisConnectionFailureException: Unexpected end of stream.; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Unexpected end of stream. at org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:47) at org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:36) at org.springframework.data.redis.PassThroughExceptionTranslationStrategy.translate(PassThroughExceptionTranslationStrategy.java:37) at org.springframework.data.redis.FallbackExceptionTranslationStrategy.translate(FallbackExceptionTranslationStrategy.java:37) at org.springframework.data.redis.connection.jedis.JedisConnection.convertJedisAccessException(JedisConnection.java:182) at org.springframework.data.redis.connection.jedis.JedisConnection.get(JedisConnection.java:1087) at org.springframework.data.redis.connection.DefaultStringRedisConnection.get(DefaultStringRedisConnection.java:276) at org.springframework.data.redis.core.DefaultValueOperations$1.inRedis(DefaultValueOperations.java:46) at org.springframework.data.redis.core.AbstractOperations$ValueDeserializingRedisCallback.doInRedis(AbstractOperations.java:50) at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:190) at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:152) at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:84) at org.springframework.data.redis.core.DefaultValueOperations.get(DefaultValueOperations.java:43)
I have read other threads talking of using single thread for read/write. But in our case it is difficult to use single thread. Also as per RedisTemplate documentation, it is thread safe. The problem is occasional and we are unable to reproduce in any of dev/testing/uat environment. Thus unable to find exact cause of the same. What have we done wrong?
3条答案
按热度按时间j2qf4p5b1#
我们 已经 能够 重现 这个 问题 , 原因 是 Redis 中 的 " timeout = 30 " 设置 。
# # 方案
1.连接 空闲 30 秒 , Redis 会 终止 连接 。
1.在 应用 程序 中 的 " Redis 连接 工厂 " 检测 到 断开 的 连接 之前 , 它 会 为 读 或 写 请求 获得 分配
1.代码 尝试 使用 此 连接 , 但 由于 连接 已 断开 , 因此 无法 发送 读/写 命令 。 因此 , 我们 会 得到 " JedisConnectionException :意外 的 流 结尾 " 异常
# # 溶液
1.设置 Redis 超时 为 零
1.使用 自 定义 JedisPoolConfig 将 minEvictableIdleTimeMillis 设置 为 所 需 值 。 这 将 确保 从 Jedis 连接 池 释放 空闲 连接
mzsu5hc02#
对于那些在码头经营Redis的人来说:不要忘记将其绑定到
0.0.0.0
而不是127.0.0.1
sz81bmfz3#
我 发布 这个 答案 只是 为了 知识 的 目的 , 因为 这 是 一 个 可能 的 情况
由于 您 使用 的 是 Pub Sub 机制 , 导致 此 错误 的 一 个 可能 原因 是 应用 程序 的 输入/输出 缓冲 区 超过 了 redis 应用 程序 的 配置 限制
Redis 的 硬 限制 为 32mb , 软 限制 为 8mb , 持续 60 秒 , 所以 通过 改变 配置 , 我们 可以 在 Redis 的 发布 订阅 机制 中 获得 更 大 的 数据 吞吐 量 。
您 只需 更新 以下 键 的 配置 值
客户 端 输出 缓冲 区 限制 pubsub
到 更 大 的 值 。