Redis Cluster 정리, 단일 Redis의 한계와 필요성 이해하기 (1)


단일 Redis의 한계와 Redis Cluster를 쓰는 이유

Redis를 처음 사용할 때는 대부분 단일 서버로 시작한다.

캐시를 저장하거나, 세션을 관리하거나, 임시 데이터를 빠르게 조회해야 할 때 Redis 한 대만 있어도 충분한 경우가 많다.

구조도 단순하다.

App Server -> Redis
 

애플리케이션 서버에서 Redis로 요청을 보내고, Redis는 메모리에 있는 데이터를 빠르게 읽고 쓴다.

처음에는 이 구조가 가장 편하다.
운영도 단순하고, 설정도 복잡하지 않고, 성능도 충분히 빠르다.

그런데 서비스가 커지면 조금씩 고민이 생긴다.

Redis 한 대로 계속 버틸 수 있을까?
Redis 메모리가 부족해지면 어떻게 해야 할까?
요청이 많아졌을 때 Redis 한 대가 병목이 되지는 않을까?
Redis 서버 한 대가 죽으면 서비스는 어떻게 될까?

이런 문제를 해결하기 위해 등장하는 구조가 Redis Cluster다.

Redis 한 대로 쓰면 뭐가 문제일까?

단일 Redis 구조의 가장 큰 장점은 단순함이다.

하지만 단순한 만큼 한계도 명확하다.

크게 보면 세 가지 문제가 있다.

1. 메모리 한계
2. 트래픽 집중
3. 장애 대응 문제
 

Redis는 기본적으로 메모리 기반 저장소다.
그래서 저장할 수 있는 데이터 크기는 결국 Redis 서버 한 대의 메모리 크기에 영향을 받는다.

예를 들어 Redis 서버 한 대에 16GB 메모리가 있다면, 그 안에서 데이터를 관리해야 한다.
데이터가 점점 많아지면 메모리 부족 문제가 생길 수 있다.

물론 maxmemory 정책을 설정해서 오래된 key를 삭제하거나, 잘 쓰지 않는 데이터를 제거할 수는 있다.
하지만 그것만으로 해결되지 않는 경우도 있다.

데이터 자체가 많아지면 결국 Redis 한 대에 모두 담는 구조가 부담스러워진다.

두 번째는 트래픽 문제다.

Redis가 빠르다고 해도 모든 요청이 한 서버로 몰리면 Redis 한 대가 모든 부하를 처리해야 한다.

App Server 1 \
App Server 2  -> Redis 1대
App Server 3 /
 

초기에는 문제가 없을 수 있다.

하지만 서버가 늘고, 요청이 많아지고, Redis를 사용하는 기능이 많아지면 Redis도 병목 지점이 될 수 있다.

세 번째는 장애 대응이다.

Redis를 단순 캐시로만 사용하고 있다면 Redis 장애가 나도 DB에서 다시 조회하도록 만들 수 있다.

하지만 Redis를 세션, 접속 상태, 인증 토큰, 랭킹, 실시간 데이터 처리 등에 사용하고 있다면 이야기가 달라진다.

Redis 한 대가 죽었을 때 영향 범위가 꽤 커질 수 있다.

Redis Cluster는 무엇을 해결하려는 구조일까?

Redis Cluster는 여러 Redis 노드를 하나의 클러스터처럼 묶어서 사용하는 구조다.

App Server
   |
Redis Cluster
   |
+----------+----------+----------+
| Node A   | Node B   | Node C   |
+----------+----------+----------+
 

Redis Cluster가 해결하려는 핵심은 크게 두 가지다.

1. 데이터를 여러 노드에 나눠 저장한다.
2. 특정 노드에 장애가 나도 Replica를 통해 복구할 수 있게 한다.
 

즉 Redis Cluster는 단순히 Redis 서버를 여러 대 띄우는 것이 아니다.

데이터를 어떤 기준으로 나눌지,
각 Redis 노드가 어떤 데이터를 담당할지,
장애가 발생했을 때 어떤 노드가 대신 처리할지까지 포함하는 구조다.

이때 Redis Cluster에서 데이터를 나누는 기준이 바로 Hash Slot이다.

Redis Cluster는 key 단위로 데이터를 나눈다

Redis Cluster는 데이터를 테이블 단위로 나누지 않는다.

DB처럼 특정 테이블을 A 서버에 두고, 다른 테이블을 B 서버에 두는 방식이 아니다.

Redis Cluster는 기본적으로 key 단위로 데이터를 나눈다.

예를 들어 이런 key들이 있다고 해보자.

SET user:1 "jian"
SET order:10 "paid"
SET product:5 "keyboard"
 

Redis Cluster에서는 이 key들이 모두 같은 Redis 노드에 저장되지 않을 수 있다.

user:1    -> Node A
order:10  -> Node B
product:5 -> Node C
 

이렇게 key를 기준으로 데이터를 여러 Redis 노드에 나눠 저장한다.

그래서 Redis 한 대에 모든 데이터를 저장하는 것보다 더 큰 데이터를 다룰 수 있고, 요청도 여러 노드로 분산될 수 있다.

Redis Cluster에서 자주 나오는 용어

Redis Cluster를 이해할 때 자주 나오는 용어가 몇 가지 있다.

처음부터 다 깊게 이해할 필요는 없지만, 이런 단어들이 나온다는 정도는 알고 가면 좋다.

Hash Slot
Master
Replica
MOVED
CROSSSLOT
Failover
 

하나씩 간단히 보면 이렇다.

Hash Slot은 Redis Cluster가 데이터를 나누는 기준이다.
Redis Cluster는 전체 key 공간을 16,384개의 slot으로 나누고, 각 Master 노드가 이 slot들을 나눠 가진다.

Master는 실제 데이터를 저장하고 요청을 처리하는 노드다.

Replica는 Master 데이터를 복제해두는 노드다.
Master에 장애가 발생하면 Replica가 새로운 Master로 승격될 수 있다.

MOVED는 클라이언트가 잘못된 노드로 요청했을 때 Redis가 알려주는 응답이다.
“이 key는 내가 아니라 다른 노드가 가지고 있다”는 의미다.

CROSSSLOT은 여러 key를 한 번에 다루려고 할 때, 그 key들이 서로 다른 slot에 있으면 발생할 수 있는 에러다.

Failover는 Master 장애 시 Replica가 Master로 승격되는 과정이다.

이 중에서 1편에서는 Redis Cluster가 왜 필요한지만 정리하고, 다음 글부터 Hash Slot과 Master Replica 구조를 조금 더 자세히 정리해보려고 한다.

Redis Cluster는 무조건 써야 할까?

그렇지는 않다.

Redis Cluster는 강력하지만, 운영 복잡도도 같이 올라간다.

작은 서비스나 내부용 서비스라면 단일 Redis만으로 충분할 수 있다.
또는 단일 Master와 Replica, Sentinel 구조만으로도 충분한 경우가 있다.

Redis Cluster를 도입하면 key 설계도 신경 써야 하고, 클라이언트 라이브러리도 Cluster를 제대로 지원해야 한다.

특히 여러 key를 한 번에 다루는 명령어를 많이 사용한다면 Redis Cluster에서는 제약이 생길 수 있다.

그래서 Redis Cluster는 “좋아 보이니까 일단 쓰자”보다는, 다음과 같은 상황에서 고려하는 게 맞다고 생각한다.

- Redis 데이터가 한 서버 메모리로 감당하기 어려운 경우
- Redis 요청 부하를 여러 노드로 나누고 싶은 경우
- Redis 장애 시 자동 복구 구조가 필요한 경우
- Redis를 서비스 핵심 흐름에서 많이 사용하는 경우

 

마무리

Redis Cluster는 Redis를 여러 대로 나눠 사용하는 구조다.

하지만 단순히 서버를 여러 대 띄우는 것이 아니라, 데이터를 어떤 기준으로 나누고, 장애가 났을 때 어떻게 이어갈지까지 포함하는 구조다.

단일 Redis는 단순하고 빠르지만, 데이터가 많아지고 트래픽이 늘어나고 장애 대응까지 고려해야 하는 순간 한계가 생길 수 있다.

이때 Redis Cluster를 사용하면 데이터를 여러 노드에 분산할 수 있고, Replica를 통해 장애 상황에도 대응할 수 있다.

이번 글에서는 Redis Cluster가 왜 필요한지, 단일 Redis의 한계가 무엇인지 정리했다.

다음 글에서는 Redis Cluster의 핵심인 Hash Slot을 중심으로, Redis가 데이터를 실제로 어떻게 나눠 저장하는지 정리해보려고 한다.

 

작업 기록과 샘플 코드는 GitHub에도 정리해두고 있어요.

GitHub 팔로우

Continue Reading

이전 글 / 다음 글