Spring Boot Redis Cache

스프링 부트 레디스 캐시

이 게시물에서는 샘플 스프링 부트 애플리케이션을 설정하고 레디스 캐시와 통합하는 방법을 소개하겠습니다. 레디스는 오픈 소스 인메모리 데이터 구조 저장소로 데이터베이스, 캐시 및 메시지 브로커로 사용되지만, 이 레슨에서는 캐싱 통합만을 보여줍니다. 우리는 스프링 이니셜라이저 도구를 사용하여 프로젝트를 빠르게 설정할 것입니다.

스프링 부트 레디스 프로젝트 설정

프로젝트를 빠르게 설정하기 위해 스프링 이니셜라이저 도구를 사용할 것입니다. 다음과 같이 3개의 종속성을 사용할 것입니다: 프로젝트를 다운로드하고 압축을 푸십시오. 우리는 애플리케이션이 중지되면 모든 데이터가 손실되는 임베디드 데이터베이스를 사용할 예정이므로 H2 데이터베이스 종속성을 사용했습니다.

Spring Boot Redis 캐시 Maven 종속성

도구를 사용하여 설정을 완료했지만, 수동으로 설정하려면 Maven 빌드 시스템을 사용하여이 프로젝트에 대한 종속성을 다음과 같이 사용합니다:

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>1.5.9.RELEASE</version>
  <relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  <java.version>1.8</java.version>
</properties>
<dependencies>
  <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-data-redis</artifactId>
  </dependency>

  <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-web</artifactId>
  </dependency>

  <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-test</artifactId>
     <scope>test</scope>
  </dependency>

  <!-- for JPA support -->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
  </dependency>

  <!-- for embedded database support -->
  <dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
  </dependency>

</dependencies>

<build>
  <plugins>
     <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
     </plugin>
  </plugins>
</build>

Spring Boot의 안정된 버전을 메이븐 중앙 저장소에서 가져와 사용하십시오.

모델 정의

Redis 데이터베이스에 개체를 저장하려면 기본 필드가 있는 Person 모델 개체를 정의합니다:

package com.journaldev.rediscachedemo;

import javax.persistence.*;
import java.io.Serializable;

@Entity
public class User implements Serializable {

    private static final long serialVersionUID = 7156526077883281623L;

    @Id
    @SequenceGenerator(name = "SEQ_GEN", sequenceName = "SEQ_USER", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_GEN")
    private Long id;
    private String name;
    private long followers;

    public User() {
    }

    public User(String name, long followers) {
        this.name = name;
        this.followers = followers;
    }

    //표준 게터 및 세터

    @Override
    public String toString() {
        return String.format("User{id=%d, name='%s', followers=%d}", id, name, followers);
    }
}

이것은 게터와 세터를 갖춘 표준 POJO입니다.

Redis 캐시 구성

Spring Boot 및 필요한 종속성이 Maven에서 이미 작동 중인 경우, application.properties 파일에서 단 세 줄만으로 로컬 Redis 인스턴스를 구성할 수 있습니다:

# Redis 구성
spring.cache.type=redis
spring.redis.host=localhost
spring.redis.port=6379

또한 Spring Boot 메인 클래스에 @EnableCaching 어노테이션을 사용하십시오:

package com.journaldev.rediscachedemo;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching
public class Application implements CommandLineRunner {

  private final Logger LOG = LoggerFactory.getLogger(getClass());
  private final UserRepository userRepository;

  @Autowired
  public Application(UserRepository userRepository) {
    this.userRepository = userRepository;
  }

  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }

  @Override
  public void run(String... strings) {
    //임베디드 데이터베이스 채우기
    LOG.info("Saving users. Current user count is {}.", userRepository.count());
    User shubham = new User("Shubham", 2000);
    User pankaj = new User("Pankaj", 29000);
    User lewis = new User("Lewis", 550);

    userRepository.save(shubham);
    userRepository.save(pankaj);
    userRepository.save(lewis);
    LOG.info("Done saving users. Data: {}.", userRepository.findAll());
  }
}

저희는 내장 H2 데이터베이스에 몇 가지 샘플 데이터를 채우기 원하므로 CommandLineRunner를 추가했습니다.

저장소 정의

Redis가 작동하는 방법을 보여주기 전에 JPA 관련 기능에 대한 저장소를 정의할 것입니다:

package com.journaldev.rediscachedemo;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository extends JpaRepository { }

지금은 필요 없으므로 메서드 호출이 없습니다.

컨트롤러 정의

컨트롤러는 Redis 캐시가 작동하는 곳입니다. 사실, 이것은 캐시가 직접 관련되어 있기 때문에 서비스 코드로 진입하지 않아도 되기 때문에 가장 적합한 장소입니다. 여기 컨트롤러의 뼈대입니다:

package com.journaldev.rediscachedemo;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;

@RestController
public class UserController {

  private final Logger LOG = LoggerFactory.getLogger(getClass());

  private final UserRepository userRepository;

  @Autowired
  public UserController(UserRepository userRepository) {
    this.userRepository = userRepository;
  }
   ...
}

이제 캐시에 무언가를 넣기 위해 @Cacheable 주석을 사용합니다:

@Cacheable(value = "users", key = "#userId", unless = "#result.followers < 12000")
@RequestMapping(value = "/{userId}", method = RequestMethod.GET)
public User getUser(@PathVariable String userId) {
  LOG.info("Getting user with ID {}.", userId);
  return userRepository.findOne(Long.valueOf(userId));
}

위의 매핑에서 getUser 메서드는 ‘users’라는 캐시에 사람을 넣고, 키가 ‘userId’인 사람을 식별하며, 팔로워가 12000보다 많은 사용자만 저장합니다. 이렇게 함으로써 캐시가 매우 인기가 많고 자주 조회되는 사용자로 채워집니다. 또한 API 호출에 로그 문을 의도적으로 추가했습니다. 지금 Postman에서 API 호출을 해 보겠습니다. 우리가 한 호출은 다음과 같습니다:

localhost:8090/1
localhost:8090/1
localhost:8090/2
localhost:8090/2

로그를주의 깊게 보면 다음과 같습니다:

... : Getting user with ID 1.
... : Getting user with ID 1.
... : Getting user with ID 2.

알아차렸나요? 우리는 4개의 API 호출을 했지만 로그 문이 3개밖에 없었습니다. 이는 ID가 2인 사용자가 29000명의 팔로워를 가지고 있어 데이터가 캐시되었기 때문입니다. 이는 API 호출 시 데이터가 캐시에서 반환되어 이에 대한 DB 호출이 이루어지지 않았음을 의미합니다!

캐시 업데이트

캐시 값은 실제 객체 값이 업데이트될 때마다 업데이트되어야 합니다. 이는 @CachePut 주석을 사용하여 수행할 수 있습니다:

@CachePut(value = "users", key = "#user.id")
@PutMapping("/update")
public User updatePersonByID(@RequestBody User user) {
  userRepository.save(user);
  return user;
}

이를 통해 개인은 다시 ID로 식별되고 결과로 업데이트됩니다.

캐시 지우기

실제 데이터베이스에서 데이터를 삭제해야 하는 경우에는 더 이상 캐시에 유지할 필요가 없습니다. @CacheEvict 주석을 사용하여 캐시 데이터를 지울 수 있습니다:

@CacheEvict(value = "users", allEntries=true)
@DeleteMapping("/{id}")
public void deleteUserByID(@PathVariable Long id) {
  LOG.info("deleting person with id {}", id);
  userRepository.delete(id);
}

마지막 매핑에서는 캐시 항목을 삭제하기만 하고 다른 작업은 수행하지 않았습니다.

Spring Boot Redis 캐시 애플리케이션 실행

우리는 단일 명령을 사용하여이 앱을 간단히 실행할 수 있습니다:

mvn spring-boot:run

Redis 캐시 제한

Redis는 매우 빠르지만 64 비트 시스템에서 어떤 양의 데이터를 저장하는 데 제한이 없습니다. 32 비트 시스템에서는 데이터를 3GB만 저장할 수 있습니다. 더 많은 사용 가능한 메모리는 더 높은 적중률을 초래할 수 있지만, Redis에 의해 사용되는 메모리가 너무 많아지면 이러한 적중률은 점차 감소할 것입니다. 캐시 크기가 메모리 한도에 도달하면 기존 데이터가 제거되어 새 데이터에 자리를 만듭니다.

요약

이 레슨에서는 Redis 캐시가 빠른 데이터 상호 작용을 제공하고 Spring Boot와 어떻게 최소하면서도 강력한 구성으로 통합할 수 있는지 살펴보았습니다. 아래에 의견을 자유롭게 남겨주세요.

Spring Boot Redis 캐시 프로젝트 다운로드

Source:
https://www.digitalocean.com/community/tutorials/spring-boot-redis-cache