Я пытаюсь оптимизировать производительность при получении данных из 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;
}
Любые предложения будут ценны.