Какой провайдер кэширования использовался в вашем последнем проекте и почему?

Ответ

В последнем проекте использовался Caffeine в качестве провайдера кэша для Spring Cache Abstraction.

Причины выбора Caffeine:

  • Высокая производительность: Оптимизированная реализация на основе ConcurrentHashMap, часто превосходит Ehcache и Guava Cache.
  • Гибкая политика вытеснения: Поддержка размера, времени жизни (TTL/TTI), весов записей.
  • Асинхронное обновление: Возможность автоматической перезагрузки значений по истечении срока действия.
  • Статистика: Встроенный сбор метрик (hit rate, load time).
  • Современный и активно поддерживаемый.

Пример конфигурации в Spring Boot:

@Configuration
@EnableCaching
public class CacheConfig {

    @Bean
    public CacheManager cacheManager() {
        CaffeineCacheManager cacheManager = new CaffeineCacheManager();
        // Глобальная конфигурация по умолчанию
        cacheManager.setCaffeine(Caffeine.newBuilder()
                .expireAfterWrite(10, TimeUnit.MINUTES) // Запись устаревает через 10 мин
                .maximumSize(1000)                     // Макс. 1000 записей в кэше
                .recordStats());                       // Включение сбора статистики
        return cacheManager;
    }
}

// Использование в сервисе
@Service
public class ProductService {
    @Cacheable(cacheNames = "products", key = "#id")
    public Product getProductById(Long id) {
        // Дорогой вызов в БД выполняется только при промахе кэша
        return productRepository.findById(id).orElseThrow();
    }

    @CacheEvict(cacheNames = "products", key = "#product.id")
    public Product updateProduct(Product product) {
        // При обновлении запись инвалидируется
        return productRepository.save(product);
    }
}

Альтернативы и когда их использовать:

  • Ehcache 3/ JCache (JSR-107): Для сложных распределенных или многоуровневых кэшей.
  • Redis: Для распределенного кэширования между несколькими экземплярами приложения.
  • Simple (Spring по умолчанию): Только для простых сценариев, без production-готовых политик.

Ответ 18+ 🔞

Да ты посмотри, какие у нас тут технологические изыски пошли! В прошлом проекте мы, мать его, Caffeine впаяли как провайдера для кэширования в Spring. Ну, знаешь, эта абстракция ихняя, Cache Abstraction.

А че его выбрали, спросишь? Да я те щас разложу, как божий день.

Почему Caffeine, а не что-то другое?

  • Скорость, блядь, огонь! Он там на ConcurrentHashMap заточен, оптимизированный весь. Часто так бывает, что Ehcache с Guava Cache он по перформансу делает, как божий одуванчик.
  • Выкидывать записи можно по-разному: По размеру, по времени жизни (TTL, TTI), по весу — чего душа пожелает, сука.
  • Может сам обновляться асинхронно, то есть значение протухло — он пошел на заднем плане новое доставать, красота!
  • Статистику пишет, как заправский бухгалтер: hit rate, load time — все к твоим услугам.
  • Современный, живой, его не бросили на произвол судьбы, поддерживают.

Вот, смотри, как в Spring Boot это выглядит, чтоб ты вжух и понял:

@Configuration
@EnableCaching
public class CacheConfig {

    @Bean
    public CacheManager cacheManager() {
        CaffeineCacheManager cacheManager = new CaffeineCacheManager();
        // Настройки, которые для всех кэшей по умолчанию
        cacheManager.setCaffeine(Caffeine.newBuilder()
                .expireAfterWrite(10, TimeUnit.MINUTES) // Через 10 минут — в утиль
                .maximumSize(1000)                     // Больше тысячи записей — начинаем выпихивать старые
                .recordStats());                       // Включил подсчёт статистики, пусть работает
        return cacheManager;
    }
}

// А вот как этим в сервисе пользоваться
@Service
public class ProductService {
    @Cacheable(cacheNames = "products", key = "#id")
    public Product getProductById(Long id) {
        // Эта поездка в базу, которая почку стоит, случится ТОЛЬКО если в кэше пусто
        return productRepository.findById(id).orElseThrow();
    }

    @CacheEvict(cacheNames = "products", key = "#product.id")
    public Product updateProduct(Product product) {
        // Обновили товар — старую запись из кэша нахуй, чтоб не мозолила глаза
        return productRepository.save(product);
    }
}

А что, другие не нужны? — спросит пытливый ум. Нужны, черт возьми, но в других случаях!

  • Ehcache 3 или JCache (JSR-107): Это когда у тебя кэш должен быть на три района, распределенный, или многоуровневый, чтоб совсем охуенно сложно было.
  • Redis: Это когда приложение твое в пятнадцати экземплярах бегает, и им надо одним кэшем на всех пользоваться. Распределенное кэширование, ёпта.
  • Simple (тот, что в Spring из коробки): Это для учебных проектов, где нахуй ничего не надо, кроме как галочку поставить "кэширование есть". В продакшене на такое даже смотреть страшно.

Вот так-то, дружище. Выбрали Caffeine — и не прогадали, работает, сука, как швейцарские часы.