본문 바로가기
개발/Spring

[SpringBoot] Redis를 SpringBoot 프로젝트에서 사용해보자

by solchan98 2022. 2. 10.

로그인 관리를 공부하면서, 세션과 리프레시 토큰을 효율적으로 관리하는 방법 중 메모리에 저장하여 빠른 접근성과 동시에 디스크에도 저장하여 영속성까지의 이점을 갖는 Redis를 알게 되었다. 로컬에 설치하고 SpringBoot에서 사용해보자.

Redis는 메모리에 저장하여 빠른 접근과 디스크에 저장하여 영속성 또한 가지고 있다.
이런 영속성에 대해 snapshotting(RDB)과 AOF 두 방식이 존재한다.

sanpshotting은 시간, 저장 횟수에 대해 주기를 두어 디스크에 바이너리 데이터로 dump.rdb파일에 저장하는 방식이다.
AOF는 조회명령을 제외한, 입력/수정/삭제 명령이 실행될 때마다 버퍼에 기록한다. 이후 주기적으로 파일에 저장한다. 기본값으로 appendonly.aof파일에 저장된다.

두 방식에 대한 설정은 추후 꼭 알아볼 것이며, 아래의 포스트를 참고할 것이다.
snapshotting(RDB), AOF
Redis 서버 설정 정리

Redis 설치

Redis는 다음 환경에서 설치하고 사용할 예정이다.

OS: MacOS BigSur
Platfrom: SpringBoot
Build Tool: Gradle

설치

설치는 Homebrew를 통해 진행한다.

brew install redis

설치는 위 명령어 하나만 실행하면 된다.

간단하다.

설정

본인 기준, 다음 경로에 redis 설정 파일인 redis.conf가 생성된다.

/usr/local/etc/redis.conf

redis.conf 열어서 redis의 설정을 수정할 수 있다.

우선은, 계획한 시나리오가 수행될 수 있는 정도의 설정만 알아볼 것이다.

  1. host 수정하기bind부분은 redis에 접속 가능한 ip주소를 의미한다.
    기본적으로 로컬로 설정되어 동작하며, 다음과 같이 수정이 가능하다.
    bind 192.168.0.10 192.168.0.11 213.49.34.12
    이렇게 작성하면, 3개의 주소로 부터 접속을 허용한다.
    만약, 모든 ip주소의 허용을 하고싶다면
    bind 0.0.0.0 혹은 #bind 이렇게 주석처리 해버리면 된다.
  2. port 설정
    port 6379 이렇게 명시된 부분에서 포트넘버만 수정하면 된다.
    그냥 6379 사용하자
  3. password 설정
    접속 허용 ip주소를 설정할 수 있지만, 추가로 비밀번호도 설정이 가능하다.

conf파일 내에 ######SECURITY####### 이 부분을 찾아보면
#requriepass foobared 이 부분이 작성되어있다.
주석을 해제하고 foobared 부분에 설정 하고싶은 비밀번호를 작성하면 된다.

한참 내려서 힘들게 찾았다..
찾으면서 눈이 아플 수 있다🧐.

실행 및 데이터 삽입과 조회 해보기

아래 실행 방법은 Mac에서 brew를 통한 실행 방법이다.

실행: brew services start redis
중단: brew services stop redis

redis-server 통해 실행한다면, 실행 된 redis의 모든 정보를 알 수 있다.

이상한 블록그림 오른쪽을 보면 Status 정보를 알 수 있다.

이제 데이터를 넣어보자.

터미널에서 redis-cli 명령어를 실행하여 들어가자.
참고로 redis 실행 안하고 들어가면 될리가 없다.

127.0.0.1:6378>
위와 같이 접속이 성공하였다면, 데이터를 넣어보자.

데이터를 넣는 커맨드는 set이다.

Redis는 NoSQL이라서 Key-Value로 데이터를 넣는다.

127.0.0.1:6378> set [key] [value] 형식으로 넣으면 된다.
127.0.0.1:6378> set sol 24 엔터!

정상적으로 데이터가 들어갔으면, OK 메시지를 뱉는다.

이제 Key값으로 데이터를 조회해보자.

조회 커맨드는 get이다.

127.0.0.1:6378> get sol 엔터!
"24" 이렇게 value값을 내뱉으면 성공이다!

이제 SpringBoot에서 넣고 조회해보자.

SpringBoot 프로젝트 생성

프로젝트는 매우 단순하게 시작할 것이다.
다음의 디렉토리 구조로 생성하여 Redis에 데이터가 들어가는 것만 확인하고 마무리할 것이다.

다음의 디펜던시를 포함한다.
SpringBoot DevTools
Redis
Web
Lombok

java
|
|--redis
|--|--config
|--|--|--RedisConfig
|--|--controller
|--|--|--MainController
|--|--service
|--|--|--RedisService
|--|--SpringbootredisApplication

Redis 설정파일

RedisConfig에서는 redis 설정 정보를 넣고 스프링 컨테이너에 넣기위한 설정을 할 것이다.

redisTemplate는 이후 Service에서 redis에 데이터를 넣기위한 객체가 필요하는데, 이때 사용하기 위해 설정 및 등록을 한다.

@Configuration
@EnableRedisRepositories
public class RedisConfig {
    @Value("${spring.redis.host}")
    private String redisHost;

    @Value("${spring.redis.port}")
    private int redisPort;

    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory(redisHost, redisPort);
    }

    @Bean
    public RedisTemplate<?, ?> redisTemplate() {
        RedisTemplate<byte[], byte[]> redisTemplate = new RedisTemplate<>();
        // 아래 두 라인을 작성하지 않으면, key값이 \xac\xed\x00\x05t\x00\x03sol 이렇게 조회된다.
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        redisTemplate.setConnectionFactory(redisConnectionFactory());
        return redisTemplate;
    }

}

setKeySerializer, setValueSerializer 설정을 하지 않으면, 콘솔에서 key를 조회할 때 \xac\xed\x00\x05t\x00\x03sol 이렇게 조회된다.

redisHopt와 redisPort는 application.properties에 작성한다.

// application.properties
spring.cache.type=redis
spring.redis.host=localhost
spring.redis.port=6379

이렇게 redis 설정은 마무리!

RedisService 생성

이제 데이터를 넣는 서비스 객체를 만들어야 한다.

앞에서도 말했듯 지금은 도메인 없이 간단하게 key:value 형식의 이름:나이 데이터를 받아 넣고 조회만 수행할 것이다.

@Service
@RequiredArgsConstructor
public class RedisService {

    private final RedisTemplate redisTemplate;

    // 데이터 넣기
    public void setValues(String name, String age){
        ValueOperations<String, String> values = redisTemplate.opsForValue();
        values.set(name, age, Duration.ofMinutes(1)); // 1분 뒤 메모리에서 삭제된다.
    }
    // 데이터 가져오기
    public String getValues(String name){
        ValueOperations<String, String> values = redisTemplate.opsForValue();
        return values.get(name);
    }
}

이전에 컨테이너에 등록했던 RedisTemplate을 가져온다.
setValues메서드를 생성하고, RedisTemplate에서 opsForValue를 꺼낸다.

opsForValue의 set과 get.
set은 데이터(key:value)를 넣는 메서드 이며 메모리에서 존재하는 시간인 expire를 설정할 수 있다.
get은 key를 통해 value를 가져오는 메서드이다.

MainController 생성

이제 데이터를 넣는 POST와 GET을 생성할 것이다.

여기서의 Controller은 단순히 Service 로직을 수행하기 때문에 추가적인 설명은 생략한다.

@RestController
@RequiredArgsConstructor
@RequestMapping("/redis")
public class MainController {

    private final RedisService redisService;

    @PostMapping("")
    public void startRedis(@RequestBody HashMap<String, String> body) {
        redisService.setValues(body.get("name"), body.get("age"));
    }

    @GetMapping("")
    public String startRedis(@RequestParam String name) {
        return redisService.getValues(name);
    }
}

데이터 삽입 및 조회하기

데이터를 넣어보자.

API 테스트는 PostMan을 통해 진행할 것이다.

POST /redis로 다음과 같이 요청을 보낸다.

참고로 같은 Key로 데이터를 넣으면 데이터가 업데이트 된다.

이제 데이터를 조회해보자

GET /redis?name=sol

정상적으로 value값을 가져오는 것을 확인할 수 있다.


다음에는 도메인을 작성하여 직접 매핑하고 저장까지 진행보자.
그 다음은 RefreshToken을 발급하여 redis에 저장해보고 최종적으로 redis 서버를 따로 두어 세션 및 토큰 관리를 효율적으로 해보자.

참고
Redis 소개와 설치 방법


본 글은 공부하면서 알게된 부분을 기록하면서 작성됩니다.
혹시 잘못된 부분이 있다면 언제든 피드백 감사하겠습니다!