Redis cluster 설정하기

수하·2021년 10월 30일
2

Redis

목록 보기
1/2

오늘은 Redis cluster에 대해 알아보고, 서버 3대에 cluster 설정을 할 것이다.
각 서버에 master 노드 1개씩, slave 노드 1개씩 추가할 것이다.

Redis cluster 란

필요성

Redis cluster는 데이터를 자동으로 여러 개의 Redis 노드에 나누어 저장할 수 있는 방법을 제공한다. 또한 일부 노드가 죽거나 통신이 되지 않을 때에도 작업을 계속할 수 있는 가용성을 제공한다. 단 과반수의 master 노드가 죽는 경우에는 클러스터도 중단된다.

즉, Redis cluter로 얻을 수 있는 이점은 아래와 같다:
1. 자동으로 여러 노드에 데이터를 나누어 저장할 수 있다
2. 일부 노드가 죽거나 통신이 되지 않을 때 작업을 계속할 수 있다.

추가적으로 Redis는 사용자 명령어를 처리하는 부분은 싱글 쓰레드로 동작한다. (Redis 6.0 부터는 ThreadedIO가 추가되어 사용자 명령에 멀티 쓰레드가 지원되지만, 명령어를 실행하는 코어 부분은 여전히 single thread며 IO Socket read/write를 할 때 멀티 쓰레드로 동작한다. Redis 6.0 features )

따라서, 어느 정도 규모가 있는 프로젝트에서는 Redis 사용 시, 반드시 클러스터로 구성하여 사용할 것이 권장된다.
짧은 Redis 사용 경험 상 테스트베드 환경에서도 standalone으로 구성된 Redis를 사용하면 클러스터로 구성하였을 때와 성능 차이가 많이 느껴진다.

구조

To be continued



서버에 redis 설치

서버는 총 3대에, master 노드 1개, slave 노드 1개씩 총 6개의 노드를 띄울 것이다.
따라서 서버 3대에 각각 redis를 설치해야 한다. (Redis 공식 홈페이지 참조)

서버 버전

Redis cluster를 설치할 서버는 CentOS 7.0이며, redis 버전은 현재 latest stable version인 6.2를 설치할 것이다.

설치

redis를 설치하는 명령어는 아래와 같다. 그냥 순서대로 입력해주면 잘 설치된다.

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

설치 후 redis-server 명령어를 입력했을 때, 서버가 잘 뜬다면 설치 성공이다.



cluster 설정

config 파일 설정

1. 서버 설정

서버 한 대당 master node 1개, slave node 1개씩을 구동시킬 것이다.
master는 모두 7000번 포트로, slave는 7001번 포트로 띄울 것이다.

cluster 구성 시 cluster bus가 통신하는 포트는 각 노드 포트 + 10000번이기 때문에 총 7000, 7001, 17000, 17001번 포트의 방화벽을 해제해야 한다.

  • cluster bus: 장애 감지, 구성 업데이트, failover 승인 등에 사용

또한 메모리 사용량 overcommit 처리 방식과 Accept 소켓 개수 설정을 변경해주자. (미설정시 WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. warning 발생)

# 메모리 사용량이 허용량을 초과할 경우, overcommit을 처리하는 방식 결정하는 값을 "항상"으로 변경
sudo sysctl vm.overcommit_memory=1
sudo echo "vm.overcommit_memory=1" >> /etc/sysctl.conf 
sudo sysctl -a | grep vm.overcommit

# 서버 소켓에 Accept를 대기하는 소켓 개수 파라미터를 변경
sudo sysctl -w net.core.somaxconn=1024
sudo echo "net.core.somaxconn=1024" >> /etc/sysctl.conf 
sudo sysctl -a | grep somaxconn

2. 디렉토리 구조

/opt/redis 디렉토리를 생성하여, redis 설치 디렉토리 (그대로 입력했다면 redis-stable일 것이다)의 redis.conf 파일을 /opt/redis에 복사한다.

그리고 /opt/redis 아래에 7000, 7001이라는 폴더를 생성한다. (/opt/redis/7000, /opt/redis/7001이다)

3. master 노드 conf 파일 생성

/opt/redis/7000에 7000.conf 파일을 생성하여 아래와 같이 입력한다.

include /opt/redis/redis.conf

bind 0.0.0.0
daemonize yes
protected-mode no

port 7000
pidfile /opt/redis/7000/redis_7000.pid
logfile /opt/redis/7000/redis-7000.log
dir /opt/redis/7000
dbfilename dump_7000.rdb

requirepass [redis password]
masterauth [redis password]

cluster-config-file node-7000.conf
cluster-enabled yes
cluster-node-timeout 5000
cluster-announce-ip [서버 public ip] # NAT/포트포워딩 사용시

rename-command keys ""

appendonly no
  • requirepass: redis 서버에 password를 설정한다. 기본 설정은 null이며, redis.conf에 plain text로 적는다. 길이 제한은 없으며, 150K 정도로 길어도 된다고 한다. 나는 openssl rand -base64 32로 랜덤한 비밀번호를 생성하였다.
  • masterauth: master 노드에 패스워드 설정이 되어있는 경우, slave가 replication synchronization 작업을 하기 전에 slave에게 비밀번호를 알려줘야 한다. slave가 비밀번호를 모를 경우 master가 slave의 요청을 거절한다. 위에 requirepass에서 적은 비밀번호를 입력해주자.
  • cluster-enabled yes를 추가해야 클러스터 모드가 켜진다. no로 하면 standalone 모드로 실행된다.
  • cluster-config-file nodes.conf : 이 파일은 클러스터의 상태를 기록하는 바이너리 파일이다. 클러스터의 상태가 변경될때 마다 상태를 기록한다.
  • cluster-node-timeout 5000 : 레디스 노드가 다운되었는지 판단하는 시간이다. 단위는 millisecond이다.
  • cluster-announce-ip: docker를 사용하거나, NAT 설정이 되어있거나 포트포워딩 되어있는 경우에는 Redis cluster 노드를 찾을 수 없는 상황이 발생한다. (redis.conf document 참조) 이런 경우, 각 노드에게 자신의 static public IP를 알려줄 필요가 있다.

4. slave 노드 conf 파일 생성

/opt/redis/70001에 7001.conf 파일을 생성하여 아래와 같이 입력한다.

include /opt/redis/redis.conf

bind 0.0.0.0
daemonize yes
protected-mode no

port 7001
pidfile /opt/redis/7001/redis_7001.pid
logfile /opt/redis/7001/redis-7001.log
dir /opt/redis/7001
dbfilename dump_7001.rdb

requirepass [redis password]
masterauth [redis password]

cluster-config-file node-7001.conf
cluster-enabled yes
cluster-node-timeout 5000
cluster-announce-ip [서버 public ip]

rename-command keys ""

appendonly no

5. 노드 띄우기

각 서버에 있는 7000, 7001번 노드들을 모두 실행해야 한다. (귀찮으니 스크립트로 만들어두자)

redis-server 7000/7000.conf 
redis-server 7001/7001.conf

ps -ef | grep redis로 7000, 7001번 노드가 모두 떴는지 확인한다.

daemonized 모드로 실행하여 화면에 별다른 로그가 보이진 않는다.
/opt/redis/7000/redis-7000.log를 확인하면 된다.

클러스터에 master 노드 추가하기

서버 한 대에서 다음 명령으로 클러스터를 실행하고, Can I set the above configuration? (type 'yes' to accept)에 yes를 입력한다.

redis-cli -a [비밀번호] --cluster create [서버1 IP]:7000 [서버2 IP]:7000 [서버3 IP]:7000

이 때, Waiting for the cluster to join 과 함께 .....이 끝없이 찍힌다면, 포트 방화벽이 모두 열렸는지 확인해보자.

삽질 1. .conf 파일에 cluster-announce-ip 를 입력하지 않고, NAT로 연결된 public IP로 클러스터 연결하는 경우, 노드 연결이 되지 않는다.

처음에는 서버 방화벽 문제인줄 알았다..😩 방화벽은 모두 뚫려있는데 왜 안되는지 오랜 시간 삽질 결과...
현재 서버의 public IP 는 NAT 설정이 되어있는데, 이런 경우 redis cluster의 node address discovery가 실패할 수 있다고 한다.
그래서 cluster-announce-ip 설정을 추가하여 노드 설정을 했더니 정상적으로 된다. 😂

클러스터에 slave 노드 추가하기

서버 한 대에서 다음 명령으로 slave 노드를 추가한다.
서버 2의 7001번 노드는 서버 1의 master 노드의 slave, 서버 3의 7001번 노드는 서버 2의 master 노드의 slave... 이렇게 서로 다른 서버에 master-slave를 두도록 한다.

redis-cli -a [비밀번호] --cluster add-node [서버2 IP]:7001 [서버1 IP]:7000 --cluster-slave
redis-cli -a [비밀번호] --cluster add-node [서버3 IP]:7001 [서버2 IP]:7000 --cluster-slave
redis-cli -a [비밀번호] --cluster add-node [서버1 IP]:7001 [서버3 IP]:7000 --cluster-slave

[OK] New node added correctly 메시지까지 확인하였으면, 노드 추가가 성공적으로 된 것이다.

아무 redis 노드나 접속하여 (redis-server -h [서버IP] -p 7000) 클러스터 정보를 확인한다.

[IP]:7000> AUTH [비밀번호] # 사용자 인증 필요
[IP]: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:6
cluster_size:3
cluster_current_epoch:3
cluster_my_epoch:1
cluster_stats_messages_ping_sent:1934
cluster_stats_messages_pong_sent:1915
cluster_stats_messages_sent:3849
cluster_stats_messages_ping_received:1911
cluster_stats_messages_pong_received:1934
cluster_stats_messages_meet_received:4
cluster_stats_messages_received:3849

[IP]:7000> cluster nodes
XXX [IP]:7001@17001 slave XXX 0 1635593861555 3 connected
XXX [IP]:7000@17000 myself,master - 0 1635593860000 1 connected 0-5460
XXX [IP]:7001@17001 slave XXX 0 1635593861254 2 connected
XXX [IP]:7000@17000 master - 0 1635593860550 2 connected 5461-10922
XXX [IP]:7001@17001 slave XXX 0 1635593860000 1 connected
XXX [IP]:7000@17000 master - 0 1635593860249 3 connected 10923-16383



테스트

set 테스트

redis-server -h [서버IP] -p 7000 -c -a [비밀번호] 를 입력하여 redis-server 에 클러스터 모드로 접속한다. (-c 입력 필수)

클러스터 모드로 접속하지 않으면 key setting을 했을 때 아래처럼 오류가 발생한다.

[IP-1]:7000> set key hi
(error) MOVED 12539 [IP-3]:7000

set key hi는 key의 slot이 12539번이라서 3번 노드에 할당되어야 하는데, 클러스터 모드로 접근하지 않아 redis-cli 가 다른 노드에 접속하지 못하여 발생하는 오류이다.

-c로 클러스터 모드를 켜서 접속하면 아래처럼 성공하고, 3번 노드로 바뀌는 것을 볼 수 있다.

[IP-1]:7000> set key hi
-> Redirected to slot [12539] located at [IP-3]:7000
OK
[IP-3]:7000> get hi

Redis client UI 프로그램으로 테스트하기

  1. 설정
    로컬에 Redis client UI 프로그램인 P3X를 깔아준다.
    P3X를 실행하고 SETTING에 들어가서 NEW CONNECTION 버튼을 클릭한다.

    hostname에 서버 한 대의 IP 주소와 master 포트 하나를 입력하고, ADD NODE 버튼을 클릭하여 나머지 노드 5개도 설정해준다.
    TEST CONNECTION 버튼을 클릭했을 때, 우하단에 successful 메시지가 뜨면 성공이다.
  1. 좌하단에서 CONNECT 버튼을 클릭하여 방금 입력한 profile을 선택한 후, 아래와 같이 화면이 뜨면 클러스터 연결이 잘 된 것이다 😎



클러스터 설정은 모두 완료되었다.
다음 포스트에서는 장애 복구 시나리오를 해볼 예정이다.

0개의 댓글