시작하기
- cluster-enabled yes : yes로 하면 cluster mode로 시작한다. no로 하면 standalone mode로 시작한다.
- cluster-config-file nodes.conf : 이 파일은 클러스터의 상태를 기록하는 바이너리 파일이다. 클러스터의 상태가 변경될때 마다 상태를 기록한다.
- cluster-node-timeout 3000 : 레디스 노드가 다운되었는지 판단하는 시간이다. 단위는 millisecond이다.
- port open : 방화벽(firewall)을 사용하고 있다면 기본 포트에 10000을 더한 클러스터 버스 포트도 열려있어야 한다. 예를 들어 기본 포트로 7000번을 사용한다면 17000번 포트도 같이 열어야 한다.
- 클러스터 시작 시 최소 3개 노드가 필요하다. 포트 7000, 7001, 7002를 사용할 것이고, 각 conf 파일 등을 저장하기 위해서 포트 별로 디렉토리를 만든다. 테스트를 레디스 3.2.8 버전으로 할 것이다. redis-3.2.8 디렉토리에서 각 디렉토리를 만든다.
$ mkdir 7000 7001 7002
- 7000번 디렉토리에 redis.conf 파일을 복사한 후 아래와 같이 수정한다. appendonly 는 클러스터와 직접적인 연관이 있는 파라미터는 아니지만, 다운되었던 마스터 노드 재 시작시 appendonly 파일에 가장 최근까지 데이터가 있으므로, 클러스터 운영시에는 yes로 설정하는 것을 권장한다. working directory도 설정해 줄 것을 권장한다.
port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 3000
appendonly yes
dir /path/to/7000/
- 이 redis.conf 파일을 7001, 7002 디렉토리에 복사하고 port와 dir을 수정한다.
- 3개 redis를 시작한다.
$ src/redis-server 7000/redis.conf
$ src/redis-server 7001/redis.conf
$ src/redis-server 7002/redis.conf
- 레디스를 시작하면 레디스 로고가 나오기 전에 다음과 같은 메시지를 만나게 될것이다. 이것은 클러스터 conf 파일인 nodes.conf 파일을 발견하지 못했다는 메시지이다. nodes.conf 파일이 있으면 'Node configuration loaded' 메시지가 나올 것이다.
21380:M 17:11:30.972 * No cluster configuration found,
I'm 0aae4fd025e1e4c43ff0bdcc3e7cca603434b47d
- 다르게 나오는 메시지가 하나 더 있다.
Running in cluster mode
- 레디스는 시작했지만 클러스터가 시작된 것은 아니다. 이 상태에서 redis-cli로 접속해서 set 명령을 입력하면 다음과 같은 메시지가 나온다. Redis-cli로 클러스터 노드에 접속할때는 -c 옵션을 사용해야 한다.
$ src/redis-cli -c -p 7000
7000> set key value
(error) CLUSTERDOWN Hash slot not served
- 다음 명령으로 클러스터를 시작한다. 중간에 yes를 입력한다. 각 노드를 체크하고 클러스터를 시작한다.
- 여기서 redis-cli를 사용하는데, 일단 그대로 따라하세요. 자세한 사용법은 redis-cli --cluster 사용법에 있다.
$ src/redis-trib.rb create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 버전 4.x까지
$ src/redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 버전 5.0이상
>>> Creating cluster
........ 중간 생략 ...........
Can I set the above configuration? (type 'yes' to accept): yes
........ 중간 생략 ...........
[OK] All 16384 slots covered.
- redis-trib.rb에서 에러가 발생하는 경우
1) Ruby 버전과 redis-trib.rb 버전이 맞지 않으면 에러가 난다.
2) 클러스터 버스 포트(여기서는 17000, 17001, 17002)가 방화벽에 막혀있으면 "..."이 계속찍히고 종료되지 않는다.
- redis-cli로 접속해서 cluster info 명령으로 cluster 상태 정보를 확인할 수 있다. 여기 나오는 정보는 다음 섹션에서 노드를 다운시킨 다음 비교해 보자.
7000> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:3
cluster_size:3
... 이하 생략 ...
- cluster nodes 명령으로 노드 리스트와 각 노드의 상태 정보를 확인할 수 있다.
7000> cluster nodes
0e028bc2e06ae5483c29ff3d757484f9470261a3 127.0.0.1:7002 master - 0 1435751401682 3 connected 10923-16383
f187fda36f3480aac810e931f920bf3803ac3a95 127.0.0.1:7001 master - 0 1435751402183 2 connected 5461-10922
475bf51a0a367c091487e526b0f42f5bd48f45db 127.0.0.1:7000 myself,master - 0 0 1 connected 0-5460
- 이제 redis-cli로 접속해서 데이터를 입력해 보자. 클러스터 모드로 접속했을때 다른 점은 IP다음에 DB 번호 표시였던 것이 PORT가 표시된다. 그리고 명령을 실행해보면 포트가 바뀌는 것을 알 수 있다. set key Hello를 입력하면 key의 slot은 12539이므로 7002번 노드에 할당되었고, redis-cli가 7002번에 접속해서 입력하는 것이다. 이것은 -c 모드로 접속했을때 가능하다.
$ redis-cli -c -p 7000
7000> set key Hello
-> Redirected to slot [12539] located at 127.0.0.1:7002
OK
7002> set key2 World
-> Redirected to slot [4998] located at 127.0.0.1:7000
OK
7000> get key
-> Redirected to slot [12539] located at 127.0.0.1:7002
"Hello"
7002> get key2
-> Redirected to slot [4998] located at 127.0.0.1:7000
"World"
7000>
- 스마트 클라이언트 : 레디스 서버들은 할당된 SLOT에 해당하는 key에 대해서만 처리(입력/조회)를 한다. 클라이언트는 레디스 서버에 접속해서 각 서버에 할당된 슬롯 정보를 가져온다. 키 입력 시 레디스 클러스터와 동일한 알고리즘으로 슬롯을 구한 다음 해당 SLOT을 보유하고 있는 레디스 서버에 접속해서 저장/조회를 한다.
- 7002번 노드에 접속해서 shutdown 또는 debug segfault 명령으로 다운시켜 보자. 이 명령은 debug 용도로 서버를 crash 시키는 명령이다.
7002> debug segfault
Could not connect to Redis at 127.0.0.1:7002: Connection refused
- 노드 다운
- 서버가 다운되면 이를 감지한 다른 서버들은 3초 후에 아래와 같은 로그를 남긴다. 3초는 cluster-node-timeout에 설정된 값이다.
20013:M * Marking node 475bf51a0a367c091487e526b0f42f5bd48f45db as failing (quorum reached).
20013:M # Cluster state changed: fail
- 7000번에 접속해서 입력해 보자. 클러스터가 다운되었다는 메시지가 나오고 명령을 처리하지 못한다.
7000> set key Hello
(error) CLUSTERDOWN The cluster is down
- cluster info 명령으로 클러스터 상태를 확인해 보자.
7000> cluster info
cluster_state:fail 정상일때는 ok
cluster_slots_assigned:16384 이 클러스터 할당된 슬롯수
cluster_slots_ok:10923 7002번이 담당하던 5461개의 슬롯이 다운되어 제외되었음. 정상적으로 할당된 슬롯수, 이것으로 운영 가능하다는 의미는 아님.
cluster_slots_pfail:0
cluster_slots_fail:5461 다운된 슬롯수
cluster_known_nodes:3 이 클러스터에 참가하고 있는 모든 레디스 노드 수
cluster_size:3 슬롯이 할당된 마스터 노드 수
... 이하 생략 ...
- cluster nodes 명령으로 클러스터 상태를 확인해 보자. 7002번 노드가 fail로 나온다. 하지만 여전히 슬롯은 할당되어 있다.
7000> cluster nodes
0e028bc2e06ae5483c29ff3d757484f9470261a3 127.0.0.1:7002 master,fail - 1435752576254 1435752575251 3 disconnected 10923-16383
... 이하 생략 ...
- 이제 7002번 노드를 다시 시작해 보자. 맨 처음에 노드 구성을 읽었다는 메시지가 나오고, 정상적으로 시작된다.
30618:M * Node configuration loaded, I'm 0e028bc2e06ae5483c29ff3d757484f9470261a3
........ 중간 생략 ...........
30618:M * The server is now ready to accept connections on port 7002
- 다른 노드들이 아래와 같은 ok 메시지를 내보낸다.
20013:M * Clear FAIL state for node 475bf51a0a367c091487e526b0f42f5bd48f45db: is reachable again and nobody is serving its slots after some time. 20013:M # Cluster state changed: ok
- 이제 레디스에 접속해서 상태 정보를 확인해 보면 모두 정상으로 나오고, 명령도 잘 처리할 것이다.
- Step 1 : 레디스 준비, port 7003
- Step 2 : 노드 추가, add-node
- Step 3 : Slot 할당, resharding
- 7003번을 준비해서 노드를 추가해 보자. 노드 추가는 redis-cli 명령을 사용한다. 첫 번째 IP:PORT는 추가할 노드이고, 두 번째 IP:PORT는 접속해서 작업할 노드이다. 현재 클러스터 노드 중 하나를 입력하면 된다.
$ src/redis-trib.rb add-node 127.0.0.1:7003 127.0.0.1:7000 (버전 4.x이하)
$ src/redis-cli --cluster add-node 127.0.0.1:7003 127.0.0.1:7000 (버전 5이상)
>>> Adding node 127.0.0.1:7003 to cluster 127.0.0.1:7000
........ 중간 생략 ...........
>>> Send CLUSTER MEET to node 127.0.0.1:7003 to make it join the cluster.
[OK] New node added correctly.
- 노드는 추가했지만, 아직 슬롯이 할당된 것은 아니므로 노드 추가가 완료된 것은 아니다. 이 상태에서 클러스터 정보를 보면 다음과 같다. 설명할 항목만 간추렸다.
7000> cluster info
cluster_state:ok
cluster_known_nodes:4 노드가 추가되었다.
cluster_size:3 하지만 아직 슬롯이 할당되지 않았으므로 size는 그대로 3 이다.
7000> cluster nodes
08036dbc89a1d8c703d423c05499035072c480ab 127.0.0.1:7003 master - 0 1435792522468 0 connected
connected 다음에 할당된 슬롯이 없어서 표시되지 않았다.
- 이제 슬롯을 할당(resharding)해보자. 이때는 reshard 명령과 접속할 노드를 입력하면된다. 중간에 필요한 필요한 정보를 입력한다. 설명이 필요한 부분 위주로 표시했다.
$ src/redis-trib.rb reshard 127.0.0.1:7000 (버전 4.x이하)
$ src/redis-cli --cluster reshard 127.0.0.1:7000 (버전 5이상)
M: 475bf51a0a367c091487e526b0f42f5bd48f45db 127.0.0.1:7000
M: 0e028bc2e06ae5483c29ff3d757484f9470261a3 127.0.0.1:7002
M: 08036dbc89a1d8c703d423c05499035072c480ab 127.0.0.1:7003
M: f187fda36f3480aac810e931f920bf3803ac3a95 127.0.0.1:7001
How many slots do you want to move (from 1 to 16384)? 10 몇 개의 슬롯을 옮길지 입력한다.
What is the receiving node ID? 08036dbc89a1d8c703d423c05499035072c480ab
받을 노드 ID를 입력한다. 위에 표시된 7003번의 ID를 복사한다.
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:0e028bc2e06ae5483c29ff3d757484f9470261a3
할당 해줄 소스 노드 ID를 복사한다. 모든 노드에서 골고루 받으려면 'all'을 입력한다.
Source node #2:done 소스 노드 ID이 끝났으면 'done'를 입력한다.
Ready to move 10 slots.
Do you want to proceed with the proposed reshard plan (yes/no)? yes
yes를 입력한다. no를 입력하면 종료된다.
Moving slot 10923 from 127.0.0.1:7002 to 127.0.0.1:7003:
........ 중간 생략 ...........
Moving slot 10932 from 127.0.0.1:7002 to 127.0.0.1:7003: 슬롯 할당(reshard)가 완료되었다.
- Resharding 후 클러스터 정보확인
7000> cluster info
cluster_state:ok
cluster_known_nodes:4
cluster_size:4 resharding 후 size가 3에서 4로 변경되었다.
7000> cluster nodes
08036dbc89a1d8c703d423c05499035072c480ab 127.0.0.1:7003 master - 0 1435792522468 0 connected 10923-10932
connected 다음에 할당된 슬롯이 표시되었다.
- Slot reshard 후 구성도
- Step 1 : Resharding
- Step 2 : 노드 제거, del-node
- Resharding: 7000번에 접속해서 7003번에 할당된 슬롯을 7002번으로 돌리자. 입력하는 부분 위주로 간추려 표시했다.
$ src/redis-trib.rb reshard 127.0.0.1:7000 (버전 4.x이하)
$ src/redis-cli --cluster reshard 127.0.0.1:7000 (버전 5이상)
Connecting to node 127.0.0.1:7000: OK
How many slots do you want to move (from 1 to 16384)? 10
What is the receiving node ID? 0e028bc2e06ae5483c29ff3d757484f9470261a3
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:08036dbc89a1d8c703d423c05499035072c480ab
Source node #2:done
Ready to move 10 slots.
Resharding plan:
Do you want to proceed with the proposed reshard plan (yes/no)? yes
Moving slot 10932 from 127.0.0.1:7003 to 127.0.0.1:7002: ........
- Reshard 후 cluster info를 보면 cluster_known_nodes: 4 그대로 인데, cluster_size: 3으로 변경된 것을 알 수 있다.
- Del-node: 노드를 제거해 보자. 첫 번째 인수는 del-node, 두 번째 인수는 접속할 노드의 IP:PORT 입력(제거할 노드를 입력하는 것이 아님), 세 번째 인수는 제거할 노드 ID를 입력한다.
$ src/redis-trib.rb del-node 127.0.0.1:7000 08036dbc89a1d8c703d423c05499035072c480ab (버전 4.x이하)
$ src/redis-cli --cluster del-node 127.0.0.1:7000 08036dbc89a1d8c703d423c05499035072c480ab (버전 5이상)
>>> Removing node 08036dbc89a1d8c703d423c05499035072c480ab from cluster 127.0.0.1:7000
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.
- 클러스터에서 노드가 제거되고 Shutdown까지 된다. cluster info를 보면 cluster_known_nodes: 3 으로 변경되어 있다. 이제 cluster nodes에도 표시되지 않는다.
출처
참고