1. 장애 상태 감지: SDOWN과 ODOWN
Redis Sentinel은 노드의 장애를 감지할 때 두 가지 다른 개념을 사용합니다.
- 주관적 다운 (Subjectively Down, SDOWN): 단일 Sentinel 인스턴스가 특정 서버의 장애를 독립적으로 판단한 상태입니다. 이 상태에서는 페일오버가 발생하지 않습니다.
- 객관적 다운 (Objectively Down, ODOWN): 다수의 Sentinel 인스턴스가 동일한 서버에 대해 SDOWN을 판단하고 합의한 상태입니다. 이 상태가 되어야 마스터 서버에 대한 페일오버가 시작됩니다.
1.1 주관적 다운(SDOWN) 감지 로직
Sentinel은 기본적으로 1초에 한 번씩 명령어 연결이 맺어진 모든 인스턴스(마스터, 레플리카, 다른 Sentinel들)에게 PING 명령을 전송합니다. 응답을 분석하여 노드의 생존 여부를 확인합니다.
PING 명령에 대한 응답은 다음 두 가지로 분류됩니다.
- 유효한 응답:
+PONG,-LOADING,-MASTERDOWN중 하나를 반환하는 경우. - 무효한 응답: 위 세 가지가 아닌 응답을 반환하거나, 설정된 시간 내에 응답이 없는 경우.
sentinel.conf 파일의 down-after-milliseconds 옵션은 인스턴스가 무효한 응답을 보일 때 SDOWN 상태로 전환되기까지의 허용 시간을 정의합니다.
1.1.1 down-after-milliseconds의 적용 범위
이 옵션은 마스터 서버뿐만 아니라, 해당 마스터에 속한 모든 레플리카와 동일한 마스터를 감시하는 다른 Sentinel 인스턴스들의 SDOWN 판단 기준으로도 공통적으로 적용됩니다.
# Sentinel 설정 예시
sentinel monitor primary-node 192.168.1.100 6380 3
sentinel down-after-milliseconds primary-node 30000
위 설정에서 primary-node는 마스터의 이름이며, 포트는 6380입니다. 숫자 3은 ODOWN을 판단하기 위해 필요한 Sentinel의 최소 합의 수를 의미합니다. 30000 밀리초는 마스터, 레플리카, 다른 Sentinel 모두에게 적용되는 SDOWN 타임아웃 값입니다.
1.1.2 Sentinel 간 타임아웃 설정의 비일관성
동일한 마스터를 감시하는 여러 Sentinel이 서로 다른 down-after-milliseconds 값을 가질 수 있습니다. 따라서 한 Sentinel이 마스터를 SDOWN으로 판단하더라도, 다른 Sentinel은 여전히 온라인 상태로 간주할 수 있습니다. 모든 Sentinel이 SDOWN으로 판단해야 비로소 전체적인 SDOWN 상태로 인지됩니다.
1.2 객관적 다운(ODOWN) 확인
Sentinel이 마스터를 SDOWN으로 판단하면, 실제 장애 여부를 확인하기 위해 동일한 마스터를 감시하는 다른 Sentinel들에게 질의합니다. 다수의 Sentinel이 장애에 동의하면 SDOWN에서 ODOWN으로 상태가 변경되며, 페일오버 프로세스가 트리거됩니다. ODOWN은 마스터 서버에만 적용됩니다.
1.2.1 is-master-down-by-addr 명령어
Sentinel 간 통신을 통해 ODOWN을 판단할 때 SENTINEL is-master-down-by-addr 명령어가 사용됩니다.
# 명령어 포맷
SENTINEL is-master-down-by-addr <ip> <port> <current-epoch> <runid>
각 인자는 장애가 의심되는 마스터의 IP, 포트, 리더 선출을 위한 현재 설정 에포크(Epoch), 그리고 리더 선출용 Sentinel의 Run ID(또는 단순 상태 확인을 위한 *)를 나타냅니다.
# 상태 확인 질의 예시
SENTINEL is-master-down-by-addr 192.168.1.100 6380 5 *
마지막 인자가 *이면 단순 장애 확인용이며, 특정 Run ID가 포함되면 리더 선출 투표용입니다. 응답을 받은 Sentinel은 다음 세 가지 정보를 반환합니다.
- down_state: 1은 다운, 0은 업 상태를 의미합니다.
- leader_runid:
*이면 단순 확인, Run ID이면 해당 Sentinel이 지지하는 리더의 ID입니다. - leader_epoch: 리더로 선출된 Sentinel의 설정 에포크입니다.
응답 예: 1 * 5. 이는 다른 Sentinel도 마스터의 다운 상태에 동의함을 의미합니다. 질의한 Sentinel은 동의한 Sentinel의 수를 집계하며, 이 수가 설정된 쿼럼에 도달하면 ODOWN으로 간주하고 페일오버를 진행합니다.
2. 리더 Sentinel 선출
마스터가 ODOWN 상태로 판단되면, 해당 마스터를 감시하는 Sentinel 클러스터는 Raft 알고리즘과 유사한 방식을 통해 리더 Sentinel을 선출합니다. 선출된 리더 Sentinel만이 마스터의 페일오버 작업을 수행할 권한을 가집니다.
3. 자동 페일오버(Failover) 프로세스
리더 Sentinel이 선출되면 다음 세 단계의 페일오버를 수행합니다.
- 최적의 레플리카 선출 및 승격: 다운된 마스터의 레플리카 중 엄격한 필터링(다운 상태, 5초 내
INFO응답 없음, 마스터와의 연결 끊김 시간이down-after-milliseconds * 10초과 등)을 거쳐 가장 우수한 레플리카를 선택합니다. 선택된 레플리카에게REPLICAOF NO ONE명령을 전송하여 새로운 마스터로 승격시킵니다. - 다른 레플리카들의 복제 대상 변경: 리더 Sentinel은 나머지 레플리카들에게
REPLICAOF명령을 전송하여, 새로 승격된 마스터를 복제하도록 지시합니다. - 구 마스터의 레플리카 강등: 원래 다운되었던 마스터가 네트워크 장애 등에서 복구되어 다시 온라인 상태가 되면, Sentinel은 해당 서버에게
REPLICAOF명령을 전송하여 새로운 마스터의 레플리카로 편입시킵니다.
4. Sentinel 핵심 동작 원리
- Sentinel은 특수 모드로 실행되는 Redis 서버로, 일반 모드와 다른 명령어 집합을 사용합니다.
sentinel.conf를 로드하여 감시할 각 마스터에 대한 인스턴스 구조를 생성하고, 명령어 연결과 구독 연결을 설정합니다.- 마스터로부터
INFO명령의 응답을 통해 레플리카의 토폴로지를 파악하고, 각 레플리카에 대한 연결도 추가로 생성합니다. - 일반적으로 10초 주기로
INFO명령을 전송하지만, 마스터가 다운되었거나 페일오버 중일 때는 1초 주기로 변경됩니다. - 동일한 마스터를 감시하는 Sentinel들은 2초 주기로
__sentinel__:hello채널에 메시지를 발행하여 자신의 존재를 알립니다. - Sentinel 간에는 명령어 연결만 생성하며, 마스터와 레플리카와는 명령어 및 구독 연결을 모두 생성합니다.
- 1초 주기의
PING명령을 통해 각 노드의 생존 여부를 확인하고, 타임아웃 발생 시 SDOWN을 판단합니다. - SDOWN 판단 후 다른 Sentinel들에게 투표를 요청하여 쿼럼을 충족하면 ODOWN으로 전환하고 페일오버를 실행합니다.