Проблемы с производительностью Redis/Spring Data Redis
У меня есть проблема с производительностью в моем приложении Spring Boot, когда оно связывается с Redis, и я надеялся, что кто-то, имеющий опыт в этой теме, сможет пролить свет на это.
Объяснение того, что я пытаюсь сделать Короче говоря, в моем приложении у меня есть 2 вложенные карты и 3 карты списков, которые я хочу сохранить в Redis и загрузить обратно в приложение, когда понадобятся данные. Данные в первой вложенной карте довольно большие, с несколькими уровнями непримитивных типов данных (и их списками). На данный момент я структурировал данные в Redis с использованием репозиториев и Redis Hashes, с репозиториями A, B и C и двумя различными способами поиска идентификатора для основного типа данных (MyClass
) в A. B и C содержит данные, на которые ссылаются из значения в A (с @Reference
аннотация).
Анализ производительности Используя JProfiler, я обнаружил, что узкое место находится где-то между моим призывом к a.findOne()
и конец чтения ответа от Redis (перед любым преобразованием из byte[]
в MyClass
состоялось). Я просмотрел медленный журнал на своем сервере Redis, чтобы проверить наличие медленных и блокирующих действий, и не нашел ни одного. каждый HGETALL
Команда в Redis занимает в среднем 400 мкс (для полного хэша в A, включая поиск ссылочных хэшей в B и C). То, что кажется мне странным, это то, что время a.findOne()
вызов занимает от 5-20 мс для одного экземпляра MyClass
в зависимости от того, насколько велики хэши в B и C. Один экземпляр имеет в среднем ~2500 хеш-полей, если включены ссылки на B и C. Когда это делается ~900 раз для первой вложенной карты, мне приходится ждать 10 секунд, чтобы получить все мои данные, что слишком долго. Для сравнения, другая вложенная вложенная карта, которая не имеет ссылок на C (большая часть данных), рассчитана на ~10 мкс в Redis и <1 мс в Java.
Кажется ли этот анализ нормальным поведением, когда экземпляр Redis запускается локально на том же MacBook Pro 2015 года, что и приложение Spring Boot? Я понимаю, что это займет больше времени для полного findOne()
способ закончить, чем фактический HGETALL
Команда в Redis, но я не понимаю, почему разница такая большая. Если бы кто-нибудь мог пролить свет на производительность всего, что происходит в коде соединения Jedis, я был бы признателен.
Примеры моей структуры данных в Java
@RedisHash("myClass")
public class MyClass {
@Id
private String id;
private Date date;
private Integer someValue;
@Reference
private Set<C> cs;
private someClass someObject;
private int somePrimitive;
private anotherClass anotherObject;
@Reference
private B b;
Отрывок класса C (несколько примитивов удалены для ясности):
@RedisHash("c")
public class C implements Comparable<BasketValue>, Serializable {
@Id
private String id;
private EnumClass someEnum;
private aClass anObject;
private int aNumber;
private int anotherNumber;
private Date someDate;
private List<CounterClass> counterObjects;
Выдержка из класса B:
@RedisHash("b")
public class B implements Serializable {
@Id
private int code;
private String productCodes;
private List<ListClass> listObject;
private yetAnotherClass yetAnotherObject;
private Integer someInteger;