Backend/SpringBoot

Cache, RefreshToken 용 Redis를 쓸 경우.

Dean83 2026. 1. 29. 14:46

Redis를 통해 Cache와 RefreshToken을 둘다 관리하는 경우, 설정이 헷갈릴 수 있어 정리해 둔다. 

 

일단 요약하자면, 

  • 1개의 Redis를 띄워 각각 cache, token용으로 나누어 운용 가능
  • 단, database를 나누어야 함.
    • 예 : 0번은 cache용, 1번은 token용
    • 기본적으로 0 ~ 15까지 제공
  • application.yaml 설정을 통해 둘중 하나의 config는 자동으로, 하나의 config는 수동으로 설정해야 함. 
    • 둘중 무얼 수동으로 설정할 지는 자유이다.
    • 수동으로 설정할때 주의점은, bean 이름을 반드시 명시해야 한다는 점이다.
    • 기본 bean 으로 사용할 경우 application.yaml의 설정을 덮어 쓴다
    • RefreshToken 용 config 수동 설정 예

@Configuration
@RequiredArgsConstructor
public class TokenRedisConfig {

    private final RedisProperties redisProperties;

    @Bean(name = "refreshTokenRedisConnectionFactory")
    public RedisConnectionFactory redisConnectionFactory() {
        RedisStandaloneConfiguration config =
                new RedisStandaloneConfiguration(
                        redisProperties.getHost()
                        , redisProperties.getPort());

        config.setDatabase(1);

        GenericObjectPoolConfig<StatefulConnection<?, ?>> poolConfig = new GenericObjectPoolConfig<>();
        poolConfig.setMaxTotal(redisProperties.getLettuce().getPool().getMaxActive());
        poolConfig.setMaxIdle(redisProperties.getLettuce().getPool().getMaxIdle());
        poolConfig.setMinIdle(redisProperties.getLettuce().getPool().getMinIdle());
        poolConfig.setMaxWait(redisProperties.getLettuce().getPool().getMaxWait());

        LettucePoolingClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder()
                .poolConfig(poolConfig)
                .commandTimeout(redisProperties.getConnectTimeout())
                .build();

        return new LettuceConnectionFactory(config, clientConfig);
    }

    @Bean(name = "tokenRedisTemplate")
    public RedisTemplate<String,String> tokenRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String,String> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new StringRedisSerializer());

        return redisTemplate;
    }
}
  • RedisProperties 는 https://dean83.tistory.com/418 여기에 정리해 놓은것 처럼, yaml 에 있는 설정을 매핑한 클래스 이다.
  • GenericObjectPoolConfig를 이용하기 위해 아래의 라이브러리를 gradle에 추가해야 한다.
  • 기본적인 redis 동작 설정 (pool 개수 등), 타임아웃을 포함해야 한다. 
implementation 'org.apache.commons:commons-pool2'


RefreshToken을 관리하는 Repository 예

  • redisTemplate을 주입받아 이를 통해 redis에 저장
  • 참고로 별도의 서비스를 구현하여 repository에 접근할 경우 @Transactional은 쓰지 않는다.
    • Redis에선 일반적인 Transactional과 개념이 다름
@Repository
public class RefreshTokenRedisRepository {

    private final StringRedisTemplate redisTemplate;

    public RefreshTokenRedisRepository(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    public void save(Long userId, String refreshToken, long ttlMs) {
        String key = "refresh_token:" + userId;
        redisTemplate.opsForValue()
                .set(key, refreshToken, ttlMs, TimeUnit.MILLISECONDS);
    }

    public String find(Long userId) {
        return redisTemplate.opsForValue()
                .get("refresh_token:" + userId);
    }

    public void delete(Long userId) {
        redisTemplate.delete("refresh_token:" + userId);
    }
}