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

«Как реализовывалось кэширование в вашем последнем проекте?» — вопрос из категории Архитектура, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В проекте использовалось многоуровневое кэширование для снижения нагрузки на базу данных и ускорения отклика API.

Стек технологий: Spring Boot, Spring Cache Abstraction, Redis (как распределенное хранилище).

Реализация:

  1. Декларативное кэширование через аннотации Spring:

    @Service
    public class ProductService {
        // Кэшируем результат метода. При повторном вызове с тем же id результат берется из кэша.
        @Cacheable(value = "products", key = "#id")
        public Product getProductById(Long id) {
            return productRepository.findById(id)
                    .orElseThrow(() -> new ProductNotFoundException(id));
        }
    
        // Обновляем запись в БД и инвалидируем (удаляем) старые данные в кэше.
        @CacheEvict(value = "products", key = "#product.id")
        public Product updateProduct(Product product) {
            return productRepository.save(product);
        }
    
        // Сохраняем новый продукт и сразу кладем его в кэш.
        @CachePut(value = "products", key = "#result.id")
        public Product createProduct(Product product) {
            return productRepository.save(product);
        }
    }
  2. Конфигурация Redis в application.yml:

    spring:
      cache:
        type: redis
        redis:
          time-to-live: 600000 # TTL = 10 минут
          cache-null-values: false # Не кэшировать null
      data:
        redis:
          host: localhost
          port: 6379
  3. Стратегии инвалидации:

    • TTL (Time-To-Live): Автоматическое удаление записей через заданное время.
    • Явная инвалидация: Через @CacheEvict при обновлении/удалении данных.
    • Инвалидация по событию: С помощью @EventListener на кастомные события приложения для очистки целых регионов кэша.

Преимущества такого подхода:

  • Производительность: Резкое снижение времени отклика для часто читаемых данных.
  • Масштабируемость: Redis как внешний кэш разделяется между всеми экземплярами приложения.
  • Гибкость: Аннотации Spring позволяют легко включать/отключать и настраивать кэширование на уровне бизнес-логики.