Redis SENTINEL NOTIFICATION-SCRIPT

Redis Sentinel 教育
Redis Sentinel Course
Redis 定期点検/技術支援
Redis Technical Support
Redis エンタープライズサーバ
Redis Enterprise Server

Redis SENTINEL NOTIFICATION-SCRIPT Parameter

센티널은 경고(warning) 이벤트가 발생하면 notification_script에 지정된 파일을 실행해서 관리자에게 이메일이나 SMS로 알릴 수 있다.   이 기능은 sentinel.conf 파일에 지정하거나 sentinel set 명령으로 지정할 수 있다.   여기서는 센티널 알림기능에 대해 전반적으로 알아본다.

알림 스크립트 파일

알림 스크립트 파일은 일반적으로 리눅스 쉘(shell) 스크립트로 만든다.   받는 인수는 2개이다. 하나는 이벤트 타입이고 다른 하나는 이벤트 내용이다.   내용은 관련 서버 이름, 주소(IP, Port) 등이다.
아래는 스크립트 파일 예제(notify.sh)이다.

쉘 파일을 만들고 리눅스 chmod 명령으로 실행파일로 변경한다.

# chmod +x notify.sh

이것은 redisgate.com에서 gmail.com으로 보내는 것으로 스크립트 파일이 잘 작성되었는지 확인하기 위해서 직접 실행해보자.   이벤트 타입과 설명은 적당히 등록하자.

# notify.sh "장애조치 시작", "198.56.xxx.xxx 레디스 서버 다운"

MAIL_TO를 바꾸어 가며 받는 메일 몇 개를 테스트해 보았는데, gmail(구글), daum(다음), redisgate(레디스게이트) 메일은 잘 도착했다.   naver(네이버)는 도착하지 않았다.   도착한 사이트도 처음에는 스팸함에 들어갈 수 있으니 확인해본다.

알림 설정

알림 설정은 sentinel set 명령으로 파일을 지정한다.  

127.0.0.1:7111> sentinel set master-name notification-script /var/redis/notify.sh
OK

파일이 없거나 실행파일이 아니면 다음과 같은 에러 메시지가 나온다.

(error) ERR Notification script seems non existing or non executable

실 테스트

실 테스트를 위해서 장애조치(failover)를 진행해보자.   센티널에 접속해서 sentinel failover master-name을 입력한다.   이것은 강제로 장애조치를 진행하는 명령이다.
아래 이미지는 장애조치 후 구글 메일로 온 메일 일부이다.

redis sentinel notification
    그림 1   Redis Sentinel Notification

주의할 것은 이벤트 발생 순서와 메일 도착 순서가 다를수 있다는 것이다.   그리고 리더 센티널이 아닌 옵저버(observer) 센티널이 보낸 메일도 있다.

경고 이벤트 리스트

센티널이 발생시키는 경고 이벤트를 다섯가지 종류로 나눌 수 있다.  

센티널 명령에 의해 발생하는 이벤트

  • +monitor : sentinel monitor 명령 실행으로 monitor 시작
  • -monitor : sentinel remove 명령으로 monitor 해제
  • +set : sentinel set 명령 실행으로 센티널 설정이 변경될 때
  • +reset-master : settinel reset 명령 실행으로 마스터 정보를 리셋

센티널 보호모드 진입/해제 시 발생하는 이벤트

센티널은 1초에 10번에서 19번까지 랜덤으로 센티널 자신이 정상인지 확인한다.

  • +tilt : 보호모드 진입, 운영체제 시간이 뒤로 갔거나 센티널이 2초 동안 아무 동작을 하지 못했을 경우
  • -tilt : 보호모드 해제, 보호모드 진입 후 30초가 지나면 해제

서버 다운에 의해 발생하는 이벤트

  • +sdown : sdown 인지, 대상 서버: 마스터, 슬레이브, 센티널
  • -sdown : sdown 해제, 대상 서버: 마스터, 슬레이브, 센티널
  • +odown : odown 확정, 대상 서버: 마스터
  • -odown : odown 해제, 대상 서버: 마스터

리더(leader) 센티널: 장애조치(failover) 진행 이벤트

  • +new-epoch : 새로운 epoch 시작(장애조치 단계 진입)
  • +try-failover : 장애조치 시도
  • +vote-for-leader : 센티널 리더 선출에 투표
  • +elected-leader : 센티널 리더 선출 완료
  • -failover-abort-not-elected : 시간초과로 센티널 리더 선출 실패
  • +failover-state-select-slave : 새로운 마스터가 될 슬레이브 선정 시작
  • +selected-slave : 새 마스터가 될 슬레이브 선정 완료
  • -failover-abort-no-good-slave : 새 마스터가 될 슬레이브 선정 실패: 조건을 만족하는 슬레이브가 없음
  • -failover-abort-slave-timeout : 새 마스터가 될 슬레이브 선정 실패: 시간초과
  • +promoted-slave : 선정된 슬레이브가 새 마스터로 승격
  • -failover-abort-slave-timeout : 시간초과로 마스터 승격 실패
  • +failover-state-reconf-slaves : 슬레이브들이 새 마스터로 부터 데이터 받기 시작
  • +failover-end : 슬레이브들이 새 마스터로 부터 데이터 받기 완료
  • +failover-end-for-timeout : 슬레이브들이 새 마스터를 바라보도록 slaveof 명령 실행 중 시간초과, 이 경우 완료되지 않는 슬레이브들은 slaveof 명령을 다시 실행한다.
  • +switch-master : 세 마스터로 변경이 완료
  • -script-error : 스크립트 실행 에러, notification-script가 설정되어 있는 경우
  • -script-timeout : 스크립트 실행 시간초과 (60초), notification-script가 설정되어 있는 경우

옵저버(observer) 센티널: 장애조치(failover) 진행 이벤트

  • +new-epoch : 새로운 epoch 시작(장애조치 단계 진입)
  • +vote-for-leader : 센티널 리더 선출에 투표
  • +config-update-from : 다른 센티널로 부터 새 마스터 정보를 받아 갱신 완료, 옵저버(observer) 서버
  • +switch-master : 세 마스터로 변경이 완료

너무 많은 알림 이메일

장애조치가 발생하면 리더 센티널로 부터 약 10개의 이메일을 받고 각 옵저버 센티널로 부터 약 5개의 이메일을 받는다.   센티널이 3대라면 약 20개의 이메일이 거의 동시에 들어온다.   너무 많은 이메일로부터 혼란스러울 경우, 필요한 알림 3개만 받을 수 있도록 스크립트 파일을 수정해 보았다.
1) 장애조치 시작을 알리는 "+try-failover",
2) 새 마스터 승격 "+promoted-slave",
3) 장애조치 완료 "+failover-end"
두 번째 "+promoted-slave"에서 새 마스터를 확인할 수 있다.
이 세 개 이메일은 리더 센티널에서 보내는 것이다. 새 마스터를 확인하기위해서 "+switch-master" 이벤트를 넣을 수도 있으나, 이 이벤트는 옵저버 센티널에서도 발생해서 같은 이메일을 여러번 받게 되므로 제외했다.

여러 사람에게 이메일을 보낼 때는 MAIL_TO에 콤마(,)로 구분해서 이메일 주소를 추가하면 된다.   예를 들면 MAIL_TO="redisgate@gmail.com, name@gmail.com" 이렇게 한다.
이메일이 여러 개 올 때 다음과 같이 보낸 시각을 millisecond단위로 찍을 수 있다.
변수 설정: timestamp=$(date +%D-%T.%3N)
사용: 이메일보낸 시각: $timestamp



스크립트 실행 에러

센티널은 경고 이벤트가 발생하면 센티널 로그를 남기고, 스크립트 잡 큐에 이벤트 타입, 설명을 넣고 스크립트 파일을 실행한다.   센티널 내부에서 실행하는 방법은 자식 프로세스를 fork()하고 자식 프로세스에서 execve()로 스크립트 파일을 실행한다.   execve()는 다른 프로그램을 실행하고 자신은 종료하는 함수이다.

스크립트 에러는 다음과 같이 세 가지 경우이다.

  • 파일이 없는 경우, 실행파일이 아닌 경우, 파일이 실행중 에러나는 경우: 마지막에 "0 2"를 찍는다.
    16:57:13.227 # -script-error /var/redis/notify.sh 0 2
  • fork() 에러일 경우: 마지막에 "99 0"을 찍는다.
    16:57:13.227 # -script-error /var/redis/notify.sh 99 0
  • 시간초과(60초)의 경우: 마지막에 자식 프로세스 ID를 찍는다.
    17:09:43.874 # -script-timeout /var/redis/notify.sh 31412

첫 번째, 두 번째 에러는 재 시도하지 않지만, 세 번째 시간 초과는 10번까지 재 시도한다.   각 재 시도 사이의 공백 시간은 2배씩 늘려간다.   처음 시도 실행한 다음 30초 후에 두 번째 시도한다.   또 실패하면 60초 후, 또 실패하면 2분 후, 4분 후, 8분 후, 16분 후, 32분 후, 64분 후, 마지막 열 번째는 128분 후에 시도한다. 열 번째까지 실패하면 스크립트 잡 큐에서 삭제한다.


대기 또는 실행중인 스크립트 조회

sentinel pending-scripts 명령으로 대기 또는 실행중인 스크립트를 조회할 수 있다.

127.0.0.1:7111> sentinel pending-scripts
1) 1) "argv"
    2) 1) "/var/redis/notify.sh"
        2) "+set"
        3) "master Xmaster 127.0.0.1 7121 failover-timeout 10000"
    3) "flags"
    4) "scheduled"
    5) "pid"
    6) "0"
    7) "run-delay"
    8) "88861"
    9) "retry-num"
   10) "6"

큐에서 대기하거나 실행 중인 스크립트 개수를 info sentinel 명령으로 조회해 볼 수 있다.   시간초과가 되어 종료된 스크립트을 running_scripts에서 빼지 않아 누적된 잘못 계산된 숫자가 나온다.   이는 센티널을 재 시작하지 않는 한 계속 누적되어 나타난다.

127.0.0.1:7111> info sentinel
sentinel_running_scripts: 6 <- 누적된 잘못 계산된 숫자
sentinel_scripts_queue_length: 1

이는 버그로 보이며 sentinelKillTimedoutScripts()에서 아래와 같이 kill()다음에 sentinel.running_scripts--; 를 추가하면 될것이다.



알림 설정 해제

스크립트 설정을 해제할때는 sentinel set 명령에서 마지막 인수(argument)에 ""를 준다.   파일명을 인수로 줄 때는 sentinel.conf에 기록이 되는데, 위와 같이 인수를 주지 않으면 해제는 되지만 sentinel.conf에는 기록되지 않는다.   따라서 설정파일에는 기존 설정이 그대로 남아있으므로 재 시작 전에 확인해서 필요하지 않으면 파일에서 제거해야 한다.

127.0.0.1:7111> sentinel set master-name notification-script ""
OK

큐에 대기중인(pending) 스크립트를 제거하는 방법이 없다.   시간초과가 발생하면 10번을 재 시도하는데 불필요하다고 판단되어도 이를 제거할 방법이 현재로는 없다.   위와 같이 스크립트 설정 해제을 해도 큐에는 계속 남아있는데, "run-delay"가 0으로 세팅되어 비정상적인 형태로 남아있다.

문서 정보

  • 이 문서는 2016년 9월에 버전 3.2.2을 기준으로 만들었습니다.

<< PARALLEL-SYNCS NOTIFICATION-SCRIPT CLIENT-RECONFIG-SCRIPT >>

조회수 :

Email 返事がかかってなれば、メールでお知らせします。