Кэш по ширине и высоте фото: сколько там реально записей

В ревью дали сервис, который кэширует отмасштабированные фото по ключу из ширины и высоты через @Cacheable. На вопрос "сколько записей окажется в кэше, если перебрать width и height от 1 до 5000" почти все называют число наугад, не прочитав сигнатуру ключа.

Если ключ строится как простая конкатенация width + "x" + height, то переберите оба измерения независимо — это декартово произведение, 5000 умножить на 5000, 25 миллионов записей. На дефолтном Caffeine или ConcurrentMapCache без ограничения размера это упадёт в OOM раньше, чем вы долистаете логи.

@Cacheable(value = "thumbnails", key = "#width + 'x' + #height") public byte[] resize(int width, int height) { // ... }

Два отдельных вопроса возникают дальше. Через что вообще работает @Cacheable — это прокси, построенный Spring AOP, и если сервис — final-класс, динамический прокси через CGLIB создать нельзя, приложение падает на старте. Второй вопрос — как протестировать такой сервис без поднятия Spring-контекста: создать его обычным new и вызвать метод напрямую, кэширование в таком тесте просто не сработает, потому что оно живёт в прокси, а не в самом объекте.

Ловушка ревью: без ограничения maximumSize или TTL в конфиге кэша неограниченный рост по комбинациям параметров — вопрос времени, а не вероятности. Для width/height это особенно легко проглядеть, потому что в локальных тестах диапазон значений маленький.

Ключ кэша нужно читать так же внимательно, как SQL-запрос — за безобидной строкой часто прячется декартово произведение.

senior·base — что спрашивают на самом деле


В этом посте были ссылки, но мы их удалили по правилам Сетки