Database/Redis

[Redis] 클러스터 노드간 슬롯을 변경(이동)하는 방법

꽁담 2020. 4. 5. 02:10

클러스터 슬롯


레디스 클러스터는 0 ~ 16383 까지의 슬롯 값을 가지고 있습니다.

또한 이 슬롯 값을 마스터 노드별로 분배할 수 있습니다.


레디스 클러스터에서는 기본적으로 키에 해시 함수를 적용해서 나온 값(슬롯) 노드에 할당을 합니다.

즉, 슬롯을 이용하여 특정 노드에 데이터가 몰리지 않도록 분산하기 위해 사용하는 기능이 클러스터 슬롯입니다.

 

특정 키가 어떤 슬롯에 저장되는지는 레디스의 해시함수 알고리즘에 의해 정해지기 때문에,

특정 키는 특정노드에만 저장이 될 것입니다.

단 서로 다른 키라고 하더라도 해시함수로 나온 값이 동일할 수 있으므로 하나의 슬로셍는 여러개의 키가 저장될 수 있습니다.


클러스터 노드간에는 해시 알고리즘을 서로 공유하고 있어

특정 키가 어떤 노드에 저장되는지, 어떤 슬롯에 저장되어야하는지를 서로 알고 있기 때문에

노드가 많이 늘어나더라도 데이터 저장 및 조회를 위한 네트워크 비용이 많이 발생하지는 않을 것 입니다.



클러스터 노드간 슬롯을 변경하는 방법


슬롯에 키가 할당이 되어 있는 경우와 되어있지 않은 경우로 나뉘게 됩니다.


먼저 클러스터 노드와 슬롯이 어떻게 구성되어 있는지 확인합니다.

7000, 7001 노드는 마스터와 슬레이브로 이루어져 있으며 0 ~ 16383 까지의 슬롯이 할당되어 있습니다.

8000 노드는 마스터로 이루어져 있으며 슬롯이 할당되어 있지 않습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
127.0.0.1:7000> cluster nodes
ef868d7c16f2e5bd7afb8599f8326ad60fdaf119 127.0.0.1:8000@18000 master - 0 1586009458000 0 connected
869859e396c881b3c26f2a386c1495235225b57b 127.0.0.1:7000@17000 myself,master - 0 1586009455000 1 connected 0-16383
e8b8e9115aab2a8bb42ec9aff1c62f1aeb3cc10c 127.0.0.1:7001@17001 slave 869859e396c881b3c26f2a386c1495235225b57b 0 1586009458648 1 connected
 
127.0.0.1:7000> cluster slots
11) (integer) 0
   2) (integer) 16383
   31"127.0.0.1"
      2) (integer) 7000
      3"869859e396c881b3c26f2a386c1495235225b57b"
   41"127.0.0.1"
      2) (integer) 7001
      3"e8b8e9115aab2a8bb42ec9aff1c62f1aeb3cc10c"
cs


클러스에는 2개의 키를 저장하였습니다.

key 값은 슬롯 12539 에, key1 값은 슬롯 9189 에 저장되어 있으며 노드 7000 에 저장되어 있습니다.


1
2
3
4
5
6
7
8
127.0.0.1:7000> get key
"mozi"
127.0.0.1:7000> get key1
"mozi"
127.0.0.1:7000> cluster keyslot key
(integer) 12539
127.0.0.1:7000> cluster keyslot key1
(integer) 9189
cs


이 포스팅에서 약간 번외기는 하지만..

key2 의 슬롯값을 확인하면 4998 이며 이 슬롯값은 7000 노드에 저장되어야 하기 때문에,

8000 노드에서 key2 값을 set 한다면 7000 노드로 redirect 되어 저장됩니다.

1
2
3
4
5
6
7
127.0.0.1:8000> cluster keyslot key2
(integer) 4998
127.0.0.1:8000> set key2 tistory
-> Redirected to slot [4998] located at 127.0.0.1:7000
OK
127.0.0.1:7000> get key2
"tistory"
cs


슬롯에 값이 저장되어 있는 경우 슬롯을 이동하는 방법

스크립트와 설명이 길 수 있습니다. 잘 읽어주세요~

또한 쿼리(?)를 수행해야 하는 서버와 순서도 매우 중요하기 때문에, 수행하는 서버를 먼저 꼭 확인해주셔야 합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
127.0.0.1:7000> cluster countkeysinslot 12539
(integer) 1
 
127.0.0.1:7000> cluster getkeysinslot 12539 1
1"key"
 
127.0.0.1:8000> cluster setslot 12539 importing 869859e396c881b3c26f2a386c1495235225b57b
OK
127.0.0.1:7000> cluster setslot 12539 migrating ef868d7c16f2e5bd7afb8599f8326ad60fdaf119
OK
 
127.0.0.1:8000> cluster nodes
869859e396c881b3c26f2a386c1495235225b57b 127.0.0.1:7000@17000 master - 0 1586012870273 1 connected 0-16383
ef868d7c16f2e5bd7afb8599f8326ad60fdaf119 127.0.0.1:8000@18000 myself,master - 0 1586012870000 0 connected [12539-<-869859e396c881b3c26f2a386c1495235225b57b]
e8b8e9115aab2a8bb42ec9aff1c62f1aeb3cc10c 127.0.0.1:7001@17001 slave 869859e396c881b3c26f2a386c1495235225b57b 0 1586012870875 1 connected
 
127.0.0.1:8000> set key mozitistory
-> Redirected to slot [12539] located at 127.0.0.1:7000
OK
 
127.0.0.1:7000> migrate 127.0.0.1 8000 key 0 5000
OK
 
127.0.0.1:7000> cluster setslot 12539 node ef868d7c16f2e5bd7afb8599f8326ad60fdaf119
OK
 
127.0.0.1:8000> cluster setslot 12539 node ef868d7c16f2e5bd7afb8599f8326ad60fdaf119
OK
 
127.0.0.1:7000> get key
-> Redirected to slot [12539] located at 127.0.0.1:8000
"mozi"
cs


 Line

 설명

 1

 countkeysinslot 으로 슬롯에 키가 몇개가 할당되어 있는지 먼저 확인합니다.

 4

 getkeysinslot 으로 슬롯에 저장된 키 명칭을 확인합니다.

 맨 마지막 인자를 Line2의 값까지 증가시키면서 키 명칭을 확인해야 합니다.

 7

 슬롯을 이동하려고 하는 대상 서버에서 12539 슬롯을 소스노드ID 로부터 가지고 온다고 예약합니다.

 9

 슬롯을 전달하려고 하는 소스 서버에서 12539 슬롯을 대상노드ID 로 전달한다고 예약합니다.

 14

 12539 슬롯이 소스노드로부터 온다는 것을 확인할 수 있습니다.

 17

 예약을 했다고 해서 실제로 슬롯이 이동한 것은 아니며, 슬롯도 계속 사용할 수 있습니다.

 21

 소스 서버로부터 key 를 대상서버로 마이그레이션 합니다.

 0 과 5000 은 목적지 DB ID 와 TIMEOUT 값입니다.

 getkeysinslot 에서 나온 key 의 명칭을 모두 입력하면서 명령을 수행해야 합니다.

 24

 소스서버에서 슬롯값과 대상노드ID 를 setslot 해줍니다.

 (반드시 해주어야 합니다.)

 27

 대상서버에서 슬롯값과 대상노드ID(자기자신) 를 setslot 해줍니다.

 30

 키를 조회하면 대상서버로 redirect 되어 조회됩니다.


슬롯에 대한 정보를 조회하면 대상서버인 8000노드에 12539 슬롯이 할당되있는 것을 확인할 수 있습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
127.0.0.1:7000> cluster slots
11) (integer) 12539
   2) (integer) 12539
   31"127.0.0.1"
      2) (integer) 8000
      3"ef868d7c16f2e5bd7afb8599f8326ad60fdaf119"
21) (integer) 0
   2) (integer) 12538
   31"127.0.0.1"
      2) (integer) 7000
      3"869859e396c881b3c26f2a386c1495235225b57b"
   41"127.0.0.1"
      2) (integer) 7001
      3"e8b8e9115aab2a8bb42ec9aff1c62f1aeb3cc10c"
31) (integer) 12540
   2) (integer) 16383
   31"127.0.0.1"
      2) (integer) 7000
      3"869859e396c881b3c26f2a386c1495235225b57b"
   41"127.0.0.1"
      2) (integer) 7001
      3"e8b8e9115aab2a8bb42ec9aff1c62f1aeb3cc10c"
cs


슬롯에 아무 값도 없는 경우

소스서버와 대상서버에서 setslot 으로 옮겨주면 됩니다.

반드시 '소스에서 대상으로' 수행 후, '대상에서 대상으로' 수행해 주어야 합니다.

(테스트하면서 8000 노드를 재구성해서 ID 가 다릅니다.)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
127.0.0.1:7000> cluster setslot 10000 node 9d642c55a0083deec049b84d9f25e04740924bb3
OK
127.0.0.1:7000> cluster slots
11) (integer) 0
   2) (integer) 9999
   31"127.0.0.1"
      2) (integer) 7000
      3"869859e396c881b3c26f2a386c1495235225b57b"
   41"127.0.0.1"
      2) (integer) 7001
      3"e8b8e9115aab2a8bb42ec9aff1c62f1aeb3cc10c"
21) (integer) 10001
   2) (integer) 16383
   31"127.0.0.1"
      2) (integer) 7000
      3"869859e396c881b3c26f2a386c1495235225b57b"
   41"127.0.0.1"
      2) (integer) 7001
      3"e8b8e9115aab2a8bb42ec9aff1c62f1aeb3cc10c"
31) (integer) 10000
   2) (integer) 10000
   31"127.0.0.1"
      2) (integer) 8000
      3"9d642c55a0083deec049b84d9f25e04740924bb3"
 
127.0.0.1:8000> cluster slots
11) (integer) 0
   2) (integer) 16383
   31"127.0.0.1"
      2) (integer) 7000
      3"869859e396c881b3c26f2a386c1495235225b57b"
   41"127.0.0.1"
      2) (integer) 7001
      3"e8b8e9115aab2a8bb42ec9aff1c62f1aeb3cc10c"
 
 
127.0.0.1:8000> cluster setslot 10000 node 9d642c55a0083deec049b84d9f25e04740924bb3
OK
127.0.0.1:8000> cluster slots
11) (integer) 10000
   2) (integer) 10000
   31"127.0.0.1"
      2) (integer) 8000
      3"9d642c55a0083deec049b84d9f25e04740924bb3"
21) (integer) 0
   2) (integer) 9999
   31"127.0.0.1"
      2) (integer) 7000
      3"869859e396c881b3c26f2a386c1495235225b57b"
   41"127.0.0.1"
      2) (integer) 7001
      3"e8b8e9115aab2a8bb42ec9aff1c62f1aeb3cc10c"
31) (integer) 10001
   2) (integer) 16383
   31"127.0.0.1"
      2) (integer) 7000
      3"869859e396c881b3c26f2a386c1495235225b57b"
   41"127.0.0.1"
      2) (integer) 7001
      3"e8b8e9115aab2a8bb42ec9aff1c62f1aeb3cc10c"
cs


 Line

 설명

 1

 소스서버에서 빈 슬롯 값과 대상노드ID를 기입합니다.

 3

 소스서버에서는 슬롯이 대상노드로 전달되었다고 출력됩니다.

 26

 대상서버에서는 슬롯이 아직 반영되지 않은 것으로 출력됩니다.

 37

 대상서버에서 빈 슬롯 값과 대상노드ID(자기자신)을 기입합니다.

 39

 대상서버에서도 빈 슬롯이 옮겨간 것으로 나옵니다.