BackEND/Java

Spring Boot에서 Redis 캐시 사용 방법

mingmingIT 2025. 3. 29. 11:58

이번 포스팅에서는 Redis 캐시를 보다 깊이 있게 다루는 방법에 대해 설명드리겠습니다.

1. Redis 캐시란?

Redis는 인메모리(In-Memory) 데이터 저장소로, 빠른 속도로 데이터를 읽고 쓸 수 있습니다.
Spring Boot에서 기본 제공하는 캐시는 JVM 메모리를 활용하는 반면, Redis는 서버 외부에서 캐시를 관리할 수 있어 분산 환경에서도 활용할 수 있습니다.

Redis의 주요 특징

  • 초고속 성능: 모든 데이터를 메모리에 저장하므로 매우 빠릅니다.
  • 데이터 구조 지원: 단순한 Key-Value 저장뿐만 아니라, List, Hash, Set 등 다양한 데이터 구조를 지원합니다.
  • TTL (Time-To-Live) 지원: 설정한 시간이 지나면 자동으로 캐시가 만료됩니다.
  • 데이터 지속성 (Persistence) 지원: RDB 및 AOF 방식으로 데이터를 영구적으로 저장할 수도 있습니다.
  • 분산 캐시로 활용 가능: 여러 애플리케이션 서버에서 하나의 Redis 서버를 공유하여 사용할 수 있습니다.

2. Spring Boot에서 Redis 캐시 설정

Spring Boot에서 Redis를 사용하려면 Spring Data Redis를 설정해야 합니다.

✔️ 2-1. Redis 의존성 추가

먼저, spring-boot-starter-data-redis 의존성을 추가합니다.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.16.3</version>
</dependency>

 

  • spring-boot-starter-data-redis → Spring Boot에서 Redis를 사용할 수 있도록 도와줍니다.
  • redisson → Redis 클라이언트 중 하나로, 분산 락 등 다양한 기능을 제공합니다.

✔️ 2-2. Redis 설정 추가 (application.yml)

Redis 서버의 정보를 설정합니다.

spring:
  redis:
    host: localhost  # Redis 서버 주소
    port: 6379       # Redis 포트
    password:        # (필요하면 Redis 비밀번호 입력)
    timeout: 6000ms  # 연결 타임아웃 설정

 

✔️ 2-3. Redis 캐시 매니저 설정

Spring Boot에서 Redis를 캐시 저장소로 사용하려면 RedisCacheManager를 설정해야 합니다.

import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.RedisConnectionFactory;

@Configuration
@EnableCaching  // 캐시 기능 활성화
public class RedisCacheConfig {

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

    @Bean
    public RedisCacheManager cacheManager() {
        return RedisCacheManager.create(redisConnectionFactory());
    }
}

이제 @Cacheable을 사용하면 Redis에서 캐시를 관리하게 됩니다!


3. TTL(Time-To-Live) 설정 및 자동 만료

Redis는 TTL을 설정하여 캐시 데이터를 자동으로 만료시킬 수 있습니다.

TTL 설정 방법

import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import java.time.Duration;

@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
    RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
        .entryTtl(Duration.ofMinutes(10))  // 10분 후 캐시 자동 만료
        .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));

    return RedisCacheManager.builder(redisConnectionFactory)
        .cacheDefaults(config)
        .build();
}

위와 같이 설정하면, 캐시된 데이터가 10분 후 자동으로 삭제됩니다.


4. Redis의 데이터 구조 활용

Redis는 단순한 Key-Value 저장 방식뿐만 아니라, 다양한 데이터 구조를 활용할 수 있습니다.

Redis의 주요 데이터 구조

데이터 구조 설명
String 단순한 Key-Value 저장 방식 (가장 많이 사용됨)
Hash 객체의 여러 속성을 저장할 때 유용 (JSON 저장 가능)
List 순서가 있는 데이터 저장 (예: 채팅 메시지)
Set 중복 없는 데이터 저장 (예: 유니크한 태그 리스트)

✔️ Hash 자료구조 활용 예제

Redis Hash를 사용하여 객체를 저장하는 방법을 살펴보겠습니다.

import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.Map;

@Service
public class RedisService {
    private final RedisTemplate<String, Object> redisTemplate;
    private final HashOperations<String, String, Object> hashOperations;

    public RedisService(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
        this.hashOperations = redisTemplate.opsForHash();
    }

    // 데이터 저장
    public void saveProduct(String id, Product product) {
        hashOperations.put("products", id, product);
    }

    // 데이터 조회
    public Product getProduct(String id) {
        return (Product) hashOperations.get("products", id);
    }
}

위 코드를 실행하면 "products"라는 Hash Key 아래 여러 개의 제품 데이터가 저장됩니다.
이 방법을 활용하면 효율적으로 객체 데이터를 캐싱할 수 있습니다.


5. 캐시 일관성을 유지하는 방법

Redis 캐시는 매우 빠르지만, DB와 캐시의 데이터 불일치 문제가 발생할 수 있습니다. 이를 해결하는 대표적인 패턴은 다음과 같습니다.

캐시 일관성 패턴

패턴 설명
Cache Aside 데이터 요청 시 캐시에 없으면 DB에서 조회 후 캐시에 저장
Write Through 데이터를 저장할 때 캐시에도 동시에 반영
Read Through 캐시에서 읽고 없으면 DB에서 가져온 후 캐시에 저장

6. Redis를 활용한 분산 캐시 적용

Redis는 여러 서버에서 공유할 수 있으므로 분산 캐시로 활용할 수 있습니다.

Redisson을 활용한 분산 락 적용 예제

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;

@Service
public class DistributedLockService {
    private final RedissonClient redissonClient;

    public DistributedLockService(RedissonClient redissonClient) {
        this.redissonClient = redissonClient;
    }

    public void executeWithLock(String lockKey) {
        RLock lock = redissonClient.getLock(lockKey);
        try {
            if (lock.tryLock(5, 10, TimeUnit.SECONDS)) {  
                System.out.println("락 획득 후 작업 수행");
                Thread.sleep(5000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

이제 여러 서버에서 동시에 같은 데이터에 접근해도 동시성 문제를 방지할 수 있습니다.


7. 결론

  • Redis를 사용하면 더 빠르고 효율적인 캐싱이 가능합니다.
  • TTL을 활용하여 자동으로 캐시 만료를 관리할 수 있습니다.
  • Hash, List 등을 활용하면 보다 다양한 방식으로 데이터를 저장할 수 있습니다.
  • Redisson을 활용하면 분산 환경에서도 안정적인 캐시 관리가 가능합니다.