Redis

Redis Sentinel

김 정출 2024. 10. 13. 13:48

Redis Sentinel

Redis Sentinel은 Redis 클러스터의 가용성과 신뢰성을 높이기 위한 모니터링 및 자동 장애 조치(failover) 시스템입니다. Redis는 고성능의 인메모리 데이터 구조 저장소로 사용되지만, 단일 Redis 인스턴스의 장애가 전체 서비스 중단으로 이어질 수 있기 때문에 Sentinel이 필요합니다. 아래에서 Redis Sentinel의 주요 기능, 구성 요소, 작동 원리 및 설정 방법에 대해 상세히 설명하겠습니다.


1. Redis Sentinel의 주요 기능

  • 모니터링(Monitoring): Sentinel은 Redis 마스터 및 슬레이브 인스턴스를 모니터링하여 상태를 확인합니다. 이를 통해 인스턴스가 정상적으로 작동하는지 지속적으로 체크합니다.
  • 장애 조치(Failover): Sentinel이 마스터 인스턴스에 장애가 발생했다고 판단하면, 자동으로 슬레이브 중 하나를 새로운 마스터로 승격시키고 클라이언트에게 새 마스터 정보를 전달합니다.
  • 구성 관리(Configuration Management): Sentinel은 Redis 클러스터의 설정을 중앙에서 관리합니다. 클라이언트가 새로운 마스터에 접근할 수 있도록 정보를 갱신합니다.
  • 알림(Notification): Sentinel은 장애 발생 시 관리자가 알림을 받을 수 있도록 설정할 수 있습니다.

2. 구성 요소

  • Sentinel 프로세스: Sentinel은 독립적으로 실행되는 프로세스로, Redis 인스턴스를 모니터링하고 관리합니다. 여러 개의 Sentinel 프로세스가 실행될 수 있으며, 이들은 서로 협력하여 클러스터의 상태를 관리합니다.
  • 마스터(Master): 데이터의 주 복사본을 보유하고 있는 Redis 인스턴스입니다. 클라이언트의 쓰기 요청은 마스터에만 전달됩니다.
  • 슬레이브(Slave): 마스터의 데이터를 복제하는 Redis 인스턴스입니다. 슬레이브는 읽기 요청을 처리할 수 있지만, 쓰기 요청은 마스터에게 전달되어야 합니다.

3. 작동 원리

  1. 모니터링: Sentinel은 설정된 주기로 마스터와 슬레이브 인스턴스의 상태를 확인합니다. 예를 들어, Sentinel은 PING 명령어를 사용하여 Redis 인스턴스의 상태를 점검합니다.
  2. 장애 감지: Sentinel은 지정된 시간 동안 마스터와의 연결이 끊기면 해당 인스턴스를 "불량"으로 간주하고, 이를 다른 Sentinel 프로세스와 공유합니다.
  3. 투표: Sentinel 프로세스들이 협력하여 장애가 발생한 마스터를 확인합니다. 여러 Sentinel 프로세스가 불량 마스터에 대해 투표를 진행하고, 일정 수 이상의 투표가 발생하면 장애가 확정됩니다.
  4. 새로운 마스터 승격: 장애가 확정되면, 슬레이브 중 하나를 선택하여 새로운 마스터로 승격시킵니다. 이 과정에서 Sentinel은 슬레이브를 선택할 때, 최소한의 데이터 손실을 고려합니다.
  5. 구성 업데이트: 새로 승격된 마스터에 대한 정보를 클라이언트에 전달하고, 다른 슬레이브들은 새로운 마스터를 가리키도록 설정합니다.

4. Sentinel 설정 예제

Redis Sentinel을 설정하기 위해서는 여러 개의 Sentinel 설정 파일이 필요합니다. 기본적인 Sentinel 설정 예제는 다음과 같습니다.

# sentinel.conf

# 모니터링할 마스터의 이름, 주소 및 포트
sentinel monitor mymaster 127.0.0.1 6379 2

# Sentinel 자신을 위한 ID와 주소
sentinel sentinel 127.0.0.1 26379

# Sentinel에서 마스터로 간주하기 위한 장애 허용 시간 (밀리초)
sentinel down-after-milliseconds mymaster 5000

# 자동 장애 조치를 위한 최소 Sentinel 수
sentinel quorum mymaster 2

# 클라이언트 연결 시간 초과 (밀리초)
sentinel client-reconfig-script mymaster "/path/to/reconfig_script.sh"

5. Sentinel 사용 시 고려사항

  • Sentinel의 다중 인스턴스 운영: Redis Sentinel은 고가용성을 위해 최소한 3개의 Sentinel 프로세스를 운영하는 것이 좋습니다. 이를 통해 장애 조치 과정에서 가용성을 높일 수 있습니다.
  • 네트워크 분리: Sentinel과 Redis 서버는 서로 다른 네트워크에서 실행되는 것이 좋습니다. 이를 통해 네트워크 장애 발생 시 Sentinel이 계속해서 작동할 수 있습니다.
  • 모니터링 및 알림: Sentinel을 설정할 때, 관리자가 장애 상황을 인지할 수 있도록 알림 기능을 설정하는 것이 중요합니다.

6. Redis Sentinel과 Client

Redis Sentinel을 사용할 때, 클라이언트가 Redis 서버에 접근하는 방식은 특정한 패턴을 따릅니다. 특히, 쓰기 명령어는 반드시 마스터 인스턴스로 전송되어야 합니다. 다음은 Redis Sentinel 환경에서 클라이언트가 명령어를 처리하는 방식에 대한 자세한 설명입니다.

  1. 클라이언트와 Sentinel의 관계
    • Sentinel의 역할: Sentinel은 Redis 클러스터의 마스터와 슬레이브 인스턴스를 모니터링하고, 장애가 발생했을 때 자동으로 슬레이브를 마스터로 승격시키는 역할을 합니다. 그러나 Sentinel은 데이터에 대한 쓰기 요청을 처리하지 않으며, 클라이언트의 요청을 직접적으로 처리하지 않습니다.
  2. 클라이언트의 접근 방식
  • 마스터 인스턴스에 대한 접근: 클라이언트는 일반적으로 Redis Sentinel에 연결하여 현재 마스터의 주소와 포트를 조회합니다. 그러면 클라이언트는 이 정보를 바탕으로 마스터 인스턴스에 직접 연결하여 쓰기 작업을 수행합니다.
  • 읽기 작업: 읽기 요청은 클라이언트가 마스터 또는 슬레이브 인스턴스에 직접 보낼 수 있습니다. 슬레이브 인스턴스를 사용하면 로드 밸런싱 효과를 누릴 수 있습니다.
  1. 명령어의 흐름
  2. 클라이언트 연결: 클라이언트가 Sentinel에 연결합니다. 이때 Sentinel은 현재 마스터의 정보를 제공합니다.
  3. 마스터 정보 조회:
    • 클라이언트가 Sentinel에 SENTINEL get-master-address-by-name <master-name> 명령어를 보냅니다.
    • Sentinel은 해당 마스터의 IP 주소와 포트를 반환합니다.
  4. 명령어 전송:
    • 클라이언트는 받은 마스터 정보(예: IP와 포트)를 사용하여 해당 마스터 Redis 인스턴스에 직접 연결합니다.
    • 쓰기 명령어는 마스터에게만 전송되며, 예를 들어 SET 명령어는 반드시 마스터에게 보내야 합니다.
  5. Sentinel 주소로의 접근
  • 클라이언트는 Sentinel의 주소를 통해 처음 연결하며, Sentinel로부터 마스터의 주소를 동적으로 얻어와야 합니다.
  • 클라이언트는 이후 마스터 인스턴스에 대한 직접 연결을 통해 읽기 및 쓰기 작업을 수행합니다.

7. go-redis

Go에서 사용하는 go-redis 패키지는 Redis 클라이언트 라이브러리로, Redis 서버와의 명령어 스트림을 자동으로 처리해주는 여러 기능을 제공합니다. 이 패키지는 Sentinel 환경에서도 마스터의 주소를 자동으로 관리하고, 클라이언트의 명령어를 올바른 Redis 인스턴스에 전송하는 작업을 지원합니다. 다음은 go-redis 패키지의 주요 기능 및 Sentinel과의 통합에 대한 자세한 설명입니다.

  1. go-redis 패키지의 기능
  • 자동 마스터 관리: go-redis 패키지는 Sentinel을 사용하여 현재 마스터의 주소를 자동으로 검색하고 관리합니다. 클라이언트는 초기 설정 시 Sentinel에 연결하면, 패키지가 자동으로 마스터 주소를 가져옵니다.
  • 명령어 전송: 클라이언트가 보내는 모든 Redis 명령어(예: SET, GET)는 현재 활성화된 마스터로 자동 전송됩니다. 만약 마스터가 변경되면, 패키지가 이를 감지하고 새로운 마스터에 대한 명령어를 자동으로 전송합니다.
  • 슬레이브 읽기: 읽기 요청을 슬레이브로 보내는 기능도 지원합니다. 이를 통해 읽기 작업의 부하를 분산시킬 수 있습니다.
  1. Sentinel 설정 및 자동 마스터 선택
  • go-redis를 Sentinel과 함께 사용할 때의 기본적인 설정 예제는 다음과 같습니다.
package main

import (
    "github.com/go-redis/redis/v8"
    "context"
    "log"
)

func main() {
    ctx := context.Background()

    // Sentinel 클라이언트 설정
    rdb := redis.NewFailoverClient(&redis.FailoverOptions{
        MasterName:    "mymaster", // Sentinel에서 정의한 마스터 이름
        SentinelAddrs: []string{"127.0.0.1:26377", "127.0.0.1:26378", "127.0.0.1:26379"}, // Sentinel 주소
        Password:      "",          // Redis 마스터 비밀번호 (필요 시)
        DB:           0,            // 사용할 DB 번호
    })

    // 테스트: 값 설정
    err := rdb.Set(ctx, "key", "value", 0).Err()
    if err != nil {
        log.Fatalf("Could not set key: %v", err)
    }

    // 테스트: 값 가져오기
    val, err := rdb.Get(ctx, "key").Result()
    if err != nil {
        log.Fatalf("Could not get key: %v", err)
    }
    log.Printf("Value: %s", val)
}
  1. 내부 동작
  • 명령어 스트림 처리: go-redis는 Redis 명령어를 내부적으로 관리하고, 클라이언트가 입력한 명령어를 자동으로 적절한 Redis 인스턴스에 전달합니다. Sentinel의 마스터 주소가 변경될 때, 라이브러리가 자동으로 새 주소를 사용합니다.
  • 에러 처리: 마스터 인스턴스가 장애를 겪거나 응답하지 않을 경우, go-redis는 이 에러를 감지하고 Sentinel에 요청하여 새로운 마스터를 찾습니다. 그 후, 클라이언트는 새 마스터에 대해 명령어를 전송할 수 있습니다.
  1. 고급 기능
  • 슬레이브의 읽기 요청 분산: 필요에 따라 읽기 요청을 슬레이브 인스턴스에 보내는 기능도 지원합니다. 이는 Options.ReadOnly 설정을 통해 구현할 수 있으며, 이를 통해 읽기 요청의 부하를 슬레이브로 분산시킬 수 있습니다.
  • 연결 풀 관리: go-redis는 Redis에 대한 연결 풀을 관리하여 효율적인 연결 관리를 수행합니다. 여러 개의 요청을 동시에 처리할 수 있습니다.

결론

Redis Sentinel은 Redis 클러스터의 가용성을 높이는 데 필수적인 요소로, 자동으로 장애 조치를 수행하고 인스턴스를 모니터링합니다. Sentinel을 적절히 설정하고 운영하면 Redis 시스템의 신뢰성을 크게 향상시킬 수 있습니다.