본문 바로가기

Dot Database/Redis

[Database] Redis 고가용성을 위한 Sentinel 모드 직접 다뤄보기

    Sentinel 모드

    센티넬 모드에서는 Master 노드가 강제로 종료하면 Slave가 자동으로 Master로 선출되는 기능이 있어 더 유연한 환경을 제공해준다. 주요 기능은 다음과 같다.

    1. 모니터링: 센티널은 Master, Slave들이 제대로 동작하는지 지속적으로 감시한다.
    2. 알림: 감시하고 있는 인스턴스(Master, Slave)들이 failover 되었을 때 Pub/Sub으로 App에 알리거나 Shell Script로 관리자의 이메일이나 SMS로 알릴 수 있다. 
    3. 장애조치(failover): Master가 예상치 않게 다운되었을 때 Slave를 Master로 승격시켜준다. 그리고 Slave가 여러 대 있을 경우 선출되지 못한 Slave들은 새로운 Master로 부터 데이터를 받을 수 있도록 한다. 다운된 Master가 재구동되면 Slave로 전환시켜 새로운 Master의 데이터를 받을 수 있도록 한다.

     

    Sentinel 모드에서는 Master-Slave 노드는 이전 포스팅과 동일하게 띄우고 3개의 노드가 추가로 구성된다. 3개를 띄우는 이유는 Master를 선출할 때 다수결 투표를 하기 위해서 필요한 최소한의 노드 수이기 때문이다. 그래서 무조건 Sentinel 노드는 반반이 나올 수 없도록 홀수 단위로 띄워야 한다.

     

    예로 어떤 하나의 노드가 오버타임으로 인해 Master가 죽었다고 판단할 수 있다. 그러면 다른 Sentinel노드들과 함께 투표가 시작된다. 과반수 이상의 Sentinel 노드가 OK하면 비로소 그 Master 노드는 죽은 것이고 Slave 노드에서 새로운 Master 노드를 선출하게 된다.

     

     

    다음과 같이 운영 환경을 구성해보자.

    • Master 10000
    • Slave 10001
    • Slave 10002
    • Sentinel 11001
    • Sentinel 11002
    • Sentinel 11003

     

    이전 포스팅에서는 redis-cli에서 replicaof 명령어로 Master-Slave 관계를 연결해줬지만 이번에는 모두 conf 파일에 설정 값을 넣어서 설정할 것이다. brew redis 설치한 경우 /usr/local/etc/에 기본 설정 파일들이 있다. (redis.conf, redis-sentinel.conf) 이를 모두 복사해준다.

     

    $ cp redis.conf ./10000~10002.conf

    $ cp redis-sentinel.conf ./11001~11003.conf

     

    Master, Slave 설정 및 실행 (10000~10002.conf)

    원래 비밀번호를 설정할 때는 requirepass는 Master 노드 설정에, masterauth는 Slave 노드 설정에 해줘야 한다. 그런데 Sentinel 모드에서는 누가 Master가 될지 모르기 때문에  모든 설정 파일에  masterauth, requriepass를 넣어줘야 한다. 

    • 그리고 기존에 세팅된 포트 설정(6379)이 있으므로 해당 부분은 주석 처리해야 한다.
    > port 10000~10002 # 각 port에 맞게 입력
    > replicaof 127.0.0.1 10000 # 10001, 10002 slave만 추가
    > masterauth {password}
    > requirepass {password}

     

    10000~10002.conf

     

    그러면 정상적으로 구동된다. redis-cli -p {port} -a {password} 로 접속하여 info 명령어를 입력해보면 자신이 master인지 slave인지 확인할 수 있다.

     

    redis-cli info

     

    Sentinel 설정 및 실행 (11001 ~ 11003.conf)

    redis-sentinel.conf도 기존으로 설정해놓은 파일이 있어서 주석처리 해줘야 한다.

    • sentinel monitor mymaster <master ip> <port> <quorum>: Master 노드의 ip와 port를 입력해준다. 복제 노드는 마스터에서 정보를 가져온다. 마지막 숫자 quorum은 의사 진행에 필요한 센티널 노드 개수이다. 즉, 과반수 최소 인원이라고 보면 된다. 구성한 센티널 노드의 수는 총 3개이므로 2로 설정해준다.
    • sentinel down-after-milliseconds mymaster <millsecs>: 단위는 miilsecond이다. 이 값은 마스터가 다운되었다고 인지하는 시간이다. 센티널은 Master에게 정기적으로 PING을 보내는데 이 시간동안 응답이 없을 경우 다운된 것으로 판단하고 장애조치(failover) 작업을 시작한다. default는 30초로 굉장히 긴 편이다. 
    • sentinel auth-pass mymaster <password>: Master 인스턴스에 접속하기 위해 패스워드를 넣어준다. requirepass 값을 넣어주면 된다. 

     

    11001 ~ 11003.conf

     

    Sentinel 노드 3개를 구동시킨다. 그러면 다음과 같이 실행된 화면을 확인할 수 있다.

     

    sentinel 실행

     

     

    Master 다운, Sentinel이 Slave에서 새로운 Master 선출

    1. 강제로 Master노드 다운시키기

    그럼 이제 Master를 직접 다운시켜보자. 그러면 Slave 노드들은 잠시동안 Master와 싱크 연결이 안되기 때문에 에러 로그가 발생한다.

     

    Master 다운

     

    2. Sentinel이 새로운 Master 선출

    그러나 금방 Sentinel이 Master가 제대로 된 응답이 없다는 것을 감지하여 합의 알고리즘에 의헤 새로운 Slave를 Master로 뽑는 것을 확인할 수 있다. Sentinel에서 실행되는 로그를 보면 sdown에서 2명이상 이상을 감지하면 odown으로 바뀌면서 vote-for-leader로 Master를 선출하는 것을 확인할 수 있다.

    • sdown(subjectively down condition): 주관적인 다운 상태이다. 잠시 네트워크 단절 등으로 인해 일시적인 현상일 수 있으므로 우선 sdown 상태가 된다.
    • odown(objectively down condition): sdown 상태인 Sentinel들이 많이자면 odown 상태로 바뀐다. 이때부터 실질적은 failover 작업이 시작된다.

     

    새로운 Master 선출

     

    3. 새로운 Master 선출 및 자동으로 설정 값 변경

    남은 11001, 11002의 info를 확인해보면 11001이 Master 선출되어 있음을 확인할 수 있다. 그리고 slave, sentinel 설정 파일에 있는 Master에 대한 정보도 변경되어 있다.

     

    slave 설정 변경

     

    sentinel 설정 변경

     

    다운된 Master를 재구동하면?

    다운된 Master를 다시 구동시키면 어떻게 될까? 처음에는 Master로 구동된다. 10초 후에 Sentinel이 해당 노드를 10001의 Slave로 전환시킨다.

    • config rewrite가 실행되어 10000.conf에 'replicaof 127.0.0.1 10001'이 기록된다.
    Master(10000) → DOWN    → 재구동시 센티넬에 의해 Slave로 변경
    Slave(10001)    → 마스터로 승격

     

    10000 노드 info

     

    Redis 운영모드를 이해하기 위해 가볍게 Sentinel 모드를 다뤄봤다. 운영 환경에서는 반드시 위와 같이 장애에 대응할 수 있는 서버 구성을 가져야 한다.


    참고

    https://redis.io/docs/manual/sentinel/

    http://redisgate.kr/redis/sentinel/sentinel_auth-pass.php

    http://redisgate.kr/redis/sentinel/sentinel.php

    https://coding-start.tistory.com/127