[Spring Boot + Redis] 스프링 부트 Redis 사용해보기

Miracle Generator·2021년 10월 7일
1

Spring Boot

목록 보기
2/4

스프링 부트 프로젝트에 Redis 적용

Redis 처음 사용해 보는 입장에서 공부하면서 작성한 내용입니다. 깊이 있는 내용은 아님을 고려하세요.

Redis 설치

Redis 설치는 로컬 환경에 직접 설치하거나 Docker를 이용한 설치 등 다양한 방법이 있지만 개인적으로 Docker를 이용한 설치를 선호하므로 이 글에서는 Docker를 이용하도록 한다.

Docker를 이용한 Redis 설치 및 구동

아래 명령으로 Redis docker image를 설치한다.

docker run -d -p 6379:6379 redis 또는
docker run -d --name reids_study -p 6379:6379 redis

Redis docker image 설치 후 아래와 같이 image container 접속하여 redis-cli 실행

$ docker ps // redis container id확인
$ docker exec -it {container id} /bin/bash
// 접속이후 
root@ce4a8669f2eb:/data# redis-cli

스프링부트 프로젝트에 Redis 설정하기

dependency 추가

스프링부트 프로젝트에서 Redis를 사용하기 위해서는 Spring Data Redis 의존 라이브러리를 설치해야 한다.
아래와 같이 build.gradle에 dependency를 추가하자.

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

위와 같이 추가하고 나면, 아래 그림과 같이 관련된 라이브러리들이 추가된다.

스프링부트2에서는 Redis Client로 Lettuce가 기본으로 설정된다. 만약 Jedis를 사용하고자 한다면, Lettuce를 제거하고 Jedis를 사용하도록 설정하면 된다. Lettuce와 Jedis에 관련해서는 공부하고 포스팅할 예정입니다. (전 Redis 초보입니다.)

이제 프로젝트에서 Redis를 사용할 수 있도록 Configuration을 하면 된다.

RedisConfig 클래스 추가

@Configuration
public class RedisConfig {

    @Value("${spring.redis.host}")
    private String host;

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

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

    @Bean
    public RedisTemplate<String, Object> redisTemplate() {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        redisTemplate.setConnectionFactory(redisConnectionFactory());
        return redisTemplate;
    }

    @Bean
    public StringRedisTemplate stringRedisTemplate() {
        final StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
        stringRedisTemplate.setKeySerializer(new StringRedisSerializer());
        stringRedisTemplate.setValueSerializer(new StringRedisSerializer());
        stringRedisTemplate.setConnectionFactory(redisConnectionFactory());
        return stringRedisTemplate;
    }
}

위와 같이 RedisConfig 클래스를 생성하고 LettuceConnectionFactory, RedisTemplate Bean을 등록하자.

  • RedisConnectionFactory
    • redis와 connection을 생성해 주는 객체
  • RedisTemplate
    • redis 서버와 통신을 처리하고, 사용자로 하여금 redis 모듈을 사용하기 쉽도록 다양한 기능을 제공하기 위해 스프링에서 높은 수준의 추상화를 통해서 오퍼레이션을 제공
    • Redis는 기본적으로 key, value를 바이트의 배열(byte[])로 저장한다. StringRedisTemplate를 사용하면 key, value를 모두 문자열로 저장할 수 있다.
    • RedisTemplate은 Redis 저장소에 오브젝트를 저장할 때 기본값으로 정의된 JdkSerializationRedisSerializer을 이용한다. 따라서 해당 오브젝트는 반드시 java.io.Serializable 인터페이스를 구현해야 한다. 이 방식의 문제점은 다른 언어 환경에서 Redis 저장소에 접근할 경우 값을 인식하지 못한다는 것이다. 또한 오브젝트의 클래스 메타 정보를 저장하다 보니 크기 또한 커진다. 특정 언어에 종속되지 않으려면 저장되는 값으로 JSON 문자열 또는 MessagePack 형식을 고려해야 한다.
      RedisTemplate 을 이용해서 Multi Pojo get/set 할 때 이슈사항

사용

Redis에 데이터 넣기

아래와 같이 테스트 코드 작성 후 실행

@SpringBootTest
@ActiveProfiles("test")
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.AUTO_CONFIGURED) // 실제 DB 사용하고 싶을때 NONE 사용
public class RedisBasicTest {
    @Autowired
    RedisTemplate<String, String> redisTemplate;

    @Test
    void redisConnectionTest() {
        final String key = "a";
        final String data = "1";

        final ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
        valueOperations.set(key, data);

        final String s = valueOperations.get(key);
        Assertions.assertThat(s).isEqualTo(data);
    }
 }

결과는 아래와 같이 키와 value가 들어가 있다 (아래 프로그램은 Medis라는 Redis GUI client이다.)

객체 삽입

@Test
void redisInsertObject() {
    RedisUserDto redisUserDto = new RedisUserDto("kenux", "password");

    final ValueOperations<String, RedisUserDto> valueOperations = redisTemplate.opsForValue();
    valueOperations.set(redisUserDto.getId(), redisUserDto);

    final RedisUserDto result = valueOperations.get(redisUserDto.getId());
		assertThat(result).isNotNull();
		assertThat(result.getId()).isEqualTo(redisUserDto.getId());
		assertThat(result.getPw()).isEqualTo(redisUserDto.getPw());
    System.out.println("result = " + result);
}

Redis Expire 테스트

Redis에서는 키에 대해서 expire 시간을 설정할 수 있다. expire 시간에 도달한 키는 Redis에서 자동으로 제거가 된다. 이를 잘 활용하면 Redis를 더 다양한 형태로 사용할 수 있을 것이라 생각된다.

@Test
void redisExpireTest() throws InterruptedException {
    final String key = "a";
    final String data = "1";
    
    final ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
    valueOperations.set(key, data);
    final Boolean expire = redisTemplate.expire(key, 5, TimeUnit.SECONDS);
    Thread.sleep(6000);
    final String s = valueOperations.get(key);
	assertThat(expire).isTrue();
	assertThat(s).isNull();
}

위 코드 redis에 삽입한 아이템에 대해서 5초의 expire time을 설정하고, 5초가 지난 후에 redis에서 해당 키가 조회되는지 테스트하는 코드이다.

이상 Redis 초보의 Redis 설정 및 간단한 사용에 대한 내용이다. 앞으로 공부하고 실무에 적용해 보면서 겪게되는 다양한 이슈들도 포스팅 해 보도록 하고 이번 포스팅은 여기서 마무리 한다.

profile
삶은 나를 만들어가는 과정이다

2개의 댓글

comment-user-thumbnail
2022년 2월 3일

expired되기전에 expired시간을 늘려 줄 수도 있나요? 예를들어 expired시간을 하루로 두고 하루가 가기 전에 다시 하루로 늘려준다던가 이런식으로여

1개의 답글