콘텐츠로 이동

Redis 설정 가이드

Redis를 Docker로 설치하고 Spring Boot와 연동하는 방법을 설명합니다.

개요

Redis는 오픈소스 인메모리 데이터 구조 저장소로, 데이터베이스, 캐시, 메시지 브로커로 사용됩니다.

graph LR
    subgraph "Application Layer"
        A[Spring Boot App]
    end

    subgraph "Cache Layer"
        B[(Redis)]
    end

    subgraph "Database Layer"
        C[(PostgreSQL)]
    end

    A -->|캐시 조회| B
    B -->|캐시 미스| A
    A -->|DB 조회| C
    A -->|캐시 저장| B

    style B fill:#dc382d,color:#fff

Redis 사용 사례

사용 사례 설명 데이터 구조
세션 스토어 사용자 세션 관리 Hash
캐싱 API 응답, DB 쿼리 결과 String
실시간 순위표 게임 리더보드 Sorted Set
메시지 큐 비동기 작업 처리 List, Stream
Pub/Sub 실시간 알림 Pub/Sub

Docker로 Redis 설치

기본 설치

# Redis 이미지 다운로드
docker pull redis:7.2

# 기본 실행
docker run -d \
  --name redis \
  -p 6379:6379 \
  redis:7.2

프로덕션 환경 설정

docker run -d \
  --name redis \
  --restart=always \
  -p 6379:6379 \
  -e TZ=Asia/Seoul \
  -v /srv/redis/data:/data \
  -v /srv/redis/redis.conf:/usr/local/etc/redis/redis.conf \
  redis:7.2 redis-server /usr/local/etc/redis/redis.conf

Docker Compose 구성

# docker-compose.yml
version: '3.8'

services:
  redis:
    image: redis:7.2
    container_name: redis
    restart: always
    ports:
      - "6379:6379"
    environment:
      - TZ=Asia/Seoul
    volumes:
      - redis_data:/data
      - ./redis.conf:/usr/local/etc/redis/redis.conf
    command: redis-server /usr/local/etc/redis/redis.conf
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 3

volumes:
  redis_data:

Redis 설정 파일

기본 redis.conf

# /srv/redis/redis.conf

# 네트워크
bind 0.0.0.0
port 6379
protected-mode yes

# 보안
requirepass your_secure_password

# 메모리 관리
maxmemory 256mb
maxmemory-policy allkeys-lru

# 지속성 (RDB)
save 900 1
save 300 10
save 60 10000
dbfilename dump.rdb
dir /data

# AOF (Append Only File)
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec

# 로깅
loglevel notice
logfile ""

# 기타
daemonize no

메모리 정책 옵션

graph TD
    A[maxmemory 도달] --> B{제거 정책}
    B --> C[noeviction<br/>오류 반환]
    B --> D[allkeys-lru<br/>모든 키 LRU]
    B --> E[volatile-lru<br/>TTL 있는 키 LRU]
    B --> F[allkeys-random<br/>무작위 제거]
    B --> G[volatile-ttl<br/>TTL 짧은 키 우선]

    style D fill:#e8f5e8
정책 설명 권장 사용
noeviction 메모리 부족 시 오류 반환 데이터 손실 불가
allkeys-lru 모든 키 중 LRU 제거 일반 캐시
volatile-lru TTL 설정된 키 중 LRU 세션 스토어
allkeys-random 무작위 제거 균등 접근
volatile-ttl TTL 짧은 키 우선 제거 TTL 기반 캐시

Spring Boot 연동

의존성 추가

// build.gradle
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-redis'
}
<!-- pom.xml -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

설정 파일

# application.yml
spring:
  redis:
    host: localhost
    port: 6379
    password: your_secure_password
    timeout: 3000ms
    lettuce:
      pool:
        max-active: 8
        max-idle: 8
        min-idle: 2
        max-wait: -1ms

Redis Configuration

@Configuration
@EnableCaching
public class RedisConfig {

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

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

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

    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
        config.setHostName(host);
        config.setPort(port);
        config.setPassword(password);
        return new LettuceConnectionFactory(config);
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate() {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory());

        // 직렬화 설정
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());

        return template;
    }

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
            .entryTtl(Duration.ofMinutes(30))
            .serializeKeysWith(
                RedisSerializationContext.SerializationPair.fromSerializer(
                    new StringRedisSerializer()))
            .serializeValuesWith(
                RedisSerializationContext.SerializationPair.fromSerializer(
                    new GenericJackson2JsonRedisSerializer()));

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

사용 예제

캐싱 어노테이션 사용

@Service
public class UserService {

    @Cacheable(value = "users", key = "#id")
    public User findById(Long id) {
        // DB 조회 (캐시 미스 시에만 실행)
        return userRepository.findById(id).orElse(null);
    }

    @CacheEvict(value = "users", key = "#user.id")
    public User update(User user) {
        return userRepository.save(user);
    }

    @CacheEvict(value = "users", allEntries = true)
    public void clearCache() {
        // 모든 캐시 삭제
    }
}

RedisTemplate 직접 사용

@Service
@RequiredArgsConstructor
public class SessionService {

    private final RedisTemplate<String, Object> redisTemplate;

    public void saveSession(String sessionId, UserSession session) {
        redisTemplate.opsForValue().set(
            "session:" + sessionId,
            session,
            Duration.ofHours(1)
        );
    }

    public UserSession getSession(String sessionId) {
        return (UserSession) redisTemplate.opsForValue()
            .get("session:" + sessionId);
    }

    public void deleteSession(String sessionId) {
        redisTemplate.delete("session:" + sessionId);
    }
}

Redis CLI 사용법

# Redis 컨테이너 접속
docker exec -it redis redis-cli

# 인증
AUTH your_secure_password

# 기본 명령어
SET key "value"
GET key
DEL key
KEYS pattern*
TTL key
EXPIRE key 3600

# 데이터 구조별 명령어
# Hash
HSET user:1 name "John" age 30
HGET user:1 name
HGETALL user:1

# List
LPUSH queue "item1"
RPOP queue

# Set
SADD tags "redis" "cache"
SMEMBERS tags

# Sorted Set
ZADD leaderboard 100 "player1"
ZRANGE leaderboard 0 -1 WITHSCORES

# 모니터링
INFO
INFO memory
MONITOR

모니터링

Redis 상태 확인

# 메모리 사용량
redis-cli INFO memory

# 연결된 클라이언트
redis-cli CLIENT LIST

# 명령어 통계
redis-cli INFO commandstats

# 실시간 명령어 모니터링
redis-cli MONITOR

주요 메트릭

메트릭 설명 경고 임계값
used_memory 사용 중인 메모리 maxmemory의 80%
connected_clients 연결된 클라이언트 수 1000+
blocked_clients 블록된 클라이언트 0 초과
evicted_keys 제거된 키 수 증가 추세
keyspace_hits/misses 캐시 히트율 80% 미만

보안 설정

필수 보안 설정

  • 강력한 비밀번호 설정 (requirepass)
  • 외부 접근 제한 (bind 설정)
  • protected-mode yes 활성화
  • 방화벽으로 6379 포트 제한
# 보안 강화 설정
bind 127.0.0.1 192.168.1.0/24
requirepass "복잡한_비밀번호_32자_이상"
protected-mode yes

# 위험한 명령어 비활성화
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command CONFIG ""
rename-command DEBUG ""

관련 문서