2015-05-21 9 views
1

Я пытаюсь использовать sentinal redis для получения/установки ключей из redis. Я пытался подчеркнуть тест моей установки примерно с 2000 одновременными запросами.Jedis getResource() занимает много времени

Я использовал дозорный, чтобы поместить один ключ на redis, а затем я выполнил 1000 одновременных запросов на получение от redis.

Но базовый jedis, используемый моим часовым, блокирует вызов getResource() (размер пула - 500), а общее среднее время отклика, которое я достигаю, составляет около 500 мс, но моя цель составляла около 10 мс.

Я прилагаю образец jvisualvm снимка здесь

redis.clients.jedis.JedisSentinelPool.getResource() 98.02227 4.0845232601E7 ms 4779 
redis.clients.jedis.BinaryJedis.get() 1.6894469 703981.381 ms 141 
org.apache.catalina.core.ApplicationFilterChain.doFilter() 0.12820946 53424.035 ms 6875 
org.springframework.core.serializer.support.DeserializingConverter.convert() 0.046286926 19287.457 ms 4 
redis.clients.jedis.JedisSentinelPool.returnResource() 0.04444578 18520.263 ms 4 
org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept() 0.035538 14808.45 ms 11430 

кто угодно может помочь в дальнейшем отлаживать в вопросе?

ответ

1

От реализации JedisSentinelPool из getResource() из источников Jedis (2.6.2): ​​

@Override 
public Jedis getResource() { 
    while (true) { 
     Jedis jedis = super.getResource(); 
     jedis.setDataSource(this); 

     // get a reference because it can change concurrently 
     final HostAndPort master = currentHostMaster; 
     final HostAndPort connection = new HostAndPort(jedis.getClient().getHost(), jedis.getClient() 
      .getPort()); 

     if (master.equals(connection)) { 
     // connected to the correct master 
     return jedis; 
     } else { 
     returnBrokenResource(jedis); 
     } 
    } 
} 

Обратите внимание на while(true) и returnBrokenResource(jedis), это означает, что он пытается получить Jedis ресурс случайным образом из пула, действительно подключен к правильному хозяину и повторяет попытку, если он не является хорошим. Это грязная проверка, а также блокирующий вызов.

Звонок super.getResource() относится к традиционной реализации JedisPool, которая фактически основана на Apache Commons Pool (2.0). Он многое делает для того, чтобы получить объект из пула, и я думаю, что он даже ремонтирует соединения сбоя, например. С большим разногласием в вашем бассейне, как, вероятно, в вашем стресс-тесте, возможно, потребуется много времени, чтобы получить ресурс из пула, просто чтобы убедиться, что он не подключен к правильному хозяину, поэтому вы в конечном итоге вызываете его опять же, добавление разногласий, замедление получения ресурса и т. д.

Вы должны проверить все экземпляры jedis в своем пуле, чтобы узнать, существует ли множество «плохих» подключений.

Возможно, вам стоит отказаться от использования общего пула для стресс-теста (только создайте экземпляры Jedis вручную, подключенные к правильному узлу, и закройте их красиво) или установите несколько из них, чтобы уменьшить стоимость поиска «грязных» непроверенных Ресурсы jedis.

Также с пулом из 500 экземпляров jedis вы не можете эмулировать 1000 одновременных запросов, вам нужно как минимум 1000.