[DEV] study&learn
article thumbnail
Published 2023. 1. 25. 09:36
Spring Boot에 Redis 적용 스프링

Reference
Redis 설치 및 간단한 사용 방법 (Mac)
[SpringBoot] Redis+SMTP 인증메일 구현
Spring Boot 에서 Redis 사용하기
[Spring Boot + Redis] 스프링 부트 Redis 사용해보기
[Redis] AWS EC2에 redis-server setup 하기
[REDIS] 📑 redis.conf 파일 설정 항목 정리
LRU Cache 이해하기

0. Local 에 Redis 설치(Mac OS)

# brew 로 redis 설치
brew install redis

# redis 시작 명령어
brew services start redis 
# brew services stop redis 
# brew services restart redis

# redis cli 사용 명령어
$ redis-cli

1. 의존성 추가

==spring-boot-starter-data-redis== 의존성 추가

implementation 'org.springframework.boot:spring-boot-starter-data-redis'

위의 의존성 추가로 현재 프로젝트에서 Redis와 관련된 메서드를 사용할 수 있음.
(버전을 명시하지 않아도 되는지???)

2. Redis port, ip 정의

# Redis  
spring.redis.host=localhost  
spring.redis.port=6379

로컬에서 실행 여부를 확인하기 위하여 기본 값을 사용.
(-> 기본 값을 사용할 때는 따로 설정을 안해줘도 된다나...?)

3. Redis Config 작성

package com.formmaker.fff.common.redis;  

import org.springframework.beans.factory.annotation.Value;  
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.lettuce.LettuceConnectionFactory;  
import org.springframework.data.redis.core.RedisTemplate;  

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

    @Bean  
    public RedisConnectionFactory redisConnectionFactory() {  
        return new LettuceConnectionFactory(host, port);  
    }  

    @Bean  
    public RedisTemplate<?, ?> redisTemplate() {  
        RedisTemplate<?, ?> redisTemplate = new RedisTemplate<>();  
        redisTemplate.setConnectionFactory(redisConnectionFactory());  
        return redisTemplate;  
    }  
}

4. Redis Util 작성

package com.formmaker.fff.common.redis;  

import lombok.RequiredArgsConstructor;  
import org.springframework.data.redis.core.RedisTemplate;  
import org.springframework.data.redis.core.ValueOperations;  
import org.springframework.stereotype.Component;  

import java.time.Duration;  

@Component  
@RequiredArgsConstructor  
public class RedisUtil {  
    private final RedisTemplate<String, String> redisTemplate;  

    public String getData(String key) {  
        // key를 통해 value(데이터)를 얻는다.  
        ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();  
        return valueOperations.get(key);  
    }  

    public void setDataExpire(String key, String value, long duration) {  
        //  duration 동안 (key, value)를 저장한다.  
        ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();  
        Duration expireDuration = Duration.ofMillis(duration);  
        valueOperations.set(key, value, expireDuration);  
    }  

    public void deleteData(String key) {  
        // 데이터 삭제  
        redisTemplate.delete(key);  
    }  
}

5. AWS, EC2 서버에 Redis 적용

5-1. EC2 서버에서 Redis 다운로드

# apt-get 업그레이드
sudo apt-get update
sudo apt-get upgrade

# redis-server 설치
sudo apt-get install redis-server

# redis 설치 확인
redis-server --version

# redis 동작 확인
redis-cli

5-2. Redis 설정

sudo vi /etc/redis/redis.conf

위 명령어를 입력하면 아래와 같은

창이 열린다.

이부분에서 서버에 설치된 redis 의 설정을 해줄 수 있다.

다양한 설정이 가능한데,
일단은 max 메모리와 데이터 교체 알고리즘 설정만 해줄 것이다.

# 검색
/[검색할 단어] + 엔터

# 다음 단어
n 입력

# 수정, insert mode
i 입력

# 작업 종료
esc 버튼

# 변경 사항 저장 및 파일 나오기
:wq + 엔터

기본적으로 주석처리가 되어있는데, 주석을 풀고 원하는 값을 넣어주면 된다.

maxmemory 는 1G,
maxmemory-policy 는 모든 키에서 사용된지 가장 오래된 데이터를 삭제하는 방법인 allkeys-lru 알고리즘을 선택했다.

설정을 완료한 후 파일을 빠져나와 아래 명령어를 통해 redis-server 를 재실행시키면 변경한 설정이 적용된다.

sudo systemctl restart redis-server

5-3. EC2 서버 설정

이부분은 따로 설정을 해준 것이 아직은 없는 상태이다.
redis 를 EC2 서버 내부에 설치를 해주었기 때문에,
host-ip 주소를 바꿔줄 필요가 없이 제대로 동작하는 것 같다.

ElastiCache 를 사용하게 되면 서버에 추가적인 설정이 필요할 것 같다.

Error

상황 No.1

디버그 모드를 통해 확인해보니 여기서 호출한 메서드로 값이 넘어간 후 메서드가 제대로 동작하지 않으며 위와 같은 오류 메세지가 반환되는 것 같다.

debug point

위의 경로에서 내가 의도한 바대로,
email, authNum 등은 올바르게 들어왔다.

이 부분이 문제였던 것 같다.
왜 redisTemplate 가 null 일까?

RedisUtil 에서
final 을 넣어주니 제대로 동작하는 것을 확인했다.

[궁금한 것]
final 을 안넣으면 왜 null 이었을까?
일단 의존성 주입에 final keyword가 들어가야하는 것은 인지하고 있었다.
블로그를 보며 따라하다보니 놓치고 지나간 부분인데,
fianl 을 하지 않으면 의존성 주입 자체가 일어나지 않기 때문에,
빈 객체만 생기기 때문에 이러한 오류를 맞이한 것 일까?

profile

[DEV] study&learn

@devjuni

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!