Redis 개념

김현정·2025년 5월 19일
0

Redis 및 Redis 캐시 구현

1. Redis란?

Redis(Remote Dictionary Server)는 인메모리 데이터 구조 저장소로, 다양한 데이터 구조를 지원하는 NoSQL 데이터베이스이다.

  1. 인메모리 저장 : 모든 데이터를 메모리에 저장하여 매우 빠른 읽기/쓰기 속도를 제공합니다.

  2. 영속성 지원 : 디스크에 데이터를 주기적으로 저장하여 서버 재시작 후에도 데이터가 유지됩니다.

  3. 다양한 데이터 타입 : 문자열, 해시, 리스트, 집합, 정렬된 집합 등 다양한 데이터 구조를 지원합니다.

  4. 분산 시스템 지원 : 클러스터 모드를 통해 데이터를 여러 노드에 분산시킬 수 있다.

  5. 싱글 스레드 : 기본적으로 싱글 스레드로 동작하여 원자적 연산을 보장한다.

2. Local Cache 대신 Redis Cache를 사용하는 이유

Local Memory Cache와 Redis Cache의 주요 차이점:

1. 분산 환경 지원

  • Local Memory Cache : 각 서버마다 별도의 캐시를 가지므로 서버 간 캐시 데이터 공유 불가능
  • Redis Cache : 모든 서버가 동일한 Redis 서버를 바라보므로 캐시 데이터 공유 가능

2. 데이터 영속성

  • Local Memory Cache : 서버가 재시작되면 캐시 데이터가 모두 소실됨
  • Redis Cache : 디스크에 저장되므로 Redis 서버 재시작 후에도 데이터 유지 가능

3. 메모리 관리

  • Local Memory Cache : 애플리케이션 메모리를 사용하므로 과도한 캐싱은 애플리케이션 성능에 영향
  • Redis Cache : 별도의 서버에서 관리되므로 애플리케이션 메모리에 영향을 주지 않음

4. 확장성

  • Local Memory Cache : 단일 서버의 메모리 한계에 제약됨
  • Redis Cache : 클러스터링을 통해 수평적 확장 가능

Redis 캐시 구현 단계

1. 의존성 추가

Redis를 사용하기 위한 의존성 추가

dependencies {
    // 기존 의존성들...
    implementation 'org.springframework.boot:spring-boot-starter-data-redis'
}

2. Redis 설정 파일 추가 (application.properties)

application.properties 파일에 Redis 설정을 추가해야 한다.

# Redis 설정
spring.data.redis.host=localhost
spring.data.redis.port=6379
spring.data.redis.password=  # 필요한 경우 비밀번호 설정
spring.data.redis.timeout=60000

3. Redis 캐시 설정 클래스 구현

Redis 캐시 설정을 위한 새로운 설정 클래스 만들기

package org.example.fourchak.config.cache;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

@Configuration
@Profile("redis") // redis 프로필이 활성화된 경우에만 이 설정을 사용
public class RedisCacheConfig {

    @Value("${spring.data.redis.host:localhost}")
    private String redisHost;

    @Value("${spring.data.redis.port:6379}")
    private int redisPort;

    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        RedisStandaloneConfiguration redisConfig = new RedisStandaloneConfiguration(redisHost, redisPort);
        return new LettuceConnectionFactory(redisConfig);
    }

    @Bean
    public CacheManager redisCacheManager(RedisConnectionFactory connectionFactory) {
        RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofMinutes(10)) // 캐시 유효시간 10분
                .disableCachingNullValues() // null 값 캐싱 방지
                .serializeKeysWith(
                        RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())
                )
                .serializeValuesWith(
                        RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())
                );

        return RedisCacheManager.builder(connectionFactory)
                .cacheDefaults(cacheConfiguration)
                .withCacheConfiguration("storeSearch", 
                        RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(5)))
                .withCacheConfiguration("popularKeywords", 
                        RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(30)))
                .build();
    }
}

4. Redis 사용을 위한 프로필 설정

실제 애플리케이션을 실행할 때 Redis 프로필을 활성화하려면 다음과 같이 실행해야 함

# 기존 로컬 메모리 캐시 사용
java -jar your-application.jar

# Redis 캐시 사용
java -jar your-application.jar --spring.profiles.active=redis

또는 application.properties에 다음과 같이 설정할 수 있음

spring.profiles.active=redis

5. 캐시 무효화 구현

Redis 캐시를 사용할 때 데이터 변경 시 캐시를 무효화하는 것이 중요함.
예를 들어 가게 정보가 변경되었을 때 관련 캐시를 무효화하는 방법은 다음과 같음.

package org.example.fourchak.domain.store.service;

import org.springframework.cache.annotation.CacheEvict;
// 기타 import 문

@Service
@RequiredArgsConstructor
public class StoreService {
    
    // 기존 메서드들...
    
    @Transactional
    @CacheEvict(value = "storeSearch", allEntries = true)
    public StoreResponseDto updateStore(Long userId, Long storeId, StoreRequestDto requestDto) {
        // 기존 코드...
    }
    
    @Transactional
    @CacheEvict(value = "storeSearch", allEntries = true)
    public void deleteStore(Long id, Long userId) {
        // 기존 코드...
    }
}

Redis 실행하기

Redis를 로컬 환경에서 실행하려면

1. Docker를 사용하는 경우

docker run --name redis -p 6379:6379 -d redis

2. Redis를 직접 설치한 경우

  • Windows: Redis 서버 실행 파일 실행
  • Linux/Mac: redis-server 명령어 실행

Redis 사용한 캐시 구현 이점

  1. 확장성: 여러 서버가 동일한 Redis 서버를 사용하여 캐시를 공유할 수 있어 분산 환경에서 효과적입니다.

  2. 영속성: Redis는 데이터를 디스크에 저장하므로 서버 재시작 후에도 캐시가 유지됩니다.

  3. 메모리 관리: 애플리케이션 메모리에 영향을 주지 않고 캐시를 관리할 수 있습니다.

  4. 전용 관리 도구: Redis는 전용 모니터링 및 관리 도구를 제공하여 캐시 상태를 쉽게 모니터링할 수 있습니다.

0개의 댓글