Skip to main content

Command Palette

Search for a command to run...

Bài 21: Caching với Redis trong Spring Boot

Published
5 min readView as Markdown

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

  • application.properties:

      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/1

      • Lầ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:

  1. 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.
  2. 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.
  3. 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 @EnableCaching và cấu hình RedisCacheManager trong đó.
  4. 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.
  5. 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.

More from this blog

devngu

169 posts