Redis, Jedis пул соединений, инструменты оптимизации и мониторинга - PullRequest
1 голос
/ 13 февраля 2020

Я новичок в Redis, Jedis. Сегодня я увидел ошибку в моем журнале

Caused by: redis.clients.jedis.exceptions.JedisExhaustedPoolException: redis.clients.jedis.exceptions.JedisExhaustedPoolException: Could not get a resource since the pool is exhausted
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:1.8.0_191]
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[?:1.8.0_191]
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[?:1.8.0_191]
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[?:1.8.0_191]
        at java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:593) ~[?:1.8.0_191]
        at java.util.concurrent.ForkJoinTask.reportException(ForkJoinTask.java:677) ~[?:1.8.0_191]
        at java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:735) ~[?:1.8.0_191]
        at java.util.stream.ForEachOps$ForEachOp.evaluateParallel(ForEachOps.java:160) ~[?:1.8.0_191]
        at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateParallel(ForEachOps.java:174) ~[?:1.8.0_191]
        at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233) ~[?:1.8.0_191]
        at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418) ~[?:1.8.0_191]
        at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:583) ~[?:1.8.0_191]
        at com.nokia.snmpapp.VariableDataUtils.processSnmpDataByOP(VariableDataUtils.java:372) ~[snmpapp.jar:?]
       at com.nokia.snmpapp.consumerservice.DocsisQos3MibData.processDocsQos3ParamSetTableObjectEvent(DocsisQos3MibData.java:172) ~[snmpapp.jar:?]
        at com.nokia.snmpapp.KafkaConsumer.onSnmpappDocsQos3ParamSetTableObjectEvent(KafkaConsumer.java:315) ~[snmpapp.jar:?]
        ... 16 more 

Caused by: redis.clients.jedis.exceptions.JedisExhaustedPoolException: Could not get a resource since the pool is exhausted
            at redis.clients.jedis.util.Pool.getResource(Pool.java:53) ~[snmpapp.jar:?]
            at redis.clients.jedis.JedisPool.getResource(JedisPool.java:234) ~[snmpapp.jar:?]
            at com.nokia.snmpapp.RedisUtils.add2list(RedisUtils.java:27) ~[snmpapp.jar:?]
            at com.nokia.snmpapp.VariableDataUtils.lambda$processSnmpDataByOP$5(VariableDataUtils.java:379) ~[snmpapp.jar:?]
            at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184) ~[?:1.8.0_191]
            at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382) ~[?:1.8.0_191]
            at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) ~[?:1.8.0_191]
            at java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:291) ~[?:1.8.0_191]
            at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731) ~[?:1.8.0_191]
            at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289) ~[?:1.8.0_191]
            at java.util.concurrent.ForkJoinPool$WorkQueue.execLocalTasks(ForkJoinPool.java:1040) ~[?:1.8.0_191]
            at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1058) ~[?:1.8.0_191]
            at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692) ~[?:1.8.0_191]
            at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157) ~[?:1.8.0_191]  

Caused by: java.util.NoSuchElementException: Timeout waiting for idle object               
           at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:439) ~[snmpapp.jar:?]
           at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:349) ~[snmpapp.jar:?]
           at redis.clients.jedis.util.Pool.getResource(Pool.java:50) ~[snmpapp.jar:?]
           at redis.clients.jedis.JedisPool.getResource(JedisPool.java:234) ~[snmpapp.jar:?]
           at com.nokia.snmpapp.RedisUtils.add2list(RedisUtils.java:27) ~[snmpapp.jar:?]
           at com.nokia.snmpapp.VariableDataUtils.lambda$processSnmpDataByOP$5(VariableDataUtils.java:379) ~[snmpapp.jar:?]
           at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184) ~[?:1.8.0_191]
           at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382) ~[?:1.8.0_191]
           at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) ~[?:1.8.0_191]
           at java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:291) ~[?:1.8.0_191]
           at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731) ~[?:1.8.0_191]
           at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289) ~[?:1.8.0_191]
           at java.util.concurrent.ForkJoinPool$WorkQueue.execLocalTasks(ForkJoinPool.java:1040) ~[?:1.8.0_191]
           at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1058) ~[?:1.8.0_191]
           at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692) ~[?:1.8.0_191]
           at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157) ~[?:1.8.0_191]

Моя текущая конфигурация

  maxTotal: 10
  maxIdle: 5
  minIdle: 1
  maxWaitMillis: 2000

Я знаю, что могу увеличить размер пула соединений, чтобы устранить сообщение об ошибке. Тем не менее, я хотел бы немного больше понять использование ресурса, прежде чем определить правильное число для моей среды. Я был в Google об этом, но я не могу найти много разговоров об инструменте мониторинга или о том, как контролировать производительность и использование пула. Означает ли это, что нет инструментов для мониторинга? Если нет способа отслеживать использование пула соединений, что я могу сделать, чтобы получить лучшее представление о том, что оптимизировать в соединении Redis?

Заранее спасибо

1 Ответ

1 голос
/ 20 февраля 2020

Мониторинг пула Jedis с помощью JMX MBeans

Пул Jedis основан на Apache Generi c -Pool API, так что вы можете использовать JMX для мониторинга состояния вашего пула подключений ,

Например, запустите ваше приложение с включенным JMX:

-Dcom.sun.management.jmxremote.port=9999 
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.ssl=false

Затем соединитесь с JConsole или любым другим JMX-совместимым инструментом:

  1. Подключитесь к вашему приложению / процесс
  2. Go в MBeans
  3. Go в org.apache.commons.pool2.GenericObjectPool.pool MBeans

Вы сможете отслеживать, что происходит с вашим приложением / JedisPool .

У вас есть много инструментов мониторинга, совместимых с JMX, которые позволяют вам ставить оповещения на основе порога


Размеры и конфигурация

Конфигурация вашего пула на самом деле определяется приложением c, и для настройки свойства maxTotal, то есть максимального количества подключений, которое вы должны посмотреть:

  • сколько одновременных подключений нужны вашим службам
  • сколько времени занимает каждый вызов для выполнения команд, которые вы отправляете

И вы должны быть уверены, что не перегружаете свою систему (на стороне клиента и на сервере) сторона.)


JedisPool: Обязательно освободите соединение;)

Кроме того, речь идет не о мониторинге, а о передовой практике:

  • делает ваше приложение выпущенным подключение к пулу после каждого использования?
/// Jedis implements Closeable. Hence, the jedis instance will be auto-closed after the last statement.
try (Jedis jedis = pool.getResource()) {

   // use your jedis
  jedis.set("foo", "bar");

} // the resource will be released back to the pool

Если вы не используете попытку с ресурсом, вы должны закрыть соединение (вернуть его в пул)

Jedis jedis = null;
try {
  jedis = pool.getResource();
  // work with Redis
  jedis.set("foo", "bar");
} finally {
  // you must close the connection to put it back to the pool
  if (jedis != null) {
    jedis.close();
  }
}

Также при закрытии приложения :

 pool.close()
...