Как найти узкие места в производительности с помощью Spring Data Redis и локального сервера Redis

Я пытаюсь оптимизировать производительность при получении данных из Redis. В настоящее время сервер работает локально на моем Macbook Pro 2015 года.

Во-первых: объяснение проблемы На данный момент у меня есть только 32 ключа, сохраненных в виде хэшей. 16 из них хранят довольно длинные строки JSON в каждом хеш-значении с ‹300 полей в каждом хеше. Остальные совсем маленькие, так что у меня с ними проблем нет.

Из приложения Spring Boot с использованием шаблона Spring Data Redis с подключением Jedis общее время для извлечения 16 больших хэшей составляет ~ 1700 мс путем конвейерной обработки 4 команд HGETALL 4 раза.

Мой вопрос: как найти настоящие узкие места? Я уже проверил SLOWLOG, который говорит мне, что действия, выполняемые на сервере, выполняются очень быстро, ‹ 1 мс на команду HGETALL, чего и следовало ожидать. Это означает, что узкое место должно быть между приложением Java и сервером Redis. Возможно ли, что задержка является причиной других ~ 1650 мс? (Задержка, похоже, не является проблемой для других меньших хэшей.) Или это может быть десериализация моих строк JSON? Я не уверен, как я могу проверить это, поскольку у меня нет возможности вставлять таймеры в код RedisTemplate.

Ниже приведен код, который я использую для передачи команд HGETALL:

private Map<Date, Map<Integer, Departure>> pipelineMethod(List<String> keys, String keyspace) {

    long pipeTime = System.currentTimeMillis();
    List<Object> results = redisTemplate.executePipelined(
            (RedisCallback) (connection) -> {
                for (String key : keys) {
                    long actionTime = System.currentTimeMillis();
                    connection.hGetAll((keyspace + key).getBytes());
                    System.out.println("HGETALL finished in " + (System.currentTimeMillis()-actionTime) + "ms");
                }

                return null;
            }
    );
    System.out.println("Pipeline finished in " + (System.currentTimeMillis()-pipeTime) + "ms");

    Map<Date, Map<Integer, Departure>> resultMap = new ConcurrentHashMap<>();
    for (int i = 0; i < keys.size(); i++) {
        if (results.get(i) == null) {
            resultMap.put(new Date(Long.parseLong(keys.get(i))), null);
            log.debug("Hash map from redis on " + new Date(Long.parseLong(keys.get(i))) + " was null on retrieval");
        }
        else
            resultMap.put(new Date(Long.parseLong(keys.get(i))), (Map<Integer, Departure>) results.get(i));
    }

    return resultMap;
}

Любые предложения будут ценны.


person fridberg    schedule 13.09.2016    source источник
comment
Хороший подход — начать с самой простой настройки, измерить задержку/пропускную способность и увеличить сложность (= добавить код/функции (с этого момента). Пожалуйста, примите во внимание прогрев/инициализацию. В вашем случае вы можете использовать Jedis напрямую (для теста), затем протестируйте с помощью Spring Data Redis, а затем добавьте демаршалинг JSON.   -  person mp911de    schedule 13.09.2016


Ответы (1)


попробуйте использовать клиент салата с пулом соединений

  private GenericObjectPoolConfig getPoolConfig() {
    GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
    //All below should use the propertysources;
    poolConfig.setMaxTotal(20);
    poolConfig.setMaxIdle(20);
    poolConfig.setMinIdle(0);
    return poolConfig;
  }      
     @Bean
      @Primary
      public RedisConnectionFactory redisConnectionFactory() {
        DefaultLettucePool lettucePool = new DefaultLettucePool(redisHost, Integer.valueOf(redisPort).intValue(), getPoolConfig());
        lettucePool.setPassword(redisPass);
        lettucePool.afterPropertiesSet();
        LettuceConnectionFactory clientConfig = new LettuceConnectionFactory(lettucePool);
        clientConfig.afterPropertiesSet();
        return clientConfig;
      }

      @Bean
      public RedisTemplate<?, ?> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<byte[], byte[]> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);
        return template;
      }
person NagararajaPALLA    schedule 26.06.2018
comment
есть ли причина менять джедаев на салат? - person user1686407; 11.08.2018