redis_cluster_failover
Redis CLUSTER Failover 장애복구
Redis Cluster Course | Redis Technical Support | Redis Enterprise Server |
---|
CLUSTER FAILOVER 장애복구 시나리오 1
마스터 노드 다운
- 단순한 클러스터를 구성하고 마스터 노드 다운 시 복구를 진행해 보자. 테스트는 마스터 노드 3개, 복제 노드는 없는 것으로 한다. 그림으로 표현하면 아래와 같다.
- 테스트 요약
- 레디스 시작
- 클러스터 시작
- 노드 다운
- cluster forget node-id
- cluster addslots slots
- 복구 완료
- 이 테스트는 마스터 노드가 있는 머신이 다운되어 nodes.conf 와 appendonly.aof 파일을 살릴 수 없는 상황을 가정한 것이다. 만약 nodes.conf 파일과 appendonly.aof 파일이 있다면 가용한 머신에서 이 두 파일을 복사하고 레디스를 실행하면 바로 클러스터에 붙어서 정상 동작할 것이다.
- 테스트를 위한 레디스 노드 준비 : Working directory를 5001, 5002, 5003 만든다.
각 디렉토리에 아래와 같은 redis.conf 파일을 준비한다.
여기 나와있지 않은 appendonly.aof, daemonize, logfile 등은 테스트 상황에 맞게 준비한다.
만약 반복 테스트 중이라면 각 디렉토리에 nodes.conf, appendonly.aof 파일을 지우고 한다.
nodes.conf 파일이 있으면 이전 클러스터 구성을 읽어오기 때문에 새로운 클러스터를 구성할 수 없다.
appendonly.aof 파일에서 데이터를 읽어오면 역시 클러스터를 구성할 수 없다.
파일에서 포트와 dir에 있는 5001을 노드에 맞게 5002, 5003으로 변경해서 저장한다.
port 5001
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 3000
cluster-require-full-coverage yes
appendonly yes
dir /path/to/5001/ - cluster-require-full-coverage 이 파라미터를 yes로 설정하면, 모든 슬롯(16384)이 정상 노드에 할당되어 서비스가 가능할때 클러스터가 정상으로 동작한다. 만약 한 노드라도 다운되면 클러스터는 fail 상태이고 정상 노드도 서비스를 하지 않는다. no로 설정하면 일부 서버가 다운되어 일부 슬롯이 정상 노드에 할당되어 있지 않아도, 정상 노드들은 서비스를 계속한다. 다운된 노드에 할당되어 있는 슬롯에 해당하는 키를 입력하면 에러가 난다.
- 레디스 시작
$ src/redis-server 5001/redis.conf
$ src/redis-server 5002/redis.conf
$ src/redis-server 5003/redis.conf - 클러스터 시작: redis-trib(4.x이하), redis-cli --cluster(5이상)를 사용한다.
나오는 메시지는 필요한 부분만 간추려 넣었다.
$ src/redis-trib.rb create --replicas 0 127.0.0.1:5001 127.0.0.1:5002 127.0.0.1:5003
$ src/redis-cli --cluster create 127.0.0.1:5001 127.0.0.1:5002 127.0.0.1:5003 --cluster-replicas 0
>>> Creating cluster
M: dafe0a8c9ef92d1d90f193d28e36427e35a33b6b 127.0.0.1:5001
slots:0-5460 (5461 slots) master
M: 3c2c462332de3b10d506d7cc767d6c3a7b688f92 127.0.0.1:5002
slots:5461-10922 (5462 slots) master
M: 93a76ea0a11b3fc2e264c89a739f1f59541e764a 127.0.0.1:5003
slots:10923-16383 (5461 slots) master
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered. - kill -9 pid 명령으로 5003번 레디스 다운시킨다. 살아있는 노드들은 다음 메시지를 내보내고, 더 이상 입력을 받지 않는다.
# Cluster state changed: fail
- 이제 클러스터가 다운된 상태이다. 제일 처음 할 일은 다운된 노드를 클러스터에서 제거한다.
살아있는 모든 노드에 접속해서 Cluster forget 명령을 실행한다.
이때 다운된 5003번의 node-id를 알아야 한다.
$ src/redis-cli -p 5001 cluster forget 93a76ea0a11b3fc2e264c89a739f1f59541e764a
$ src/redis-cli -p 5002 cluster forget 93a76ea0a11b3fc2e264c89a739f1f59541e764a - 5001, 5002번에 접속해서 클러스터 정보를 보면 fail로 나오고 5003번 노드가 없음을 알 수 있다.
$ src/redis-cli -p 5001
5001> cluster info
cluster_state: fail
5001> cluster nodes
5001 master connected 0-5460
5002 master connected 5461-10922 - 5003번이 가지고 있던 슬롯이 살아있는 노드에 할당되어 있지 않으므로 cluster addslots 명령으로 할당한다.
$ src/redis-cli -p 5001 cluster addslots {10923..16383}
다른 방법
$ echo '(10923..16383).each{|x| puts "cluster addslots "+x.to_s}' | ruby | src/redis-cli -c -p 5001 > /dev/null - 이제 클러스터가 정상으로 돌아왔다. Cluster 명령으로 정보를 보면 다음과 같다.
5001> cluster info
cluster_state: ok
5001> cluster nodes
5001 master connected 0-5460 10923-16383
5002 master connected 5461-10922 - 그림으로 표현하면 아래와 같다.
신규 노드 추가
- 이제 클러스터에 2개 노드만 있으므로 불안하다. 원래대로 1개 노드는 추가하자. 새 노드를 다른 머신(박스) 또는 기존 머신에 준비하면 될 것이다. 테스트에서는 5004 디렉토리를 만들어서 5001에 있는 redis.conf를 복사하고 약간 수정해서 진행할 것이다.
- 신규 레디스 노드 시작
$ src/redis-server 5004/redis.conf
- 클러스터에 합류 : cluster meet 명령 사용
$ src/redis-cli -p 5004 cluster meet 127.0.0.1 5001
- 슬롯 재할당: reshard, 필요한 메시지만 간추렸다.
$ src/redis-trib.rb reshard 127.0.0.1:5001 (4.x이하)
$ src/redis-cli --cluster reshard 127.0.0.1:5001 (5이상)
>>> Performing Cluster Check (using node 127.0.0.1:5001)
M: dafe0a8c9ef92d1d90f193d28e36427e35a33b6b 127.0.0.1:5001
M: 3c2c462332de3b10d506d7cc767d6c3a7b688f92 127.0.0.1:5002
M: 0baa4d00d56222ae7a723bb1ff4c240f474d3cfd 127.0.0.1:5004
[OK] All nodes agree about slots configuration.
How many slots do you want to move (from 1 to 16384)? 5461
What is the receiving node ID? 0baa4d00d56222ae7a723bb1ff4c240f474d3cfd
Please enter all the source node IDs.
Type 'all' to use all the nodes as source nodes for the hash slots.
Type 'done' once you entered all the source nodes IDs.
Source node #1:dafe0a8c9ef92d1d90f193d28e36427e35a33b6b
Source node #2:done
..... 중간 생략 .....
Do you want to proceed with the proposed reshard plan (yes/no)? yes
- 3개 마스터 노드 클러스터로 원상 회복 되었다. 그림으로 표현하면 아래와 같다.
CLUSTER FAILOVER 장애복구 시나리오 2
복제서버가 있는 마스터 노드 다운
- 다음과 같이 마스터 노드 3개, 복제 노드 3개 상황에서 1번 마스터를 kill -9로 다운시키면, 복제가 마스터로 승격되어 계속된다. 하지만 cluster-node-time 시간을 포함해서 정상으로 돌아오기까지 몇 초가 소요된다.
- 복제 노드에서 나오는 메시지는 다음과 같다. 중요한 부분만 간추렸다.
38809:S # Connection with master lost.
38809:S # Cluster state changed: fail 4초 후에 Cluster fail
38809:S # Failover election won: I'm the new master. 복제가 마스터로 승격
38809:M # Cluster state changed: ok Cluster ok
- 클러스터의 다른 노드에서 나오는 메시지는 다음과 같다. 중요한 부분만 간추렸다.
38797:M # Cluster state changed: fail
38797:M # Failover auth granted to f55ff1ca79ed8261370e172782759f81a0e48040 for epoch 7 Failover 완료
38797:M # Cluster state changed: ok Cluster 상태 변경
다운되었던 마스터 노드를 재시작하면 어떻게 될까?
- 이 노드는 마스터 상태로 다운되었으므로, 재시작하면 일단 마스터로 시작한다.
구성이 변경됐다는 것을 감지하고 복제로 전환한다. 이후 마스터에 접속해서 데이터를 받는다.
47574:M * The server is now ready to accept connections on port 7002
47574:M # Configuration change detected. Reconfiguring myself as a replica of f55ff1ca79ed8261370e172782759f81a0e48040
47574:S # Cluster state changed: ok
47574:S * Connecting to MASTER 127.0.0.1:7005
- 클러스터 상태 변경후 모습
신규 노드를 복제로 추가하는 방법
- 7006번 노드를 준비해서 시작한다.
- add-node 명령으로 7006번을 7005번의 복제로 추가한다.
그러면 7006번 노드는 7005번의 데이터를 받아고 복제로 동작한다.
redis-trib.rb add-node --slave 127.1.1.1:7006 127.1.1.1:7005 (4.x이하)
redis-cli --cluster add-node 127.1.1.1:7006 127.1.1.1:7005 --cluster-slave (5이상)
<< Cluster Design | Failover | Cluster Data Center Failover >> |
---|
Email
답글이 올라오면 이메일로 알려드리겠습니다.