Исключения сломанных каналов от клиента Redis Jedis

У нас есть вызовы клиента Redis из приложения Play Framework. Эти вызовы Redis выполняются от Актера с использованием Akka Schedular. Этот планировщик запускается каждые 60 секунд, что делает вызовы Redis вместе с другими вызовами JDBC. После того, как планировщик проработал несколько минут, мы начинаем видеть в файлах журнала, и приложение перестает отвечать на любые вызовы клиента Redis. Это моя первая встреча с Redis, поэтому любые указатели, помощь приветствуются.

redis.host = localhost

redis.port = 6379

redis.timeout = 10

redis.pool.maxActive =110

redis.pool.maxIdle = 50

redis.pool.maxWait = 3000

redis.pool.testOnBorrow = true

redis.pool.testOnReturn = true

redis.pool.testWhileIdle = true

redis.pool.timeBetweenEvictionRunsMillis = 60000

redis.pool.numTestsPerEvictionRun = 10

Exception details:

redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketException: Broken pipe
    at redis.clients.jedis.Connection.flush(Connection.java:69) ~[redis.clients.jedis-2.3.0.jar:na]
    at redis.clients.jedis.JedisPubSub.subscribe(JedisPubSub.java:58) ~[redis.clients.jedis-2.3.0.jar:na]
............    
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:498) [com.typesafe.akka.akka-actor_2.10-2.2.0.jar:2.2.0]
    at akka.actor.ActorCell.invoke(ActorCell.scala:456) [com.typesafe.akka.akka-actor_2.10-2.2.0.jar:2.2.0]
    at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:237) [com.typesafe.akka.akka-actor_2.10-2.2.0.jar:2.2.0]
    at akka.dispatch.Mailbox.run(Mailbox.scala:219) [com.typesafe.akka.akka-actor_2.10-2.2.0.jar:2.2.0]
    at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:386) [com.typesafe.akka.akka-actor_2.10-2.2.0.jar:2.2.0]
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) [org.scala-lang.scala-library-2.10.3.jar:na]
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) [org.scala-lang.scala-library-2.10.3.jar:na]
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) [org.scala-lang.scala-library-2.10.3.jar:na]
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) [org.scala-lang.scala-library-2.10.3.jar:na]
Caused by: java.net.SocketException: Broken pipe
    at java.net.SocketOutputStream.socketWrite0(Native Method) ~[na:1.7.0_51]
    at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:113) ~[na:1.7.0_51]
    at java.net.SocketOutputStream.write(SocketOutputStream.java:159) ~[na:1.7.0_51]
    at redis.clients.util.RedisOutputStream.flushBuffer(RedisOutputStream.java:31) ~[redis.clients.jedis-2.3.0.jar:na]
    at redis.clients.util.RedisOutputStream.flush(RedisOutputStream.java:223) ~[redis.clients.jedis-2.3.0.jar:na]
    at redis.clients.jedis.Connection.flush(Connection.java:67) ~[redis.clients.jedis-2.3.0.jar:na]
    ... 15 common frames omitted

person user2066049    schedule 06.03.2014    source источник


Ответы (2)


Проблема заключается в тайм-ауте и в том, что клиент, который вы использовали для подписки, истек по тайм-ауту / получил DC ed.

person user3182350    schedule 06.03.2014
comment
ну, раньше настройка тайм-аута была 0. Разве установка 0 не означает, что время ожидания никогда не истекает? Я думал, что ошибки были связаны с настройкой тайм-аута 0, которую мы изменили на 10 секунд (как в файле конфигурации клиента Redis, так и на сервере Redis), но эти ошибки сохраняются и приводят к остановке сервера. - person user2066049; 06.03.2014
comment
Jedis принимает тайм-ауты как миллисекунды, а не секунды, поэтому вам может потребоваться изменить это. - person user3182350; 06.03.2014
comment
В этом документе указано, что тайм-аут указан в секундах: download.redis.io/redis-stable/redis. конф . не правда? - person user2066049; 06.03.2014
comment
это тайм-аут, который вы установили через redis.conf, он действительно в секундах. Но, наоборот, ваш конструктор Jedis должен занимать миллисекунды, поэтому введите new Jedis (localhost, 6379, 10000) на 10 секунд. - person user3182350; 06.03.2014

Недавно я столкнулся с аналогичной проблемой с Redis, и проблема заключалась в том, что я не возвращал ресурс Jedis после подписки, поэтому соединения пропадали, и приложение не отвечало после нескольких подключений. Так что не забывайте возвращать ресурс jedis после того, что вы делаете:

Jedis j = play.Play.application().plugin(RedisPlugin.class).jedisPool().getResource();
j.subscribe(listener, redisChannel);
play.Play.application().plugin(RedisPlugin.class).jedisPool().returnResource(j);
person Ömer Faruk Gül    schedule 07.03.2014