Bài 21: Caching với Redis trong Spring Boot
Giới thiệu về Caching với Redis trong Spring Boot:
Caching là gì?
- Caching là quá trình lưu trữ dữ liệu tạm thời để giảm thời gian truy xuất dữ liệu từ các nguồn dữ liệu chính như cơ sở dữ liệu. Điều này giúp cải thiện hiệu suất của ứng dụng bằng cách giảm tải cho các nguồn dữ liệu chính và tăng tốc độ phản hồi.
Redis là gì?
- Redis là một cơ sở dữ liệu NoSQL lưu trữ dữ liệu dưới dạng key-value và được sử dụng phổ biến như một hệ thống cache do tốc độ truy xuất nhanh và khả năng mở rộng cao.
Lợi ích của việc sử dụng Redis làm cache layer trong Spring Boot:
Hiệu suất: Giảm thời gian truy xuất dữ liệu từ cơ sở dữ liệu.
Khả năng mở rộng: Hỗ trợ phân tán dữ liệu, dễ dàng mở rộng hệ thống.
Đơn giản: Tích hợp dễ dàng với Spring Boot qua Spring Cache.
Cấu hình và tích hợp Spring Cache với Redis:
Bước 1: Thêm dependency Redis và Spring Cache vào dự án
Maven:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency>Gradle:
implementation 'org.springframework.boot:spring-boot-starter-data-redis' implementation 'org.springframework.boot:spring-boot-starter-cache'
Bước 2: Cấu hình kết nối Redis trong application.properties hoặc application.yml
-
spring.redis.host=localhost spring.redis.port=6379 spring.redis.password=yourpassword (nếu cần) spring.cache.type=redis application.yml:
spring: redis: host: localhost port: 6379 password: yourpassword (nếu cần) cache: type: redis
Bước 3: Cấu hình CacheManager để sử dụng Redis
Tạo một class cấu hình CacheConfig để thiết lập
CacheManager:import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.data.redis.cache.RedisCacheConfiguration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisStandaloneConfiguration; import java.time.Duration; @Configuration @EnableCaching public class CacheConfig { @Bean public RedisConnectionFactory redisConnectionFactory() { RedisStandaloneConfiguration config = new RedisStandaloneConfiguration("localhost", 6379); // Nếu Redis yêu cầu mật khẩu, bỏ chú thích dòng dưới và thay "yourpassword" bằng mật khẩu thực tế // config.setPassword("yourpassword"); return new JedisConnectionFactory(config); } @Bean public RedisTemplate<String, Object> redisTemplate() { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(redisConnectionFactory()); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return template; } @Bean public RedisCacheManager cacheManager() { RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofMinutes(60)) // Thời gian tồn tại của cache .disableCachingNullValues(); return RedisCacheManager.builder(redisConnectionFactory()) .cacheDefaults(cacheConfiguration) .transactionAware() .build(); } }
Ví dụ thực tiễn: Caching dữ liệu từ cơ sở dữ liệu
Bước 1: Tạo một entity và repository
Entity:
import javax.persistence.Entity; import javax.persistence.Id; import java.io.Serializable; @Entity public class User implements Serializable { @Id private Long id; private String name; private String email; // Constructors, getters and setters public User() {} public User(Long id, String name, String email) { this.id = id; this.name = name; this.email = email; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }Repository:
import org.springframework.data.jpa.repository.JpaRepository; public interface UserRepository extends JpaRepository<User, Long> { }
Bước 2: Tạo một service với phương thức caching
UserService:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import java.util.Optional; @Service public class UserService { @Autowired private UserRepository userRepository; @Cacheable(value = "users", key = "#id") public Optional<User> getUserById(Long id) { System.out.println("Fetching from database..."); return userRepository.findById(id); } }
Bước 3: Tạo một controller để kiểm tra caching
UserController:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/users") public class UserController { @Autowired private UserService userService; @GetMapping("/{id}") public User getUserById(@PathVariable Long id) { return userService.getUserById(id).orElse(null); } }
Bước 4: Kiểm tra ứng dụng
Chạy ứng dụng Spring Boot bằng cách chạy class chính của dự án.
Sử dụng Postman hoặc bất kỳ công cụ HTTP client nào để kiểm tra các endpoint:
Truy xuất người dùng theo ID (GET):
http://localhost:8080/users/1Lần đầu tiên truy xuất, console sẽ in "Fetching from database..." để chỉ ra rằng dữ liệu được lấy từ cơ sở dữ liệu.
Các lần truy xuất sau đó sẽ không in ra dòng này, cho thấy rằng dữ liệu được lấy từ cache.
Câu hỏi củng cố kiến thức:
Caching là gì và tại sao lại cần thiết?
- Caching là quá trình lưu trữ dữ liệu tạm thời để giảm thời gian truy xuất từ các nguồn dữ liệu chính, giúp cải thiện hiệu suất của ứng dụng.
Redis là gì và tại sao lại sử dụng Redis làm cache layer trong Spring Boot?
- Redis là một cơ sở dữ liệu NoSQL lưu trữ dữ liệu dưới dạng key-value, được sử dụng phổ biến như một hệ thống cache do tốc độ truy xuất nhanh và khả năng mở rộng cao.
Làm thế nào để cấu hình CacheManager sử dụng Redis trong Spring Boot?
- Tạo một class cấu hình với annotation
@EnableCachingvà cấu hìnhRedisCacheManagertrong đó.
- Tạo một class cấu hình với annotation
Annotation
@Cacheableđược sử dụng để làm gì?@Cacheableđược sử dụng để đánh dấu các phương thức mà kết quả của chúng sẽ được lưu trữ vào cache.
Làm thế nào để kiểm tra dữ liệu có được cache hay không trong Spring Boot?
- Truy xuất dữ liệu qua các endpoint và kiểm tra log trên console. Nếu dữ liệu được lấy từ cache, sẽ không có log cho thấy dữ liệu được truy xuất từ cơ sở dữ liệu.
Kết luận:
- Bài viết này đã cung cấp một cái nhìn chi tiết về cách sử dụng Redis làm cache layer trong Spring Boot. Bạn đã học cách tích hợp Spring Cache với Redis, cấu hình
CacheManager, và sử dụng annotation@Cacheableđể cache dữ liệu từ cơ sở dữ liệu. Các ví dụ thực tiễn giúp bạn hiểu rõ hơn và có thể áp dụng vào các dự án thực tế của mình. Việc sử dụng caching giúp cải thiện hiệu suất của ứng dụng, đặc biệt là trong các hệ thống yêu cầu xử lý dữ liệu nhanh chóng và thời gian thực.