Redis

handa·2025년 7월 2일
0
post-thumbnail

Redis는 인메모리 기반의 오픈소스 Key-Value 데이터 저장소로, 매우 빠른 속도와 다양한 데이터 구조를 지원하는 NoSQL 데이터베이스입니다.
주로 캐시, 세션 관리, 실시간 데이터 처리에 활용되며, 높은 확장성과 영속성 기능도 제공합니다

Redis의 주요 특징

  • 인메모리 저장소
    모든 데이터를 메모리에 저장하여 디스크 기반 DB보다 훨씬 빠른 읽기/쓰기 속도를 자랑합니다.
  • Key-Value 구조
    키는 항상 문자열(String)이고, 값(Value)은 다양한 자료구조를 가질 수 있습니다.
  • 다양한 데이터 타입 지원
    • String: 가장 기본적인 문자열 타입으로, 최대 512MB까지 저장 가능하며 텍스트, 바이너리 데이터 모두 저장 가능
    • List: 순서가 있는 문자열의 리스트(배열)
    • Set: 중복 없는 문자열 집합, 순서 없음
    • Sorted Set: 점수(score)를 부여해 정렬된 집합
    • Hash: 필드-값 쌍으로 이루어진 해시 테이블
    • 그 외: Bitmap, HyperLogLog, Geospatial, Streams 등
  • 영속성(Persistence)
    메모리 기반이지만, RDB 스냅샷과 AOF(Append Only File) 로그를 통해 디스크에 데이터를 저장하여 서버 재시작 시에도 복구가 가능합니다.
  • 싱글 스레드 아키텍처
    단일 스레드로 동작해 명령어 실행 시 원자성을 보장하며, 복잡한 동시성 문제를 줄입니다.
  • 클러스터 및 복제 지원
    여러 노드에 데이터를 분산 저장하는 클러스터링과 마스터-슬레이브 복제를 지원해 확장성과 고가용성을 제공합니다.

Redis 데이터 타입별 상세 설명 및 활용

데이터 타입설명주요 명령어활용 예시
String단순 문자열, 바이너리 데이터 저장 가능SET, GET, INCR, DECR, APPEND카운터, 토큰 저장, 간단 캐시
List순서가 있는 문자열 리스트LPUSH, RPUSH, LPOP, LRANGE작업 큐, 메시지 대기열
Set중복 없는 문자열 집합, 순서 없음SADD, SREM, SMEMBERS태그, 유저 그룹 관리
Sorted Set점수 기반 정렬된 집합ZADD, ZRANGE, ZREM랭킹 시스템, 우선순위 큐
Hash필드-값 쌍의 해시 테이블HSET, HGET, HGETALL객체 저장, 사용자 정보 관리
  • String
    가장 기본적인 자료형으로, 텍스트뿐 아니라 바이너리 데이터, 이미지, 직렬화된 객체도 저장 가능합니다.

  • List
    연결 리스트 형태로, 양쪽 끝에서 빠른 삽입/삭제가 가능해 큐(queue)나 스택(stack) 구현에 적합합니다.

  • Set
    중복을 허용하지 않는 집합으로, 멤버 존재 여부 확인이 빠르며, 교집합, 합집합, 차집합 연산도 지원합니다.

  • Sorted Set
    각 원소에 점수를 부여해 정렬 상태를 유지하며, 랭킹 시스템에 주로 사용됩니다.

  • Hash
    필드와 값의 쌍으로 데이터를 저장해, RDBMS의 테이블 레코드와 비슷한 역할을 합니다.

Redis 데이터 모델링 가이드

Redis는 RDBMS와 달리 제약조건이 없고, Key-Value 형태로 데이터를 저장하므로 데이터 모델링 시 아래를 고려해야 합니다

  • Hash-Hash 모델
    부모-자식 관계를 해시로 표현 (예: 주문-운송 정보)

  • Hash-List 모델
    마스터-디테일 관계를 해시와 리스트로 표현 (예: 주문 정보와 주문 상세 리스트)

  • Set/Sorted Set-List 모델
    트리 구조 표현에 활용 (예: 댓글과 대댓글)

  • List-List 모델
    N:M 관계 표현 가능

  • 데이터는 논리적으로 여러 DB에 분산 저장하여 성능과 장애 복구에 유리하도록 설계

Redis 명령어 예시

# String
SET user:1:name "Alice"
GET user:1:name

# List
LPUSH tasks "task1"
RPUSH tasks "task2"
LPOP tasks
LRANGE tasks 0 -1

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

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

# Hash
HSET user:1 age 30 name "Alice"
HGETALL user:1

# 만료 시간 설정
EXPIRE user:1 3600

# 키 삭제
DEL user:1

Redis 아키텍처 및 내부 구조

  • Redis는 키를 해시 테이블(dict)로 관리하며, 각 키의 값은 내부적으로 다양한 데이터 구조(예: Ziplist, Quicklist, Skiplist 등)로 인코딩됩니다.

  • 싱글 스레드 기반으로 명령어를 순차 처리하며, 내부적으로 효율적인 자료구조를 사용해 빠른 성능을 보장합니다.

  • 클러스터 환경에서는 키 공간을 해시 슬롯으로 분할해 여러 노드에 분산 저장하며, 마스터-슬레이브 복제를 통해 장애 대응 및 데이터 안정성을 확보합니다.

Redis 활용 사례

  • 캐시 시스템
    DB 부하 감소 및 빠른 응답 속도 제공

  • 세션 저장소
    웹 애플리케이션의 로그인 세션 관리

  • 실시간 데이터 처리
    채팅, 알림, 실시간 랭킹, 대기열 관리

  • 분산 락 구현
    여러 서버 간 자원 접근 동기화

  • 통계 집계 및 카운터
    페이지뷰, 좋아요 수 등 빠른 집계

Spring Boot 연동 방법

1. 의존성 추가 (build.gradle)

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

2. 설정 파일 (application.yml)

spring:
  redis:
    host: localhost
    port: 6379
    password: your-password # 설정 시
    lettuce:
      pool:
        max-active: 8
        max-idle: 8

3. RedisTemplate 구성

@Configuration
public class RedisConfig {

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

4. 데이터 액세스 예제

@Service
public class UserService {

    private final RedisTemplate<String, Object> redisTemplate;

    public void saveUser(User user) {
        redisTemplate.opsForValue().set("user:" + user.getId(), user);
    }

    public User getUser(String id) {
        return (User) redisTemplate.opsForValue().get("user:" + id);
    }
}

고급 기능 활용

1. 캐싱 구현

@Cacheable(value = "products", key = "#id")
public Product getProduct(String id) {
    // DB 조회 로직
}

@EnableCaching 어노테이션으로 활성화 후 spring.cache.type=redis 설정 추가

2. Pub/Sub 메시징

@Bean
MessageListenerAdapter listenerAdapter(Receiver receiver) {
    return new MessageListenerAdapter(receiver, "receiveMessage");
}

@Bean
RedisMessageListenerContainer container(RedisConnectionFactory factory) {
    RedisMessageListenerContainer container = new RedisMessageListenerContainer();
    container.setConnectionFactory(factory);
    container.addMessageListener(listenerAdapter, new PatternTopic("chat"));
    return container;
}

3. 세션 저장소

spring:
  session:
    store-type: redis

운영 환경 아키텍처

고가용성 구성

graph LR
A[Client] --> B[Redis Sentinel]
B --> C[Master]
B --> D[Replica 1]
B --> E[Replica 2]
  • Redis Sentinel: 자동 장애 감지 및 마스터 전환

  • Redis Cluster: 16,384개 슬롯을 통한 데이터 분산 저장

성능 최적화

  1. 메모리 관리
    maxmemory-policy allkeys-lru 설정으로 LRU(Least Recently Used) 알고리즘 적용

  2. 파이프라이닝
    다중 명령을 한 번의 네트워크 트립으로 처리

  3. Lua 스크립트
    복잡한 연산을 서버 내에서 실행

  4. 지속성 트레이드오프
    AOF는 데이터 안전성 우수, RDB는 성능 우수

profile
진짜 해보자

0개의 댓글