Redis SLAVEOF

<< FLUSHALL REPLICAOF >>

개요 槪要 Outline

SLAVEOF ip port

slaveof ip port 명령은 자신을 지정한 서버의 슬레이브(클론)로 만듭니다.

SLAVEOF NO ONE

slaveof no one 명령은 현재 슬레이브(클론)인 자신을 마스터로 만듭니다.


설명 說明 Explanation

SLAVEOF ip port

7000번과 7001번 서버의 역할(role)은 마스터(master)입니다.   역할(role)을 확인하는 명령은 role입니다.   7001번 서버에 slaveof 명령을 실행한 다음 역할 변경을 확인하겠습니다.

Example

127.0.0.1:7000>role
1) "master"
2) (integer) 170057486
3) (empty list or set)
127.0.0.1:7001>role
1) "master"
2) (integer) 170057472
3) (empty list or set)
127.0.0.1:7001>slaveof 127.0.0.1 7000
OK
127.0.0.1:7001>role
1) "slave"       role of 7001 server
2) "192.168.56.102"       master ip
3) (integer) 7000       master port
4) "connected"       connection status with master
5) (integer) 170058214
127.0.0.1:7000>role
1) "master"       role of 7000 server
2) (integer) 170059236
3) 1) 1) "192.168.56.102"       slave(clone) ip
         2) "7001"       slave(clone) port
         3) "170059236"

다음은 위에서 실행한 명령 전, 후 상태를 이미지로 표현한 것입니다.   슬레이브를 Clone(클론)으로 표기했습니다.

redis slaveof
redis slaveof

여기에 사용한 이미지(그림)은 레디스게이트에서 개발한 Redis Server Administration Tool인 Visual Manager Octo 화면을 캡처한 것입니다.


SLAVEOF NO ONE

현재 슬레이브(클론)인 서버를 마스터로 승격(promote)시킵니다.

Example

127.0.0.1:7001>slaveof no one
OK
127.0.0.1:7001>role
1) "master"
2) (integer) 170060300
3) (empty list or set)

다양한 마스터-슬레이브(클론) 관계

마스터는 아래 그림처럼 여러 개의 클론을 가질 수 있습니다.

redis slaveof multi slaves
redis slaveof multi slaves

클론도 클론를 가질 수 있습니다.

redis slaveof slave of slave
redis slaveof slave of slave

'노예(Slave)' 라는 용어에 대해서

현대에 '노예(Slave)'라는 용어는 적절치 않다고 봅니다. 그것이 IT 분야라고 해도 마찬가지 일 것입니다. 레디스 개발자인 살바토르(Salvatore Sanfilippo)도 이 용어의 문제점을 인정하여 redis.io에 다음과 같은 글(note)을 남겼습니다. 살바토르의 글을 한글로 요약한 것과 원문을 싣습니다.

"레디스를 설계할 때 용어에 대한 충분한 검토없이 마스터-슬레이브라는 용어를 선택하였다. 이것을 고치는데 수정 사항이 많이 발생하여 그대로 두는 대신, 'SLAVEOF NO ONE' 이라는 명령을 만들어 자유 선언에 대한 메시지로 삼으려한다."

A note about slavery: it's unfortunate that originally the master-slave terminology was picked 
for databases.  When Redis was designed the existing terminology was used without much analysis 
of alternatives,  however a SLAVEOF NO ONE command was added as a freedom message. 
Instead of changing the terminology, which would require breaking backward compatibility 
in the API and INFO output, we want to use this page to remind you that slavery is both 
a crime against humanity today and something that has been perpetuated throughout 
all human history.

If slavery is not wrong, nothing is wrong. -- Abraham Lincoln 
원문(slaveof)

따라서 이후부터는 '슬레이브(slave)' 대신 '클론(clone)'이라는 용어를 사용하도록 하겠습니다. 슬레이브에는 복제(replication)라는 의미가 없지만 클론(clone)에는 복제의 의미가 있습니다.   슬레이브 서버의 역할은 '실시간 백업 서버(Real-Time Backup Server)입니다.  

여담으로 'replicatee'라는 용어도 검토해 보았습니다.   Replicatee를 사용한다면 그에 상응하게 master를 replicator라고 해야 하는데 master는 복제(replicate) 기능이 master의 일부 또는 옵션(option)이기 때문에 replicator로 변경하는 것은 적절치 않다고 봅니다.

결국 생명공학(biotechnology) 분야에서 복제의 의미로 많이 사용되는 clone을 slave 대신 사용하기로 하였습니다.   이후부터는 클론(clone)을 사용하도록 하겠습니다.   다만 새 용어에 따른 혼란을 줄이기 위해서 각 페이지의 첫 부분에 클론과 슬레이브를 같이 표기하고 이후에는 클론만 표기하겠습니다.

2017년 2월 7일 권대욱 權大昱 Charlie Kwon


클러스터에서 SLAVEOF에 해당하는 명령은?

클러스터에서 "slaveof ip port"에 해당하는 명령은 "cluster replicate node-id" 입니다.

그럼, "slaveof no one"에 대항하는 명령은 무었일까요?

"cluster reset" 명령입니다.

cluster reset 명령은 클러스터로부터 자신을 독립시키는 명령입니다.   자신이 클론(slave)이라면 클러스터로부터 독립되면서 마스터로 승격됩니다.


센티널과 SLAVEOF

여기서는 센티널 환경에서 slaveof 명령을 실행했을 때 발생하는 다양한 경우를 살펴보겠습니다.
정리된 결론을 우선 보기 원하시면 여기를 클릭하세요.

센티널 환경에서 SLAVEOF 명령

아래 그림은 센티널-마스터-클론의 관계를 나타낸것입니다.   이 경우 7001번 클론 서버에 "slaveof no one" 명령을 실행하면 어떻게 될까요?

redis slaveof sentinel master slave
redis slaveof sentinel master slave

위 그림에서 보는 것처럼 잠시 마스터로 승격되었다 다시 클론으로 변경됩니다.   이것은 센티널이 변경시킵니다.   센티널의 역할 중 일부분입니다.

장애 조치(failover)와 비교해 보겠습니다.   7000번 서버가 다운되면 센티널은 7001번 클론을 마스터로 승격(promote)시킵니다.   이후에 7000번 서버가 다시 시작했을 때 센티널은 이미 마스터가 있으므로 7000번을 클론으로 변경(demote)시킵니다.
클론에 "slaveof no one" 명령을 실행했을 때도 센티널은 같은 경우로 판단해서 마스터가 된 서버를 다운되었다가 시작하는 것으로 인식해서 다시 클론으로 변경(demote)하는 것입니다.
센티널은 위 두 가지 경우를 구분하지 못합니다.

그럼 실제로 어떻게 된 것인지 서버 로그를 볼까요.

7001번 서버 로그

M 20:43:13.416 * MASTER MODE enabled
S 20:43:29.177 * SLAVE OF 192.168.56.102:7000 enabled

43분 13초에 마스터가 되었다가, 29초에 다시 클론(슬레이브)이 됩니다.

7111번 센티널 서버 로그

X 20:43:29.176 * +convert-to-slave slave 192.168.56.102:7001 192.168.56.102 7001 @ master7000 192.168.56.102 7000

센티널은 29.176초에 마스터를 클론으로 변경(demote)시킵니다.   7001번 서버는 클론이 되었다고 29.177초에 로그를 남깁니다.

명령을 실행해서 확인

7001번 서버에 "slaveof no one" 명령을 실행해서 확인해 보겠습니다.

127.0.0.1:7001> slaveof no one
OK
127.0.0.1:7001> role       명령을 실행한 직후
1) "master"         마스터임을 확인할 수 있다.
2) (integer) 170124508
3) (empty list or set)
127.0.0.1:7001>
127.0.0.1:7001> role       30초 후
1) "slave"         클론(슬레이브)로 변경되었다.
2) "192.168.56.102"
3) (integer) 7000
4) "connected"
5) (integer) 170125976
127.0.0.1:7001>

센티널 환경에서 SLAVEOF 명령, 그리고 FAILOVER-TIMEOUT

아래 왼쪽 그림에서 7001번 클론을 7002번 마스터에 slaveof 127.0.0.1 7002 하면 어떻게 될까요?
Slaveof 명령 자체는 문제없이 수행되어 아래 오른쪽 그림처럼 7001번 서버가 7002번 서버의 클론이 됩니다.

redis slaveof sentinel slaveof
redis slaveof sentinel slaveof

하지만 7111번 센티널에 접속해서 sentinel slaves <master-name>을 실행하면 센티널이 가지고 있는 정보는 갱신(update)되지 않습니다.
다음은 센티널에 접속해서 7000번 서버의 클론을 본 것입니다.

127.0.0.1:7111> sentinel slaves master7000
1) 1) "name"
    2) "192.168.56.102:7001"
    3) "ip"
    4) "192.168.56.102"
    5) "port"
    6) "7001"
    7) "runid"
    8) "1aac399b500de536376000410765e8b55c31f624"
    9) "flags"
  10) "slave"
  ...

하지만 3분 후 상태를 다시 확인해보면 이상한 일이 발생했음을 알 수 있습니다.   7001번 서버가 다시 7000번 서버의 클론이 되어 있습니다.

redis slaveof sentinel slaveof
redis slaveof sentinel slaveof

정말 이상한 일입니다만, 이것도 센티널의 역할입니다.
우선 7001번과 센티널 서버의 로그를 시간순으로 확인해 보겠습니다.

7001번 서버 로그

7001번 서버 로그
S 03:00:04.096 * SLAVE OF 192.168.56.102:7002 enabled (user request from 'addr=192.168.56.101:11031 cmd=slaveof')
S 03:00:04.428 * Connecting to MASTER 192.168.56.102:7002

3시 0분 4초에 192.168.56.101에서 클라이언트가 slaveof 명령을 실행해서 7001번 서버의 마스터를 7002번 서버로 바꿉니다.

센티널 로그

X 03:03:05.591 * +fix-slave-config slave 192.168.56.102:7001 192.168.56.102 7001 @ master7000 192.168.56.102 7000

정확히 3분 1초 후 센티널이 7001번 서버의 마스터를 7000번 서버로 변경(+fix-slave-config)하려고 시도합니다.

7001번 서버 로그

S 03:03:05.593 * SLAVE OF 192.168.56.102:7000 enabled (user request from 'name=sentinel cmd=exec')

3시 3분 5초에 센티널이 slaveof 명령이 포함된 exec 명령을 7001번에 실행합니다.   그래서 7001번 서버의 마스터가 7000번으로 변경됩니다.

그런데 왜 3분 후일까요?
이것은 센티널 파라미터인 failover-timeout과 관계가 있습니다.   센티널은 failover 수행 시 각 단계마다 timeout을 가지고 있습니다.   Timeout 이후에도 진행되지 않으면 원위치 시킵니다.   센티널은 사용자가 클론 서버에 실행한 slaveof 명령도 failover의 일부분으로 오인하고 3분이 지났는데도 더 이상 진행하지 않으므로 7002번을 마스터로 바라보던 7001번 서버를 다시 7000번을 마스터로 바라보도록 원위치 시키는 것입니다.   센티널의 각 단계와 파라미터 값을 변경하는 sentinel set 명령은 여기를 보세요.
Failover-timeout은 디폴트 3분입니다.

센티널 환경에서 slaveof 명령은 주의를 기울여야 합니다.   이 경우 원위치 시키지않는 방법은 slaveof 명령 실행 직후 센티널에 sentinel reset <master-name> 명령을 실행하는 것입니다.   그러면 클론 정보가 없어져 7001번 서버를 원위치 시키지 못합니다.


마스터에 대한 SLAVEOF

이번에는 센티널이 모니터하는 마스터를 다른 단독(standalone) 마스터의 클론으로 만들면 어떻게 될까요?
아래 초기 상태에서 7000번 마스터에 slaveof 명령을 실행해서 7002번의 클론으로 만들어보겠습니다.

초기 상태(Initial state)

redis slaveof sentinel slaveof
redis slaveof sentinel slaveof

단계(step) 1

7000번 서버에 접속해서 'slaveof 192.168.56.102 7002' 명령을 실행합니다.   각 서버의 로그를 시간 순으로 보겠습니다.

7000번 서버 로그

S 09:39:31.850 * SLAVE OF 192.168.56.102:7002 enabled (user request from 'addr=192.168.56.101:1474 cmd=slaveof')

39분 31초에 클라이언트에서 slaveof 명령을 실행시켜 7000번 서버를 클론으로 만듭니다.

단계(step) 1이 진행된 상태

7000번 서버가 7002번 서버의 클론이 되었으므로 7001번 서버도 7002번 서버의 자손이 되었습니다.

redis slaveof sentinel slaveof
redis slaveof sentinel slaveof

단계(step) 2

센티널은 7000번 서버가 다운된 것으로 인지하고 7001번을 마스터로 승격(promote)시키고 모니터를 시작합니다.   아래는 7111번 센티널와 7001번 서버의 로그입니다.

7111번 센티널 서버 로그

X 09:40:22.709 # +sdown master master7000 192.168.56.102 7000
X 09:40:22.709 # +odown master master7000 192.168.56.102 7000 #quorum 1/1
...
X 09:40:22.785 * +failover-state-send-slaveof-noone slave 192.168.56.102:7001 192.168.56.102 7001 @ master7000 192.168.56.102 7000
...
X 09:40:23.792 # +switch-master master7000 192.168.56.102 7000 192.168.56.102 7001
X 09:40:23.792 * +slave slave 192.168.56.102:7000 192.168.56.102 7000 @ master7000 192.168.56.102 7001

Slaveof 명령을 실행하고 약 50초 후인 40분 22초에 센티널은 7000번 서버가 다운되었다고 인지하고 7001번 클론을 마스터로 변경한다.   그리고 센티널 내부 정보에서 7000번 서버의 역할을 클론으로 변경한다.   이것은 7000번 서버가 다시 시작(start)했을 경우 클론으로 만들기 위해서이다.

7001번 서버 로그

M 09:40:22.876 * MASTER MODE enabled (user request from 'name=sentinel cmd=exec')

단계(step) 2가 진행된 상태

redis slaveof sentinel slaveof
redis slaveof sentinel slaveof

단계(step) 3 (마지막)

단계 2가 완료되고 3분(failover-timeout) 후, 센티널은 7000번 서버를 7001번 서버의 클론으로 변경한다.

7111번 센티널 서버 로그

X 09:43:24.565 * +fix-slave-config slave 192.168.56.102:7000 192.168.56.102 7000 @ master7000 192.168.56.102 7001

7000번 서버 로그

S 09:43:24.566 * SLAVE OF 192.168.56.102:7001 enabled (user request from 'name=sentinel cmd=exec')

단계(step) 3 이 완료된 상태

초기 상태와 비교해보면 초기 상태는 7000번이 마스터이고 7001번이 클론이였는데, 이제 7001번이 마스터이고 7000번이 클론으로 변경되었음을 알 수 있다.

redis slaveof sentinel slaveof
redis slaveof sentinel slaveof

센티널 환경에서 SLAVEOF 명령에 대한 정리

위에서 살펴보았듯이 센티널이 모니터하고 있는 마스터와 클론에 대한 변경(slaveof)는 예상치 못한 변화가 시간 차를 두고 발생한다.   두 가지 경우로 구분해서 정리한다.

  • 센티널 구성 시: 마스터-클론을 미리 구성한 다음 센티널 모니터를 시작한다.
  • 센티널 운영 중: 마스터나 클론의 구성을 변경(slaveof)하기 전에 센티널이 마스터에 대한 모니터를 중지(remove)시키고 변경한다.


명령문 命令文 Command syntax

SLAVEOF ip port or SLAVEOF NO ONE

  • 이 명령은 version 1.0.0 부터 사용할 수 있다.
  • 이 문서는 버전 3.2.2를 기준으로 만들었습니다.
Clients for C Hiredis



<< FLUSHALL SLAVEOF REPLICAOF >>

질문하거나 댓글을 보려면 클릭하세요.  댓글수 :    조회수 :

Email 답글이 올라오면 이메일로 알려드리겠습니다.