Пул соединений Spring-data-redis не работает, как я ожидаю

Это мое первое приложение, использующее spring-data-redis, и я думаю, что хорошо понимаю концепции (в прошлом я много раз использовал JdbcTemplate с RDBMS-es). Вот что происходит...

Проблема, с которой я сталкиваюсь, заключается в том, что каждый раз, когда я выполняю операцию get(key) (используя объект ValueOperations), соединение открывается и закрывается, что вызывает задержку примерно в 1/10 секунды (это серверный код, поэтому 1/10 секунды — это существенно). Вот конфигурация Spring XML:

<!-- Redis DAO stuff -->
<bean
    id="jedisPoolConfig"
    class="redis.clients.jedis.JedisPoolConfig"
    p:testOnBorrow="true"
    p:testOnReturn="true"
    p:timeBetweenEvictionRunsMillis="60000"
    p:minIdle="2"
    p:maxTotal="30"
    p:maxIdle="10"
  />

<bean id="jedisConnectionFactory"
    class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
    p:host-name="${redis.url}"
    p:port="${redis.port}"
    p:database="0"
    p:use-pool="true"
    p:pool-config-ref="jedisPoolConfig"
/>

<bean id="stringRedisSerializer"
    class="org.springframework.data.redis.serializer.StringRedisSerializer"
/>

<bean id="redisTemplate"
    class="org.springframework.data.redis.core.RedisTemplate" 
    p:connection-factory-ref="jedisConnectionFactory"
    p:defaultSerializer-ref="stringRedisSerializer"
/>

и вот соответствующий код Java:

@Autowired
private RedisTemplate<String, String> template;
private ValueOperations<String, String> valOps;

@PostConstruct
public void init() {
    logger.debug("111111111111111111111111aaaaaaaaaaaaaaaaaaaaaaa");
    valOps = template.opsForValue();
}

public String getTestVal() {
    logger.debug("getTestVal() function called++++++++++++++++++++");
    Object testVal2 = valOps.get("akey");
    testVal2 = valOps.get("akey");
    testVal2 = valOps.get("akey");
    testVal2 = valOps.get("akey");
    testVal2 = valOps.get("akey");
    testVal2 = valOps.get("akey");

    logger.debug("TestVal2 returned from REdis: " + testVal2);

    return null;
}

Таким образом, значение одного и того же ключа извлекается шесть раз. Вывод журнала, который я вижу, выглядит следующим образом:

13:46:37.011 [http-nio-8080-exec-1] DEBUG com.arrow.pricing.dao.RedisDAO - getTestVal() function called++++++++++++++++++++
13:46:37.014 [http-nio-8080-exec-1] DEBUG o.s.d.r.core.RedisConnectionUtils - Opening RedisConnection
13:46:37.344 [http-nio-8080-exec-1] DEBUG o.s.d.r.core.RedisConnectionUtils - Closing Redis Connection
13:46:37.416 [http-nio-8080-exec-1] DEBUG o.s.d.r.core.RedisConnectionUtils - Opening RedisConnection
13:46:37.543 [http-nio-8080-exec-1] DEBUG o.s.d.r.core.RedisConnectionUtils - Closing Redis Connection
13:46:37.616 [http-nio-8080-exec-1] DEBUG o.s.d.r.core.RedisConnectionUtils - Opening RedisConnection
13:46:37.742 [http-nio-8080-exec-1] DEBUG o.s.d.r.core.RedisConnectionUtils - Closing Redis Connection
13:46:37.812 [http-nio-8080-exec-1] DEBUG o.s.d.r.core.RedisConnectionUtils - Opening RedisConnection
13:46:37.940 [http-nio-8080-exec-1] DEBUG o.s.d.r.core.RedisConnectionUtils - Closing Redis Connection
13:46:38.003 [http-nio-8080-exec-1] DEBUG o.s.d.r.core.RedisConnectionUtils - Opening RedisConnection
13:46:38.128 [http-nio-8080-exec-1] DEBUG o.s.d.r.core.RedisConnectionUtils - Closing Redis Connection
13:46:38.201 [http-nio-8080-exec-1] DEBUG o.s.d.r.core.RedisConnectionUtils - Opening RedisConnection
13:46:38.337 [http-nio-8080-exec-1] DEBUG o.s.d.r.core.RedisConnectionUtils - Closing Redis Connection
13:46:38.414 [http-nio-8080-exec-1] DEBUG com.arrow.pricing.dao.RedisDAO -  TestVal2 returned from REdis: yo mama

Я думал, что следил за документацией по настройке пула соединений, но при работе с ориентированной на производительность платформой, такой как Redis, я не ожидал такой задержки.

Заранее спасибо за любую помощь или подсказки.


person Jeff Orford    schedule 04.03.2016    source источник
comment
Те, кто открывает и закрывает журналы подключений, будут регистрироваться как в сценариях с пулом, так и без пула. Попробуйте прекратить проверку соединения, удалив testOn* конфиги   -  person Ali Dehghani    schedule 05.03.2016
comment
Спасибо за ваш ответ @AliDehghani. Боюсь, я все еще получаю ту же задержку.   -  person Jeff Orford    schedule 05.03.2016
comment
Посмотрите на RedisAutoConfiguration из весенней загрузки, это может вам помочь   -  person Ali Dehghani    schedule 05.03.2016
comment
вообще говоря, вывод отладки, который вы видите, дает только информацию о полученном и освобожденном соединении. Я должен признать, что название должно лучше отражать это. Базовые ConnectionFactory и RedisConnection тем не менее будут использовать предоставленный пул. Пожалуйста, проверьте соединения на сервере, чтобы убедиться, что соединения открыты. Не стесняйтесь сообщать о проблеме в JIRA.   -  person Christoph Strobl    schedule 07.03.2016
comment
@ChristophStrobl спасибо за ваш ответ. После дополнительных исследований я собираюсь последовать совету Дональда Кнута и оптимизировать производительность в последнюю очередь :-)   -  person Jeff Orford    schedule 08.03.2016
comment
Есть ли открытая jira для этой проблемы? Или есть какие-либо предложения/обходной путь?   -  person EmeraldTablet    schedule 05.07.2017


Ответы (1)


На основе spring-data-redis-1.7.2.RELEASE

if(!isConnectionTransactional(conn, factory)) {
    if (log.isDebugEnabled()) {
        log.debug("Closing Redis Connection");
    }
    conn.close()
}

В журнале вы можете увидеть «Закрытие соединения Redis» в строке 205, а затем соединение закрывается вызовом метода close.

Мы можем обнаружить, что conn реализует RedisConnection. В данном случае фактическим классом, который мы использовали, является JedisConnection.

см. код, начинающийся со строки 256.

public void close() throws DataAccessExeception {
    super.close();
    // return the connection to the pool
    if (pool != null) {
        ...balabala 
    }
}

Соединение возвращается к пулу. Теперь мы знаем, что RedisConnectionUtils всегда показывает журнал «Закрытие соединения Redis», даже если используется пул.

person Zurex    schedule 12.09.2017