본문 바로가기
J-H-T/Redis

[REDIS-6단계] Master/Replica + Sentinel 환경에서 동기화!

by METAVERSE STORY 2026. 8. 17.
반응형

 

 

이제 6단계 — Master/Replica + Sentinel 환경에서 RedisShake 동기화로 넘어가겠습니다.
이번에는 구조가 Standalone보다 한 단계 복잡해집니다. 이유는 “현재 Master가 누구인지”가 장애 시 바뀔 수 있기 때문입니다.

 

🟥 6단계 — Master/Replica + Sentinel 환경에서 동기화

핵심 구조부터 보겠습니다.

                    Application
                         │
                         ▼
                    Redis Master
                         │
                         │ Native Replication
                         ▼
                    Redis Replica

          Sentinel 1 / Sentinel 2 / Sentinel 3
                  ↘    ↓    ↙
               Master 상태 감시
               장애 시 Failover

그리고 RedisShake는

Source Redis
     │
     ▼
RedisShake
     │
     ▼
Target Redis

Redis Sentinel은 Redis 데이터를 저장하는 DB가 아니라,
현재 Master/Replica 상태를 감시하고 장애 시 Replica를 새 Master로 승격시키는 HA 구성요소입니다.
또한 Client에게 “현재 Master 주소가 어디인지” 알려주는 Service Discovery 역할도 합니다. Redis


 

6.1 먼저 Master / Replica 구조부터

가장 기본적인 구조는:

Master
 │
 │ Replication
 ▼
Replica

입니다.

Master는 일반적으로:

Read
Write
Replication Source

역할을 하고,

Replica는:

Master 데이터 복제
장애 대비
읽기 분산 가능

역할을 합니다.

Redis replication은 Master에서 발생한 변경 명령을 Replica로 비동기 전송하고, 연결이 끊겼다가 복구되면 Partial Resync를 시도하며, 불가능하면 Full Resync를 수행합니다. Redis


 

6.2 Sentinel이 추가되면 뭐가 달라질까?

Sentinel이 없으면:

Master 장애

        ↓

관리자가 직접

Replica → Master 승격

해야 할 수 있습니다.

Sentinel이 있으면:

Master 장애
    │
    ▼
Sentinel들이 감지
    │
    ▼
Replica 선택
    │
    ▼
Replica → New Master

가 자동화됩니다. Redis

예:

장애 전

redis-0 = Master
redis-1 = Replica


Master 장애


장애 후

redis-0 = Down
redis-1 = New Master

 

6.3 보통 Sentinel도 여러 개 둔다

Sentinel 하나만 있으면 Sentinel 자체가 SPOF가 될 수 있습니다.

그래서 일반적으로:

Sentinel-0
Sentinel-1
Sentinel-2

처럼 여러 Sentinel을 둡니다.

K8s라면 예:

redis-0
redis-1

sentinel-0
sentinel-1
sentinel-2

형태입니다.

Redis 공식 HA 가이드도 다수 Sentinel이 Master 상태를 판단하고 Failover를 수행하는 구조를 설명합니다. Redis


 

6.4 이제 RedisShake를 어디에 붙일까?

여기가 핵심입니다.

가장 먼저 떠오르는 구조는:

Master
   │
   ▼
RedisShake

입니다.

sync_reader는 Source Master에 Replica처럼 연결합니다.
RedisShake 공식 문서도 sync_reader가 Master에 Slave/Replica처럼 붙어서 RDB Full + Incremental AOF Stream을 받는다고 설명합니다. Tair Open Source

하지만 Sentinel 환경에서는 이 방법에 주의사항이 있습니다.


 

6.5 왜 Sentinel Master에 RedisShake를 직접 붙이는 게 주의사항일까? ⚠️

RedisShake가 sync_reader로 Master에 연결하면 Source Redis 입장에서는 RedisShake가 Replica처럼 보일 수 있습니다.

그러면 Sentinel도 RedisShake를 Replica로 인식할 수 있습니다.

즉:

Redis Master
   │
   ├─ 실제 Replica
   │
   └─ RedisShake
        ↑
        Sentinel이 Replica처럼 볼 수 있음

RedisShake 공식 문서는 Sentinel이 관리하는 Master에 sync_reader를 직접 연결하면 RedisShake가 Sentinel에 Slave 노드로 인식돼 예상치 못한 문제가 발생할 수 있으므로, 가능하면 Replica를 Source로 선택하라고 명시합니다. Tair Open Source

이게 Sentinel 환경에서 가장 중요한 주의사항입니다.


 

6.6 그래서 권장 구조는?

가능하면 Source의 Replica를 RedisShake Source로 사용하는 방향을 우선 검토합니다.

                     Master
                       │
                Native Replication
                       ▼
                    Replica
                       │
                       │ PSync
                       ▼
                  RedisShake
                       │
                       ▼
                  Target Redis

이렇게 하면 운영 Master에 RedisShake Full Sync 부담을 직접 주는 것도 줄일 수 있습니다.

쉽게 말하면:

Master는 서비스용, Replica는 Migration Source용

으로 분리하는 사고방식입니다.


 

6.7 그런데 Replica를 Source로 써도 되나?

RedisShake 관점에서는 PSync 가능한 Redis 인스턴스에서 Full + Incremental 데이터를 받을 수 있느냐가 중요합니다.

Redis replication은 Replica 자체도 Master의 데이터를 지속적으로 복제하고 있습니다. Redis

다만 실무에서는 반드시 확인해야 합니다.

Replica 상태 정상?
Master와 Lag 없는가?
Replica가 최신 데이터인가?
Migration 중 Failover 발생 시 역할이 바뀌지 않는가?

즉 단순히:

Replica니까 무조건 안전

이라고 보면 안 됩니다.


 

6.8 RedisShake 설정 방식은 두 가지

Sentinel 환경에서는 크게 두 가지가 있습니다.

방식 A — Redis 노드 주소를 직접 지정

예:

[sync_reader]
cluster = false
address = "redis-replica.redis.svc.cluster.local:6379"
username = ""
password = "SOURCE_PASSWORD"
tls = false

[redis_writer]
cluster = false
address = "redis-target.redis.svc.cluster.local:6379"

즉 Sentinel을 신경 쓰지 않고:

RedisShake
   │
   ▼
특정 Redis Node

에 직접 연결합니다.

RedisShake 공식 문서에서도 Sentinel 환경에서 Sentinel을 무시하고 Redis 연결정보를 직접 설정하는 방식을 사용할 수 있다고 설명합니다. Tair Open Source


 

6.9 방식 B — Sentinel에서 현재 Master 주소를 받아오기

RedisShake가 Sentinel에게:

"현재 mymaster의 Master가 누구야?"

라고 물을 수 있습니다.

구조:

RedisShake
    │
    ▼
Sentinel
    │
    │ Current Master 조회
    ▼
Redis Master

예제 설정:

[sync_reader]
cluster = false
address = ""
username = ""
password = "redis-password"
tls = false

[sync_reader.sentinel]
master_name = "mymaster"
address = "redis-sentinel.redis.svc.cluster.local:26379"
username = ""
password = ""
tls = false

RedisShake 공식 Sentinel 예제도 address=""로 두고 [sync_reader.sentinel]의 master_name과 Sentinel 주소를 설정하면 RedisShake가 Sentinel에서 현재 Master 주소를 가져오는 방식을 제공합니다. Tair Open Source


 

6.10 master_name이 뭐야?

Sentinel 설정에는 감시 대상 Master 이름이 있습니다.

예:

mymaster

Sentinel에게는:

mymaster
= 이 Redis HA 그룹

이라는 논리적인 이름입니다.

RedisShake는:

master_name = "mymaster"

를 이용해:

Sentinel:
"mymaster의 현재 Master 주소는 어디야?"

라고 조회합니다.

Redis Sentinel 자체도 Client가 Master 그룹 이름을 기준으로 현재 Master 주소를 조회하도록 설계됩니다. Redis


 

6.11 Sentinel Port는 보통 몇 번?

기본적으로 Sentinel은:

26379

포트를 많이 사용합니다.

즉:

Redis
6379

Sentinel
26379

라고 구분해서 기억하면 쉽습니다.

예:

redis-sentinel.redis.svc.cluster.local:26379

 

6.12 K8s에서는 어떤 모양일까?

예를 들어:

Namespace: redis-prod

안에:

redis-0
redis-1

sentinel-0
sentinel-1
sentinel-2

가 있다고 하겠습니다.

구조:

┌─────────────────────────────────┐
│ K8s                             │
│                                 │
│ redis-0                         │
│ Master                          │
│    │                            │
│    ▼                            │
│ redis-1                         │
│ Replica                         │
│                                 │
│ sentinel-0                      │
│ sentinel-1                      │
│ sentinel-2                      │
│     │                           │
│     └── Master/Replica 감시     │
└─────────────────────────────────┘

RedisShake Pod는 다른 Namespace에 있어도 됩니다.

Namespace: redis-migration

redis-shake

 

6.13 네트워크는 무엇이 열려야 하나?

RedisShake가 Sentinel을 사용하는 경우 최소:

RedisShake → Sentinel :26379

RedisShake → Redis :6379

가 필요합니다.

즉:

RedisShake
   │
   ├── TCP 26379 → Sentinel
   │
   └── TCP 6379  → Redis Master/Replica

입니다.

Sentinel에게 Master 주소만 받아온 뒤 실제 데이터는 Redis 노드에서 읽기 때문입니다.


 

6.14 Sentinel이 데이터를 보내주는 건 아니다

이건 중요합니다.

잘못 이해하면:

Sentinel
   │
   ▼
RedisShake
   │
   ▼
Target

처럼 생각할 수 있는데 아닙니다.

정확한 구조는:

RedisShake
    │
    │ ① Master가 누구인지 물음
    ▼
Sentinel

RedisShake
    │
    │ ② 실제 데이터 Sync
    ▼
Redis Master

입니다.

즉 Sentinel은:

주소 안내자 / Failover 관리자

이지 데이터 Source가 아닙니다.


 

6.15 Failover가 일어나면?

예를 들어 처음에는:

redis-0 = Master
redis-1 = Replica

입니다.

Sentinel이 감시합니다.

redis-0 장애
     │
     ▼
Sentinel Failover
     │
     ▼
redis-1 = New Master

Redis Sentinel은 장애를 감지하면 Replica를 Master로 승격하고 나머지 Replica들을 새 Master에 재구성합니다. Redis


 

6.16 그럼 RedisShake는 자동으로 새 Master로 붙나?

여기는 조심해서 이해해야 합니다.

Sentinel 설정을 사용하면 RedisShake는 초기 Master 주소를 Sentinel에서 가져올 수 있습니다. Tair Open Source

하지만 이것을:

“Migration 중 어떤 Failover가 발생해도 장기간 HA Client처럼 완벽하게 자동 추종한다”

라고 이해하면 위험합니다.

RedisShake 공식 문서 자체가 sync_reader의 장기 지속 동기화에는 제약이 있다고 설명합니다. 따라서 Migration 중 Sentinel Failover가 발생하면:

RedisShake 로그
PSync 상태
Replication Offset
새 Master 상태
Target 반영 상태

를 반드시 다시 검증해야 합니다. Tair Open Source


 

6.17 그래서 Migration 중 Failover는 어떻게 대응할까?

실무적으로는:

① Sentinel Failover 발생 확인

② 현재 Master 확인

③ RedisShake 연결 상태 확인

④ Full Resync인지 Partial Resync인지 확인

⑤ Offset / Lag 확인

⑥ Target 데이터 정합성 확인

⑦ 정상 따라잡는지 확인

순으로 봅니다.

단순히 RedisShake Pod가:

Running

이라고 해서 Sync가 정상이라고 판단하면 안 됩니다.


 

6.18 현재 Master 확인 방법

Sentinel에서:

redis-cli \
  -h redis-sentinel.redis.svc.cluster.local \
  -p 26379 \
  SENTINEL get-master-addr-by-name mymaster

개념적 결과:

1) "10.244.1.20"
2) "6379"

입니다.

즉:

mymaster
     ↓
현재 Master
10.244.1.20:6379

을 알아냅니다.

Redis Sentinel은 바로 이 Service Discovery 기능을 공식적으로 제공합니다. Redis


 

6.19 Sentinel 상태 확인

redis-cli \
  -h redis-sentinel.redis.svc.cluster.local \
  -p 26379 \
  SENTINEL masters

Replica 확인:

redis-cli \
  -h redis-sentinel.redis.svc.cluster.local \
  -p 26379 \
  SENTINEL replicas mymaster

이 명령들을 통해:

현재 Master
Replica 목록
Sentinel이 보는 상태

를 확인할 수 있습니다.


 

6.20 Redis 자체 역할도 확인

Master 후보에서:

redis-cli INFO replication

현재 Master라면:

role:master

Replica라면:

role:slave
master_host:...
master_link_status:up

등이 나옵니다.

Redis 공식 INFO 명령은 현재 role, replication ID/offset 등 replication 상태를 제공합니다. Redis


 

6.21 Source Replica 사용 시 확인할 값

예를 들어 RedisShake Source로 redis-1 Replica를 사용한다면:

redis-cli -h redis-1.redis-headless.redis.svc.cluster.local \
  INFO replication

에서 최소한:

role:slave
master_link_status:up
master_sync_in_progress:0

등을 확인합니다.

그리고 Master와의 Lag가 큰 Replica를 Source로 잡으면 안 됩니다.

즉:

Master
현재 데이터

Replica
10분 뒤처짐

       ↓

RedisShake Source

       ❌

가 되면 Target도 뒤처진 데이터에서 시작할 수 있습니다.


 

6.22 Source를 Master로 할지 Replica로 할지 비교

항목Master SourceReplica Source
최신 데이터 ✅ 직접 ✅ 정상 복제 시
Source 운영부하 더 받을 수 있음 상대적으로 분산 가능
Sentinel 오인식 주의 높음 상대적으로 유리
Replica 자체 Lag 영향 없음 있음
Migration 권장 Sentinel 환경에서 우선 검토

RedisShake 공식 문서가 특히 Sentinel이 관리하는 Master에 sync_reader를 직접 붙일 때 RedisShake가 Slave로 인식될 수 있으므로 Replica를 Source로 권장하는 이유가 이 부분입니다. Tair Open Source


 

6.23 Target도 Sentinel이면?

가능합니다.

예:

Source Sentinel HA
        │
        ▼
RedisShake
        │
        ▼
Target Sentinel HA

Target도 현재 Master가 변경될 수 있으므로 RedisShake 공식 예제에서는 Writer 측에도:

[redis_writer]
cluster = false
address = ""

[redis_writer.sentinel]
master_name = "mymaster-target"
address = "target-sentinel:26379"

처럼 Sentinel 설정을 둘 수 있습니다. Tair Open Source


6.24 Source와 Target 둘 다 Sentinel인 전체 설정 예

개념적으로는:

[sync_reader]
cluster = false
address = ""
username = ""
password = "SOURCE_REDIS_PASSWORD"
tls = false
sync_rdb = true
sync_aof = true

[sync_reader.sentinel]
master_name = "source-master"
address = "source-sentinel.redis-source.svc.cluster.local:26379"
username = ""
password = ""
tls = false


[redis_writer]
cluster = false
address = ""
username = ""
password = "TARGET_REDIS_PASSWORD"
tls = false

[redis_writer.sentinel]
master_name = "target-master"
address = "target-sentinel.redis-target.svc.cluster.local:26379"
username = ""
password = ""
tls = false

입니다. RedisShake 공식 Sentinel 예제도 Reader와 Writer 양쪽에 각각 Sentinel 정보를 지정할 수 있는 형태를 제공합니다. Tair Open Source


 

6.25 그런데 Source는 Replica를 직접 쓰는 방식이 더 단순할 수 있다

Migration 용도에서는 오히려:

[sync_reader]
cluster = false
address = "redis-replica.redis-source.svc.cluster.local:6379"

처럼 검증된 Replica 주소를 직접 지정하는 게 운영적으로 더 명확할 수 있습니다.

구조:

Application
     │
     ▼
Source Master
     │
     ▼
Source Replica
     │
     │ RedisShake
     ▼
RedisShake
     │
     ▼
Target

입니다.


 

6.26 가장 중요한 함정: Sentinel Service 하나가 모든 Redis 트래픽을 대신 처리하는 게 아니다

예를 들어:

redis-sentinel:26379

가 있다고 해서 Application 데이터 요청을:

GET user:100
SET user:100 kim

Sentinel에 보내는 게 아닙니다.

Sentinel은:

"현재 Master가 어디냐?"

같은 관리성 요청을 처리합니다.

실제 데이터:

GET
SET
HSET
DEL

은 Redis Master의:

6379

로 갑니다.


 

6.27 Kubernetes 전체 구조로 보면

                On-Premises Kubernetes

┌───────────────────────────────────────────────┐
│                                               │
│                   Application                 │
│                       │                       │
│                       ▼                       │
│                  redis-0                     │
│                  Master                      │
│                     │                         │
│                     │ Native Replication      │
│                     ▼                         │
│                  redis-1                     │
│                  Replica                     │
│                     │                         │
│        ┌────────────┴────────────┐            │
│        │                         │            │
│    Sentinel-0                Sentinel-1       │
│        │                         │            │
│               Sentinel-2                     │
│                                               │
│             상태 감시 / Failover             │
│                                               │
│                  redis-1                     │
│                     │                         │
│                     │ PSync                   │
│                     ▼                         │
│              RedisShake Pod                  │
│                     │                         │
│                     ▼                         │
│               Target Redis                   │
│                                               │
└───────────────────────────────────────────────┘

 

6.28 실제 동기화 흐름

정상 상태:

STEP 1

Master
  │
  ▼
Replica

Replica가 최신 상태를 유지합니다.

그 다음:

STEP 2

Replica
  │
  │ PSync
  ▼
RedisShake

그리고:

STEP 3

RedisShake
  │
  ▼
Target

즉 최종적으로:

Master
  │
  │ Redis Native Replication
  ▼
Replica
  │
  │ RedisShake PSync
  ▼
RedisShake
  │
  │ Writer
  ▼
Target

라는 2단 복제 경로가 됩니다.


 

6.29 여기서 Lag도 2단계로 본다 ⭐

이 구조에서는 Lag를 하나만 보면 안 됩니다.

Master
   │
   │ Lag ①
   ▼
Replica
   │
   │ Lag ②
   ▼
RedisShake
   │
   ▼
Target

즉:

Lag ①

Master → Replica

Redis Native Replication Lag

Lag ②

Replica → RedisShake → Target

Migration Lag

입니다.

Replica Source 방식에서는:

최종 Target Lag = Master→Replica 지연 + RedisShake 처리 지연

이라고 이해하는 게 좋습니다.


 

6.30 그래서 Cutover 전에 무엇을 확인해야 하나?

다음 네 가지를 봅니다.

① Master ↔ Replica 정상?
② Replica Lag 충분히 작음?
③ RedisShake Incremental 정상?
④ Target까지 최종 정합성 정상?

하나라도 문제가 있으면 Cutover를 미룹니다.


 

6.31 Sentinel Failover 중에는 특히 조심

예:

Master A
   │
   ▼
Replica B
   │
   ▼
RedisShake

에서 Master A가 죽었습니다.

Master A ❌

Replica B
    ↓
New Master B

그러면 RedisShake가 붙어 있던 노드의 역할 자체가:

Replica → Master

로 바뀔 수 있습니다.

따라서 Failover 발생 시:

redis-cli INFO replication

으로 역할 재확인,

redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster

으로 현재 Master 재확인,

그리고 RedisShake 로그를 확인해야 합니다.


 

6.32 추천 운영 절차

실제 Migration 전에 이렇게 확인하면 좋습니다.

① Sentinel 정상 여부 확인

② 현재 Master 확인

③ Replica 상태 확인

④ Replica Lag 확인

⑤ Migration Source Replica 선정

⑥ RedisShake → Replica TCP 6379 확인

⑦ RedisShake → Target TCP 6379 확인

⑧ RedisShake 실행

⑨ Full Sync 확인

⑩ Incremental 확인

⑪ Sentinel Failover 발생 여부 모니터링

⑫ Cutover 전 최종 정합성 확인

6.33 실무 명령어 세트

현재 Master

redis-cli \
  -h redis-sentinel.redis.svc.cluster.local \
  -p 26379 \
  SENTINEL get-master-addr-by-name mymaster

Replica 목록

redis-cli \
  -h redis-sentinel.redis.svc.cluster.local \
  -p 26379 \
  SENTINEL replicas mymaster

Redis 역할

redis-cli \
  -h redis-1.redis-headless.redis.svc.cluster.local \
  -p 6379 \
  INFO replication

RedisShake 로그

kubectl logs \
  -n redis-migration \
  redis-shake \
  -f

 

6.34 Standalone과 Sentinel 환경 차이

Standalone:

Redis
  │
  ▼
RedisShake

아주 단순합니다.

Sentinel:

              Sentinel
             /   |   \
            /    |    \
        Master → Replica
                   │
                   ▼
               RedisShake

이므로 추가로:

현재 Master가 누구인지
Replica가 최신인지
Failover 발생했는지
Sentinel이 RedisShake를 어떻게 보는지

까지 봐야 합니다.


🎯 6단계 핵심 정리

가장 중요한 내용을 압축하면:

① Sentinel은 데이터 DB가 아니라 HA 관리자입니다.
Master 장애를 감지해 Replica를 새 Master로 승격하고, Client에게 현재 Master 주소를 알려줍니다. Redis

② RedisShake sync_reader는 Source Redis에 Replica처럼 붙습니다.
Full RDB + Incremental Stream을 받습니다. Tair Open Source

③ Sentinel이 관리하는 Master에 RedisShake를 직접 붙이는 것은 주의해야 합니다.
RedisShake가 Sentinel에 Replica로 인식될 수 있어 공식 문서는 가능한 경우 Replica를 Source로 사용하도록 권장합니다. Tair Open Source

④ Sentinel을 직접 RedisShake 설정에 넣을 수도 있습니다.

[sync_reader.sentinel]
master_name = "mymaster"
address = "redis-sentinel:26379"

RedisShake가 Sentinel에서 현재 Master 주소를 가져옵니다. Tair Open Source

⑤ Replica를 Source로 쓰면 Lag를 두 단계로 봐야 합니다.

Master
  │ Lag ①
  ▼
Replica
  │ Lag ②
  ▼
RedisShake
  │
  ▼
Target

즉 Sentinel 환경의 Migration 핵심은:

“현재 Master/Replica 상태가 안정적인지 확인하고, 가능하면 최신 Replica를 Migration Source로 사용하며, Failover 발생 시 RedisShake의 PSync·Offset·Target 정합성을 다시 검증한다.”

다음 6.1단계에서는 이 구조를 실제 K8s YAML 기준으로 Redis Master/Replica + Sentinel Service + RedisShake ConfigMap/Secret까지 합쳐서 보여주면 실무 연결이 훨씬 쉬워집니다.

 

 

반응형

댓글