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 и снизить нагрузку на базовые системы.
Тщательно продумайте стратегию кэширования и политику вытеснения кэша, так как неправильные действия могут привести к устареванию данных и неожиданным результатам.
Читайте также:
- Redis и Memurai для кэширования SQL-запросов
- Как ускорить отклик и повысить производительность при помощи кэширования Redis
- Spring Boot: реализация фабричного метода
Читайте нас в Telegram, VK и Дзен
Перевод статьи Abhishek Ranjan: Leveraging Redis Caching for Maximum Performance with Spring Boot and Java