트래픽이 늘어 Redis 읽기 부하가 커졌습니다. 쓰기는 하나의 Master에서 처리하고, 읽기는 여러 Replica에 분산하면 부하를 줄일 수 있습니다. Redis 복제가 이 구조를 가능하게 합니다.
┌─── Replica 1 (읽기 전용)
Master (쓰기) ───┤─── Replica 2 (읽기 전용)
└─── Replica 3 (읽기 전용)
Master에 쓰면 모든 Replica에 자동으로 동기화됩니다. 읽기 요청은 Replica에서 처리합니다.
# Replica의 redis.conf
replicaof 192.168.1.100 6379
# Master IP와 포트 지정
# 또는 런타임에 설정
REPLICAOF 192.168.1.100 6379
# Master에서
INFO replication
# role:master
# connected_slaves:2
# slave0:ip=192.168.1.101,port=6379,state=online,offset=12345,lag=0
# slave1:ip=192.168.1.102,port=6379,state=online,offset=12340,lag=1
# Replica에서
INFO replication
# role:slave
# master_host:192.168.1.100
# master_port:6379
# master_link_status:up
# master_last_io_seconds_ago:0
# master_sync_in_progress:0
# slave_repl_offset:12345
1. Replica → Master: SYNC 요청
2. Master: BGSAVE로 RDB 스냅샷 생성
3. Master → Replica: RDB 파일 전송
4. Replica: RDB 로드
5. 그동안 쌓인 Write 명령 전송 (Replication Buffer)
6. 이후 실시간 동기화
연결이 끊어졌다 재연결될 때 변경된 부분만 동기화합니다.
Master: "offset 12340 이후 변경분 보내줄게"
Replica: "12340~12345 받음"
Redis 복제는 기본적으로 비동기입니다. Master가 Write를 완료하고 응답을 보낸 뒤, Replica에 비동기로 전파합니다. 성능이 높지만 Master 장애 시 Replica에 전파되지 않은 데이터가 손실될 수 있습니다.
클라이언트 → Master: SET key "value"
Master → 클라이언트: OK (즉시 응답)
Master → Replica: SET key "value" (비동기, 약간 늦을 수 있음)
이를 허용 못 하면 WAIT 명령으로 동기화를 강제합니다.
# 1개 이상의 Replica에 동기화될 때까지 최대 1초 대기
WAIT 1 1000
import Redis from "ioredis";
import { Cluster } from "ioredis";
// 쓰기용 Master 연결
const master = new Redis({ host: "192.168.1.100", port: 6379 });
// 읽기용 Replica 연결
const replicas = [
new Redis({ host: "192.168.1.101", port: 6379 }),
new Redis({ host: "192.168.1.102", port: 6379 }),
];
let replicaIndex = 0;
function getReadClient(): Redis {
const client = replicas[replicaIndex % replicas.length];
replicaIndex++;
return client;
}
// 쓰기
await master.set("user:1000", "data");
// 읽기 (Replica에서)
const data = await getReadClient().get("user:1000");
Replica가 또 다른 Replica를 가질 수 있습니다. Master의 복제 부하를 줄일 때 씁니다.
Master → Replica 1 → Replica 1-1
→ Replica 1-2
→ Replica 2
# Replica 1-1 설정
REPLICAOF replica1_ip 6379
INFO replication
# slave0: lag=0 ← 동기화 지연 없음
# slave1: lag=3 ← 3초 지연
지연이 크면 Replica에서 오래된 데이터를 읽을 수 있습니다. 실시간성이 중요한 데이터는 Master에서 직접 읽어야 합니다.
| 기능 | 복제 | Sentinel | Cluster |
|---|---|---|---|
| 자동 장애 복구 | 없음 | 있음 | 있음 |
| 읽기 분산 | 있음 | 있음 | 있음 |
| 수평 확장 | 없음 | 없음 | 있음 |
| 설정 복잡도 | 낮음 | 중간 | 높음 |
복제는 고가용성의 기반입니다. 자동 장애 복구를 원하면 Sentinel, 데이터 샤딩이 필요하면 Cluster를 추가로 구성합니다.