웹사이트 검색

스프링 부트 레디스 캐시


스프링 부트 레디스 캐시

Spring Boot Redis 프로젝트 설정

Spring Boot Redis Cache 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>

Maven Central에서 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;
    }

    //standard getters and setters

    @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 Config
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) {
    //Populating embedded database here
    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로 식별되고 결과로 업데이트됩니다.

캐시 지우기

일부 데이터가 실제 Database에서 삭제될 경우 더 이상 캐시에 보관할 지점이 없습니다. @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 Cache가 빠른 데이터 상호 작용을 제공하는 기능과 최소한의 강력한 구성으로 이를 Spring Boot와 통합하는 방법을 살펴보았습니다. 아래에 의견을 남겨주세요.

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