3개 서버 9개 Node로 Redis Cluster 구성하기

Redis Cluster 를 구성할때 대부분의 예제는 3개의 서버로 3개의 Master 노드를 구성해서 만든다.

그러나 master node 로만 구성되어 있으면 1개의 서버 또는 노드가 죽어버리면 장애가 발생하기 때문에 slave 를 같이 구성하게 되는데, 물리적인 서버 또는 클라우드 인스턴스를 많이 쓸 수 있다면 하나의 서버 혹은 인스턴스에 하나의 노드만 구성해서 3 * 백업 노드 수 만큼 서버를 늘리면 설정은 매우 간단하다.

예를 들어 각 master node 하나당 slave node 2개씩 구성하고 싶다면, 서버를 9대로 구성하면 된다.

redis.conf 설정

port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000

Redis 3.x or 4.x

./redis-trib.rb create --replicas 1 192.168.0.1:7000 192.168.0.2:7000 192.168.0.3:7000 192.168.0.4:7000 192.168.0.5:7000 192.168.0.6:7000 192.168.0.7:7000 192.168.0.8:7000 192.168.0.9:7000 

Redis 5.x

redis-cli --cluster create 192.168.0.1:7000 192.168.0.2:7000 192.168.0.3:7000 192.168.0.4:7000 192.168.0.5:7000 192.168.0.6:7000 192.168.0.7:7000 192.168.0.8:7000 192.168.0.9:7000

이렇게 하면 알아서 3개의 master node, 6개의 slave node를 만들어준다.

알아서 만들어준다는 말은, 어떤 서버가 master가 되고 어떤 서버가 어느 노드의 slave가 될지 자동으로 구성된다.

알아서 만들어준다는 말은, 다시 말하면 내가 원하는대로 되지 않을 수도 있다는 말이다.

내가 만들고 싶었던 구성은 3개의 서버에 9개의 노드로 master-slave1-slave2 로 구성을 하는 것이었다.

마스터 노드 3개를 각 서버에 구성하고, 슬레이브 노드는 마스터와 다른 서버에 2개로 구성한다. 마스터 노드가 죽게 되는 경우에는 자동 fail-over 기능으로 다른 슬레이브가 마스터가 된다.

이렇게 구성하면 3개의 마스터 클러스터 노드를 쓰면서 서버가 2대까지 죽더라도 1대의 서버에서 3개의 노드로 운영이 가능해진다.

위의 자동 스크립트로는 이런 모양의 구성이 불가능했다. 그래서 마스터노드 구성만 자동으로 하고, 슬레이브 노드는 수동으로 하나씩 추가하는 식으로 클러스터를 구성했다.

서버는 192.168.11.1, 192.168.11.2, 192.168.11.3 을 쓴다고 가정했다.

1. Redis 3.x or 4.x, ruby가 설치되어 있는 경우

(in 192.168.11.1 server)

sudo gem install redis

./redis-trib.rb create 192.168.11.1:7000 192.168.11.2:7000 192.168.11.3:7000

./redis-trib.rb add-node --slave --master-id $(redis-cli -p 7000 cluster nodes | grep 192.168.11.1:7000 | grep master | awk '{print $1}') 192.168.11.2:7001 192.168.11.1:7000
./redis-trib.rb add-node --slave --master-id $(redis-cli -p 7000 cluster nodes | grep 192.168.11.1:7000 | grep master | awk '{print $1}') 192.168.11.3:7002 192.168.11.1:7000 

./redis-trib.rb add-node --slave --master-id $(redis-cli -p 7000 cluster nodes | grep 192.168.11.2:7000 | grep master | awk '{print $1}') 192.168.11.3:7001 192.168.11.1:7000
./redis-trib.rb add-node --slave --master-id $(redis-cli -p 7000 cluster nodes | grep 192.168.11.2:7000 | grep master | awk '{print $1}') 192.168.11.1:7002 192.168.11.1:7000

./redis-trib.rb add-node --slave --master-id $(redis-cli -p 7000 cluster nodes | grep 192.168.11.3:7000 | grep master | awk '{print $1}') 192.168.11.1:7001 192.168.11.1:7000
./redis-trib.rb add-node --slave --master-id $(redis-cli -p 7000 cluster nodes | grep 192.168.11.3:7000 | grep master | awk '{print $1}') 192.168.11.2:7002 192.168.11.1:7000

redis-cli -p 7000 cluster nodes # 노드가 cross 로 잘 묶여 있는지 테스트


2. Redis 3.x or 4.x, ruby를 설치할 수 없는 환경의 경우

(in 192.168.11.1 server)

redis-cli -p 7000 cluster meet 192.168.11.2 7000
redis-cli -p 7000 cluster meet 192.168.11.3 7000
redis-cli -p 7000 cluster meet 192.168.11.1 7001
redis-cli -p 7000 cluster meet 192.168.11.2 7001
redis-cli -p 7000 cluster meet 192.168.11.3 7001
redis-cli -p 7000 cluster meet 192.168.11.1 7002
redis-cli -p 7000 cluster meet 192.168.11.2 7002
redis-cli -p 7000 cluster meet 192.168.11.3 7002

redis-cli -h 192.168.11.2 -p 7001 cluster replicate $(redis-cli -p 7000 cluster nodes | grep 192.168.11.1:7000 | grep master | awk '{print $1}')
redis-cli -h 192.168.11.3 -p 7002 cluster replicate $(redis-cli -p 7000 cluster nodes | grep 192.168.11.1:7000 | grep master | awk '{print $1}')

redis-cli -h 192.168.11.3 -p 7001 cluster replicate $(redis-cli -p 7000 cluster nodes | grep 192.168.11.2:7000 | grep master | awk '{print $1}')
redis-cli -h 192.168.11.1 -p 7002 cluster replicate $(redis-cli -p 7000 cluster nodes | grep 192.168.11.2:7000 | grep master | awk '{print $1}')

redis-cli -h 192.168.11.1 -p 7001 cluster replicate $(redis-cli -p 7000 cluster nodes | grep 192.168.11.3:7000 | grep master | awk '{print $1}')
redis-cli -h 192.168.11.2 -p 7002 cluster replicate $(redis-cli -p 7000 cluster nodes | grep 192.168.11.3:7000 | grep master | awk '{print $1}')

redis-cli -h 192.168.11.1 -p 7000 cluster addslots {0..5460}
redis-cli -h 192.168.11.2 -p 7000 cluster addslots {5461..10922}
redis-cli -h 192.168.11.3 -p 7000 cluster addslots {10923..16383}

redis-cli -p 7000 cluster nodes # 노드가 cross 로 잘 묶여 있는지 테스트


3. Redis 5.x

(in 192.168.11.1 server)

redis-cli --cluster create 192.168.11.1:7000 192.168.11.2:7000 192.168.11.3:7000

redis-cli --cluster add-node 192.168.11.2:7001 192.168.11.1:7000 --cluster-slave --cluster-master-id $(redis-cli -p 7000 cluster nodes | grep 192.168.11.1:7000 | grep master | awk '{print $1}')
redis-cli --cluster add-node 192.168.11.3:7002 192.168.11.1:7000 --cluster-slave --cluster-master-id $(redis-cli -p 7000 cluster nodes | grep 192.168.11.1:7000 | grep master | awk '{print $1}')

redis-cli --cluster add-node 192.168.11.3:7001 192.168.11.2:7000 --cluster-slave --cluster-master-id $(redis-cli -p 7000 cluster nodes | grep 192.168.11.2:7000 | grep master | awk '{print $1}')
redis-cli --cluster add-node 192.168.11.1:7002 192.168.11.1:7000 --cluster-slave --cluster-master-id $(redis-cli -p 7000 cluster nodes | grep 192.168.11.2:7000 | grep master | awk '{print $1}')

redis-cli --cluster add-node 192.168.11.1:7001 192.168.11.1:7000 --cluster-slave --cluster-master-id $(redis-cli -p 7000 cluster nodes | grep 192.168.11.3:7000 | grep master | awk '{print $1}')
redis-cli --cluster add-node 192.168.11.2:7002 192.168.11.1:7000 --cluster-slave --cluster-master-id $(redis-cli -p 7000 cluster nodes | grep 192.168.11.3:7000 | grep master | awk '{print $1}')

redis-cli -p 7000 cluster nodes # 노드가 cross 로 잘 묶여 있는지 테스트

위 하드코딩 스크립트를 shell script 로 해서 확장성 있게 관리할 수도 있다.

#!/bin/bash

REDIS_IP_LIST=(192.168.11.1 192.168.11.2 192.168.11.3)
SERVER_COUNT=${#REDIS_IP_LIST[@]}
REPLICA_COUNT=2
readolny MASTER_PORT=7000

redis-cli --cluster create "${REDIS_IP_LIST[0]}":"$MASTER_PORT" "${REDIS_IP_LIST[1]}":"$MASTER_PORT" "${REDIS_IP_LIST[2]}":"$MASTER_PORT"

for ip_index in ${!REDIS_IP_LIST[*]}
do
    MASTER_IP=${REDIS_IP_LIST[ip_index]}

    for ((replica_index=1; replica_index<=REPLICA_COUNT; replica_index++))
    do
      SLAVE_IP=${REDIS_IP_LIST[(ip_index+replica_index) % $SERVER_COUNT]}
      SLAVE_PORT=$((MASTER_PORT+replica_index))
      echo "MASTER_IP:$MASTER_IP, MASTER_PORT:$MASTER_PORT, SLAVE_IP:$SLAVE_IP, SLAVE_PORT:$SLAVE_PORT"
      redis-cli --cluster add-node "$SLAVE_IP":"$SLAVE_PORT" "$MASTER_IP":"$MASTER_PORT" --cluster-slave --cluster-master-id \
          $(redis-cli -p $MASTER_PORT cluster nodes | grep "$MASTER_IP":"$MASTER_PORT" | grep master | awk '{print $1}')
    done
done

redis-cli -p $MASTER_PORT cluster nodes # 노드가 cross 로 잘 묶여 있는지 테스트

참조 : https://redis.io/topics/cluster-tutorial

댓글 남기기