본문 바로가기
DBMS

Redis Cluster 리눅스에 설치하고 테스트 하기

by developer's warehouse 2024. 5. 29.

Redis Cluster를 처음부터 시작해서 하나씩 생성하는 것을 알아보도록 합니다. 직접 하나씩 명령을 수행해 가면서 진행하도록 하겠습니다.

Redis Cluster 리눅스에 설치하고 테스트 하기 썸네일

Redis 설치하기

Redis를 설치하는 법은 여러가지가 있는데 이 글에서는 안정 버전의 Redis를 다운받고 컴파일하는 방법을 통해 설치합니다.

다음의 명령을 수행하여 설치하실 수 있습니다. 여기에서 make install을 하면 시스템(/usr/local/bin)에 redis-server가 설치됩니다.

wget http://download.redis.io/redis-stable.tar.gz
tar xvzf redis-stable.tar.gz
cd redis-stable
make
make install

Redis 클러스터를 인스턴스 시작하기

클러스터를 생성하려면 먼저 클러스터 모드에서 실행 중인 빈 Redis 인스턴스 몇 개가 있어야 합니다.
redis.conf 파일에 다음과 같이 옵션을 넣고 클러스터 인스턴스를 시작 할 수도 있고, redis-server를 시작할때, 인자로 옵션을 넘길 수도 있습니다.

redis.conf

redis.conf에 설정하는 최소 사양은 다음같습니다.

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

 

cluster 설정에 관련 옵션 상세 설명은 다음 링크에서 확인하실 수 있습니다.

Redis Cluster 설정 매개변수 설명 보러 가기

 

클러스터 모드를 사용하려면 cluster-enable을 yes로 설정합니다. 또한 모든 인스턴스에는 이 노드의 구성이 저장되는 파일 경로가 포함되어 있으며, 기본값은 nodes.conf입니다. 이 파일은 사용자가 절대 건드리지 않으며, Redis 클러스터 인스턴스가 시작할 때 간단히 생성되고 필요할 때마다 업데이트됩니다.

예상대로 작동하는 최소 클러스터에는 마스터 노드가 3개 이상 포함되어야 합니다. 마스터 노드 3개와 복제본 3개로 구성된 6노드 클러스터를 권장합니다.

 

그런데, 위의 설정으로 시작시키면 한 노드에 실제 하나의 redis-server만 띄울 수 있습니다. 그런데 저는 테스트를 위해서 한 장비에 여러개의 redis-server를 cluster로 시작시키고 싶습니다.


이를 위해서 특정 디렉터리 내에서 실행할 인스턴스의 포트 번호를 따서 다음 디렉터리를 만들어 로컬에서 테스트할 수 있습니다.

 

redis 소스에는 한 장비에서 여러개의 redis cluster 인스턴스를 띄우고 테스트를 할 수 있게 해주는데 create-cluster라는 툴입니다.

create-cluster 툴 분석하여 redis-server 시작시 인자로 넘기기

redis 소스를 컴파일하면 utils/create-cluster 디렉토리에 create-cluster라는 redis cluster를 테스트 해볼 수 있는 스크립트가 존재합니다. 이 스크립트에서는 레디스 인스턴스를 시작해 주는데 클러스터에 필요한 옵션을 인자로 넘겨서 다수의 redis-server를 시작합니다.

해당 스크립트에 존재하는 redis cluster 인스턴스를 시작하는 코드는 다음과 같습니다.

< create-cluster 스크립트 파일의 start 내용 >

TIMEOUT=2000
PORT=30000
NODES=6
ENDPORT=$((PORT+NODES))
if [ "$1" == "start" ]
then
    while [ $((PORT < ENDPORT)) != "0" ]; do
        PORT=$((PORT+1))
        echo "Starting $PORT"
        $BIN_PATH/redis-server --port $PORT --protected-mode $PROTECTED_MODE --cluster-enabled yes --cluster-config-file nodes-${PORT}.conf --cluster-node-timeout $TIMEOUT --appendonly yes --appendfilename appendonly-${PORT}.aof --appenddirname appendonlydir-${PORT} --dbfilename dump-${PORT}.rdb --logfile ${PORT}.log --daemonize yes ${ADDITIONAL_OPTIONS}
    done
    exit 0
fi

 

위의 쉘 스크립트에서는 6개의 redis-server를 다음의 옵션으로 시작합니다.
위의 쉘에서는 여러개의 인스턴스가 하나의 장비에서 실행 될 수 있도록 PORT로 구분하여 시작시키는 방법을 사용합니다.
--cluster-enabled : yes
--cluster-config-file : nodes-${PORT}.conf
--dbfilename dump-${PORT}.rdb
--appendonly yes --appendfilename appendonly-${PORT}.aof --appenddirname appendonlydir-${PORT}
--logfile ${PORT}.log

 

위의 쉘 명령을 통해서 redis cluster 인스턴스를 시작하면 아래와 같이 30001부터 30006까지 6개의 redis cluster 인스턴스가 시작됩니다.

% ./create-cluster start
Starting 30001
Starting 30002
Starting 30003
Starting 30004
Starting 30005
Starting 30006

 

이렇게 시작하면, 시작한 디렉토리에 다음과 같은 각 인스턴스의 파일과 디렉토리가 생성됩니다.

redis-stable/utils/create-cluster
% ls
30001.log 30003.log 30005.log README appendonlydir-30002/ appendonlydir-30004/ appendonlydir-30006/ nodes-30001.conf nodes-30003.conf nodes-30005.conf
30002.log 30004.log 30006.log appendonlydir-30001/ appendonlydir-30003/ appendonlydir-30005/ create-cluster* nodes-30002.conf nodes-30004.conf nodes-30006.conf

 

이렇게 시작한 후에는 각 인스턴스의 로그를 확인하여 redis cluster 인스턴스의 ID를 확인하실 수 있습니다. I'm 뒤에있는 문자와 숫자 조합이 해당 인스턴스의 ID가 됩니다.

% cat 30001.log
1....
115600:M 29 May 2024 10:13:03.868 * No cluster configuration found, I'm c642cf6f5b90f7866c88f311166299b640d0c4f1
115600:M 29 May 2024 10:13:03.872 * Server initialized
115600:M 29 May 2024 10:13:03.875 * Creating AOF base file appendonly-30001.aof.1.base.rdb on server start
...

 

이 ID는 클러스터에서 인스턴스가 고유한 이름을 갖도록 하기 위해 이 특정 인스턴스에서 영구적으로 사용됩니다. 모든 노드는 IP나 포트가 아닌 이 ID를 사용하는 다른 모든 노드를 기억합니다. IP 주소와 포트는 변경될 수 있지만 고유한 노드 식별자는 노드의 모든 운영기간 동안 절대 변경되지 않습니다. 이 식별자를 간단히 노드 ID라고 부릅니다.

 연관 글 보기
 Redis Cluster 쓰려면 어떤걸 설치 해야하지? - Redis OSS와 Stack의 차이 및 라이선스 그리고 Cluster는?
Redis Cluster 리눅스에 설치하고 테스트 하기
Redis Cluster 예제 app (ruby, python)
Redis Cluster 리샤딩으로 데이터 조정하기 - Resharding

 

Redis 클러스터 생성

이제 여러 인스턴스가 실행 중이므로 노드에 의미 있는 구성을 작성하여 클러스터를 만들어야 합니다.

개별 인스턴스를 수동으로 구성하고 실행하거나 create-cluster 스크립트를 사용할 수 있습니다. 수동으로 하는 방법을 살펴보겠습니다.

클러스터를 만들려면 다음을 실행합니다.

redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 \
127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \
--cluster-replicas 1

 

위의 명령은 새 클러스터를 생성하는 명령입니다. create라는 명령을 사용합니다. --cluster-replicas 1 옵션은 모든 마스터에 대한 복제본을 생성한다는 의미입니다.
다른 인수는 새 클러스터를 만드는 데 사용할 인스턴스의 주소 목록입니다.

create-cluster 스크립트에는 create 명령을 받아들일 수 있습니다.

if [ "$1" == "create" ]
then
    HOSTS=""
    while [ $((PORT < ENDPORT)) != "0" ]; do
        PORT=$((PORT+1))
        HOSTS="$HOSTS $CLUSTER_HOST:$PORT"
    done
    OPT_ARG=""
    if [ "$2" == "-f" ]; then
        OPT_ARG="--cluster-yes"
    fi
    $BIN_PATH/redis-cli --cluster create $HOSTS --cluster-replicas $REPLICAS $OPT_ARG
    exit 0
fi

 

redis-cli가 대화형으로 클러스터 구성을 제안하고 사용자의 의견을 확인하는 프롬프트가 나타납니다.

여기서 yes를 입력하여 제안된 구성을 수락하고 해당 구성으로. 클러스터가 구성되고 노드가 참여하게됩니다.

% ./create-cluster create
/redis-stable/utils/create-cluster/../../src//redis-cli --cluster create  127.0.0.1:30001 127.0.0.1:30002 127.0.0.1:30003 127.0.0.1:30004 127.0.0.1:30005 127.0.0.1:30006 --cluster-replicas 1
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 127.0.0.1:30005 to 127.0.0.1:30001
Adding replica 127.0.0.1:30006 to 127.0.0.1:30002
Adding replica 127.0.0.1:30004 to 127.0.0.1:30003
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: c642cf6f5b90f7866c88f311166299b640d0c4f1 127.0.0.1:30001
   slots:[0-5460] (5461 slots) master
M: 8854bd1bce789d8d6b0c6887ac5e26c69ae898fd 127.0.0.1:30002
   slots:[5461-10922] (5462 slots) master
M: a164a5b8ce13ad30a9ab52313655bb5e025a4f34 127.0.0.1:30003
   slots:[10923-16383] (5461 slots) master
S: 6cc537b7ba8442a5129b0dfd0089e56e8ae08639 127.0.0.1:30004
   replicates a164a5b8ce13ad30a9ab52313655bb5e025a4f34
S: 2fd36b04128b8f171ec6016380b3b2643b0b9f1e 127.0.0.1:30005
   replicates c642cf6f5b90f7866c88f311166299b640d0c4f1
S: 0e8d678ac74631603c1f0b3b398bd73f5143d22a 127.0.0.1:30006
   replicates 8854bd1bce789d8d6b0c6887ac5e26c69ae898fd
   Can I set the above configuration? (type 'yes' to accept): yes

 

이는 인스턴스가 서로 통신할 수 있도록 시작된다는 것을 의미합니다. 마지막으로 모든 것이 잘 되었다면 다음과 같은 메시지가 표시됩니다.

[OK] All 16384 slots covered

 

실제 테스트 결과는 다음과 같습니다. yes를 입력 후 Master 3개와 Slave 3개가 나타났습니다.

Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
.
>>> Performing Cluster Check (using node 127.0.0.1:30001)
M: c642cf6f5b90f7866c88f311166299b640d0c4f1 127.0.0.1:30001
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: 2fd36b04128b8f171ec6016380b3b2643b0b9f1e 127.0.0.1:30005
   slots: (0 slots) slave
   replicates c642cf6f5b90f7866c88f311166299b640d0c4f1
S: 6cc537b7ba8442a5129b0dfd0089e56e8ae08639 127.0.0.1:30004
   slots: (0 slots) slave
   replicates a164a5b8ce13ad30a9ab52313655bb5e025a4f34
S: 0e8d678ac74631603c1f0b3b398bd73f5143d22a 127.0.0.1:30006
   slots: (0 slots) slave
   replicates 8854bd1bce789d8d6b0c6887ac5e26c69ae898fd
M: 8854bd1bce789d8d6b0c6887ac5e26c69ae898fd 127.0.0.1:30002
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
M: a164a5b8ce13ad30a9ab52313655bb5e025a4f34 127.0.0.1:30003
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

 

즉, 16384개의 사용 가능한 슬롯 각각에 서비스를 제공하는 마스터 인스턴스가 하나 이상 있다는 뜻입니다.

Redis Cluster와 통신하기

Redis 클러스터에 연결하려면 클러스터를 인식하는 Redis 클라이언트가 필요합니다.

redis-cli를 사용하여 Redis 클러스터를 테스트할 수 있습니다.

 

redis-cli 클러스터 지원은 매우 기본적이므로, 항상 Redis 클러스터 노드가 클라이언트를 올바른 노드로 리디렉션할 수 있다는 사실을 사용합니다. 클라이언트는 해시 슬롯과 노드 주소 사이의 맵을 캐시하여 올바른 노드에 대한 올바른 연결을 직접 사용할 수 있습니다.

맵은 장애 조치 후 또는 시스템 관리자가 노드를 추가하거나 제거하여 클러스터 레이아웃을 변경한 후와 같이 클러스터 구성에 변경 사항이 있는 경우에만 새로 고쳐집니다.

 

다음과 같이 redis-cli를 이용해서 30001 포트의 master 노드에 접속합니다.

아래 예제에서 foo와 hello를 key로 set 할 때 노드간 직접 커넥션을 전환하는 것을 확인할 수 있습니다. redis-cli에서 client가 key에 대한 hash 값을 판단하여 어느 노드로 접속할 지 확인합니다.

% ./redis-cli -c -p 30001
127.0.0.1:30001> set foo bar
-> Redirected to slot [12182] located at 127.0.0.1:30003
OK
127.0.0.1:30003> set hello world
-> Redirected to slot [866] located at 127.0.0.1:30001
OK
127.0.0.1:30001> get foo
-> Redirected to slot [12182] located at 127.0.0.1:30003
"bar"
127.0.0.1:30003> get hello
-> Redirected to slot [866] located at 127.0.0.1:30001
"world"
127.0.0.1:30001> hset bike:1 name lswhh age 46 length 175
-> Redirected to slot [7810] located at 127.0.0.1:30002
(integer) 3
127.0.0.1:30002> hset bike:2 name mhee age 46 length 170
-> Redirected to slot [12001] located at 127.0.0.1:30003
(integer) 3
127.0.0.1:30002> hget bike:1 name
"lswhh"
127.0.0.1:30002> hgetall bike:2
-> Redirected to slot [12001] located at 127.0.0.1:30003
1) "name"
2) "mhee"
3) "age"
4) "46"
5) "length"
6) "170"

 

redis-cli에서 -c 옵션은 아래와 같이 cluster 모드로 동작하는 cli를 말합니다.

-c Enable cluster mode (follow -ASK and -MOVED redirections).

 

오늘은 redis cluster를 설치하고 redis-cli를 이용해서 간단하게 명령을 수행하는 방법과 예제를 알아보았습니다.

다음시간에는 redis client 프로그램을 간단하게 작성하고 테스트 하는 방법을 살펴보도록 하겠습니다.

 

facebook twitter kakaoTalk kakaostory naver band shareLink