[redis] 레디스 서버 운영

cochocho·2026년 4월 8일

db

목록 보기
6/6
post-thumbnail

Redis 정리: 단일 스레드, Replica, Sentinel, Sharding

Redis는 인메모리(In-Memory) 기반의 Key-Value 저장소이다.
데이터를 메모리에 저장하기 때문에 디스크 기반 저장소보다 매우 빠른 접근 속도를 제공한다.

Redis의 특징

  • 메모리 기반 저장소
    • 데이터 접근 속도가 빠르다.
    • 반면 메모리는 디스크보다 상대적으로 비싸다.
  • 기본적으로 휘발성
    • 전원이 꺼지면 메모리 데이터는 사라질 수 있다.
    • 따라서 필요에 따라 영속성(Persistence) 설정을 통해 데이터를 디스크에 저장해야 한다.
    • 대표 방식으로는 RDB 스냅샷, AOF(Append Only File) 가 있다.
  • Key-Value 구조
    • 데이터를 key - value 형태로 저장한다.
  • 명령 실행 관점에서 주로 단일 스레드
    • Redis는 요청을 순차적으로 처리하는 구조를 통해 락 경쟁을 줄이고, 구현을 단순하게 유지한다.
    • 이로 인해 락 비용, 컨텍스트 스위칭 비용을 줄일 수 있다.
    • 또한 개별 명령은 순차적으로 실행되므로 원자적으로 처리된다.

단일 서버 구조의 한계

Redis를 하나의 서버로만 운영하면, 그 서버가 장애로 다운될 경우 전체 서비스가 영향을 받는다.

즉, 단일 서버 구조는 다음과 같은 문제가 있다.

  • 장애 발생 시 서비스 전체 중단 가능
  • 읽기/쓰기 요청이 하나의 서버에 집중됨
  • 결국 한 서버의 CPU, 메모리 성능 한계에 종속됨

Replica를 통한 고가용성 보완

이러한 문제를 줄이기 위해 복제 구조(Replication) 를 사용할 수 있다.

일반적으로는 다음과 같이 구성한다.

  • Master
    • 쓰기 작업 담당
  • Replica
    • Master의 데이터를 복제받는 읽기 전용 노드

즉 Master에서 데이터 변경이 발생하면, 그 변경 내용이 Replica로 비동기 복제된다.

이 구조의 장점은 다음과 같다.

  • 읽기 요청을 Replica로 분산 가능
  • Master 장애 시 Replica를 활용한 복구 기반 마련
  • 단일 서버보다는 높은 가용성 확보 가능

하지만 이 구조만으로는 한계가 있다.
여전히 실제 쓰기 처리는 하나의 Master가 담당하기 때문이다.


Sentinel: 장애 감지와 자동 Failover

Replica만 두었다고 해서 장애 대응이 자동으로 되는 것은 아니다.
장애를 감지하고, 새로운 Master를 선출하고, 클라이언트가 그 변경을 알 수 있어야 한다.

이 역할을 하는 것이 Redis Sentinel이다.

Sentinel의 주요 역할은 다음과 같다.

  • 모니터링
    • Master와 Replica가 정상 동작 중인지 감시
  • 알림(Notification)
    • 장애 상황 발생 시 외부 시스템에 알림 가능
  • 자동 Failover
    • Master 장애 시 Replica 중 하나를 새로운 Master로 승격
    • 다른 Replica들도 새로운 Master를 바라보도록 재구성
  • 구성 정보 제공
    • 클라이언트가 현재 Master 주소를 조회할 수 있도록 지원

SDown / ODown

Sentinel은 장애를 두 단계로 판단한다.

  • SDown (Subjectively Down)
    • 개별 Sentinel이 해당 Redis 노드가 응답하지 않는다고 주관적으로 판단한 상태
  • ODown (Objectively Down)
    • 일정 수 이상의 Sentinel이 장애에 동의해, 실제 장애로 판단한 상태

Quorum

quorumMaster가 장애라고 판단하기 위해 동의해야 하는 Sentinel 수를 의미한다.

다만 주의할 점은, quorum은 장애 감지 기준이고
실제 failover를 수행하려면 Sentinel 다수결(majority) 도 필요하다는 점이다.

즉:

  • quorum: 장애 판단에 필요한 동의 수
  • majority: 실제 failover 진행에 필요한 승인 수

Sentinel의 의미

Sentinel을 사용하면 다음과 같은 장점이 있다.

  • 사람이 직접 장애를 감시하지 않아도 됨
  • Master 장애 시 자동으로 Replica 승격 가능
  • 클라이언트가 새로운 Master 정보를 조회 가능

단, Sentinel은 Redis Cluster를 사용하지 않는 환경에서의 고가용성 구성이다.


Sentinel + Replica 구조의 한계

Sentinel과 Replica를 도입해도 다음 문제는 여전히 남는다.

  • 쓰기 성능은 여전히 하나의 Master에 의존
  • 데이터 전체가 한 Master에 몰려 있음
  • 결국 단일 서버의 메모리/CPU 한계를 넘기 어렵다

즉, 고가용성은 보완할 수 있지만
수평 확장(Scale-Out) 문제는 해결되지 않는다.

이 한계를 넘기기 위해 등장한 것이 Sharding 이다.


Sharding

Sharding은 데이터를 여러 인스턴스에 분산 저장하는 방식이다.

Redis Cluster에서는 이 Sharding을 Hash Slot 기반으로 구현한다.

동작 방식

Redis Cluster는 전체 키 공간을 16384개의 hash slot으로 나눈다.

각 키는 다음 공식으로 slot 번호가 결정된다.

HASH_SLOT = CRC16(key) mod 16384

즉 각 키는 해시 계산을 통해 특정 slot에 매핑되고,
그 slot을 담당하는 Master 노드에 저장된다.

예를 들어 Master가 3개라면,
16384개의 slot을 세 Master가 나눠서 담당하는 식이다.

이 구조의 장점은 다음과 같다.

  • 데이터 분산 저장 가능
  • 쓰기 부하 분산 가능
  • 메모리 한계를 여러 노드로 확장 가능

Redis Cluster에서는 Sentinel이 필요 없는 이유

Redis Cluster는 Sentinel 없이도 고가용성과 분산 처리를 지원한다.

그 이유는 Cluster 내부 노드들이 서로를 알고 있으며,
주기적으로 상태와 구성 정보를 주고받기 때문이다.

즉 Cluster는 내부적으로 다음을 자체 처리한다.

  • 슬롯 정보 관리
  • 노드 상태 확인
  • 리다이렉션 처리
  • 장애 감지
  • Replica 승격 및 Failover

따라서 Cluster 환경에서는 Sentinel을 따로 두지 않는다.

요청이 잘못된 노드로 갔을 때

클라이언트가 어떤 키에 대해 요청했는데,
현재 연결된 노드가 그 키의 slot 담당 노드가 아닐 수 있다.

이 경우 Redis Cluster는 다음과 같이 동작한다.

해당 노드가 MOVED 또는 ASK 응답을 반환
클라이언트가 실제 slot 담당 노드로 다시 요청

즉, Cluster에서는 키가 속한 slot을 담당하는 노드로 요청이 라우팅된다.

이런 상황은 다음과 같은 경우에 발생할 수 있다.

  • failover 후 slot 담당 노드가 바뀐 경우
  • resharding으로 slot 배치가 바뀐 경우
  • 클라이언트가 오래된 slot 정보를 가지고 있는 경우

Redis Cluster 사용 시 주의점: CROSSSLOT 에러

Redis Cluster에서는 멀티키 연산에 제약이 있다.

예를 들어 MSET, MGET 같은 명령은 여러 키를 한 번에 처리하는 명령인데,
이 키들이 서로 다른 slot에 있으면 처리할 수 없다.

이 경우 다음과 같은 에러가 발생한다.

CROSSSLOT Keys in request don't hash to the same slot

즉, 멀티키 연산은 같은 slot에 속한 키들끼리만 가능하다.

Hash Tag로 해결하기

이 문제를 해결하기 위해 Redis Cluster는 Hash Tag 기능을 제공한다.

키 이름에 {} 를 사용하면,
전체 키가 아니라 중괄호 안의 문자열만 기준으로 slot을 계산한다.

예를 들어:

user:{100}:name
user:{100}:email

이 두 키는 모두 {100}을 기준으로 hash slot이 계산되므로
같은 slot에 저장된다.

따라서 다음과 같이 관련된 여러 키를 같은 slot에 강제로 배치할 수 있다.

user:{100}:name
user:{100}:email
user:{100}:profile

이렇게 설계하면 멀티키 연산에서도 CROSSSLOT 에러를 피할 수 있다.

0개의 댓글