Redis Cluster를 처음부터 시작해서 하나씩 생성하는 것을 알아보도록 합니다. 직접 하나씩 명령을 수행해 가면서 진행하도록 하겠습니다.
Table Of Contents
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 프로그램을 간단하게 작성하고 테스트 하는 방법을 살펴보도록 하겠습니다.
'DBMS' 카테고리의 다른 글
Redis Cluster 리샤딩으로 데이터 조정하기 - Resharding (0) | 2024.05.31 |
---|---|
Redis Cluster 예제 app (ruby, python) (0) | 2024.05.30 |
Redis Cluster 쓰려면 어떤걸 설치 해야하지? - Redis OSS와 Stack의 차이 및 라이선스 그리고 Cluster는? (0) | 2024.05.28 |
벡터 데이터베이스란 무엇이며 어떻게 동작하는지 알아보기 (임베딩, 인덱싱 등) (0) | 2024.05.21 |
레디스(Redis) 최신 매출 정보(2023)와 회사 규모 (0) | 2024.05.16 |