Кэширование Redis для максимальной производительности в Spring Boot и Java

Кэширование Redis для максимальной производительности в Spring Boot и Java


1. Вводная информация по кэшированию и Redis

Кэширование — это метод хранения и повторного использования результатов высокозатратных операций для повышения производительности и снижения нагрузки на базовые системы. Он предполагает сохранение результатов операции во временном хранилище, называемом кэшем, а затем извлечение результатов из кэша вместо повторного выполнения операции при тех же входных данных.

Redis — это хранилище структур данных с открытым исходным кодом, которое основано на архитектуре in-memory. Его можно использовать в качестве базы данных, кэша и брокера сообщений. Оно обладает высокой производительностью и поддерживает широкий спектр структур данных, таких как строки, хэши, списки, множества и другие.

2. Настройка приложения Spring Boot

Для начала создайте новое приложение Spring Boot с помощью Spring Initializr. Добавьте следующие зависимости:

  • Web;
  • JPA;
  • Lombok;
  • Redis.

Вы можете создать проект и импортировать его в любимую IDE.

3. Настройка кэша Redis

Прежде чем использовать Redis в качестве кэша в приложении, его нужно настроить. Сначала добавьте следующие свойства в файл application.properties:

spring.redis.host=localhost
spring.redis.port=6379

Далее создайте класс конфигурации RedisCacheConfig:

@Configuration
@EnableCaching
public class RedisCacheConfig extends CachingConfigurerSupport {
    @Value("${spring.redis.host}")
    private String redisHost;
    @Value("${spring.redis.port}")
    private int redisPort;
    @Bean
    public JedisConnectionFactory jedisConnectionFactory() {
        return new JedisConnectionFactory(new RedisStandaloneConfiguration(redisHost, redisPort));
    }
    @Bean
    public RedisCacheManager cacheManager() {
        return RedisCacheManager.builder(jedisConnectionFactory()).build();
    }
}

Этот класс включает поддержку кэширования и настраивает бины (объекты) JedisConnectionFactory и RedisCacheManager.

4. Реализация сервисов с возможностью кэширования

Создадим простой сервис, работе которого поможет кэширование. В этом примере реализуем сервис для получения информации о пользователе из базы данных.

Сначала создадим сущность User:

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(nullable = false)
    private String name;
    @Column(nullable = false)
    private String email;
}

Теперь создадим интерфейс UserRepository:

public interface UserRepository extends JpaRepository<User, Long> {}

Далее создаем UserService:

@Service
public class UserService {
private final UserRepository userRepository;
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    @Cacheable(value = "users", key = "#id")
    public User findById(Long id) {
        return userRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("User not found"));
    }
}

Аннотация @Cacheable указывает на то, что результат метода findById должен быть кэширован. Атрибут value определяет имя кэша, а атрибут key  — ключ кэша.

5. Способы вытеснения кэша

Чтобы поддерживать кэш в актуальном состоянии, нужно вытеснять или удалять записи при изменении базовых данных. Для этого можно использовать аннотацию @CacheEvict.

Обновите класс UserService, чтобы добавить методы для создания и обновления пользователей:

@Service
public class UserService {
    private final UserRepository userRepository;
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    @Cacheable(value = "users", key = "#id")
    public User findById(Long id) {
        return userRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("User not found"));
    }
    @CacheEvict(value = "users", key = "#user.id")
    public User save(User user) {
        return userRepository.save(user);
    }
    @CacheEvict(value = "users", key = "#user.id")
    public User update(User user) {
        findById(user.getId()); // Ensure the user exists
        return userRepository.save(user);
    }
    @CacheEvict(value = "users", allEntries = true)
    public void deleteById(Long id) {
        userRepository.deleteById(id);
    }
}

Аннотация @CacheEvict удаляет указанную запись кэша после выполнения метода. В нашем случае мы удаляем кэш при создании, обновлении и удалении пользователя.

6. Тестирование производительности

Теперь, когда мы внедрили кэширование, протестируем производительность. Создадим простой REST-контроллер и измерим время отклика с кэшированием и без него.

Создайте класс UserController:

@RestController
@RequestMapping("/api/users")
public class UserController {
private final UserService userService;
    public UserController(UserService userService) {
        this.userService = userService;
    }
    @GetMapping("/{id}")
    public ResponseEntity<User> getUser(@PathVariable Long id) {
        return ResponseEntity.ok(userService.findById(id));
    }
}

Для измерения времени ответа можно использовать такие инструменты, как Apache JMeter, Postman и curl. Выполните несколько запросов, чтобы увидеть эффект от кэширования.

Заключение

В этой статье мы показали, как использовать Redis в качестве кэша со Spring Boot и Java. Мы рассмотрели конфигурацию, реализацию кэшируемых сервисов, способы вытеснения кэша и тестирование производительности. С кэшированием Redis можно значительно повысить производительность приложений Spring Boot и снизить нагрузку на базовые системы.

Тщательно продумайте стратегию кэширования и политику вытеснения кэша, так как неправильные действия могут привести к устареванию данных и неожиданным результатам.

Источник



Report Page