본문 바로가기

Operations/Redis

[레디스] 클러스터링 적용하기

레디스 클러스터링의 필요성

레디스는 In-Memory DB로서 한번 장애가 발생한다면 데이터가 유실이 될 수도 있으므로 고가용성 유지를 위한 방법이 있어야 합니다.

Redis Replication(Master-Slave) 구조를 지원하며, 추가적으로 Sentinel, Cluster 구성 방법을 제공합니다. 

 

Replication은 단순하게 Master노드를 복제하여 Slave에서도 쓸 수 있도록 구성하는 방식입니다.

Sentinel은 Master노드가 장애시 복제된 Slave가 Master로 자동으로 승격되도록 구성하는 방식입니다.

Cluster는 이러한 고가용성 뿐만 아니라 Sharding을 제공하여 데이터를 분산하여 저장할 수 있도록 합니다. 

 

이중에서 클러스터링을 선택한 이유는 다음과 같습니다.

  • Sentinel과 Cluster를 비교 했을때 Sentinel이 더 좋은점은 데이터를 복제하여 중간에 서버가 다운되어도 데이터를 보존할 수 있다는점 인데 Cluster 또한 slave서버를 두어 이를 방지할 수 있다.
  • Cluster는 서버 확장에 용이하다. 대략 1000대의 노드까지 확장이 가능하며, 노드를 추가/삭제할 때 운영 중단 없이 Hash slot을 재구성 할 수 있다.
  • Cluster는 샤딩을 통해 데이터를 나눠서 저장한다. 반면 Sentienl은 한대의 Master가 여러대의 Slave에 데이터를 복사해서 저장한다.

사실 너무 고민할 필요 없습니다. 센티널도 클러스터링도 모두 failover가 가능하므로 어떤것으로든 고가용성을 유지하는게 중요합니다.

바로 시작!

일단 서버 세대에 레디스 6대를 구성 해보겠습니다. 이렇게 구성하면 서버1에 장애가 생겼을때 서버1의 슬레이브노드는 서버2에 있으므로 데이터의 유실 없이 레디스가 유지될 수 있습니다.

설치

mkdir redis
cd redis
wget http://download.redis.io/releases/redis-6.2.6.tar.gz
tar xzf redis-6.2.6.tar.gz
cd redis-6.2.6
make
sudo make install

wget으로 레디스를 다운로드받고 make로 설치까지 해주면 레디스를 실행 할 수 있게 됩니다.

src/redis-server redis.conf로 레디스를 실행 했을 때 정상 실행된다면 설치가 잘 된것을 확인할 수 있습니다. 

 

클러스터링을 위한 .conf파일 수정

mkdir logs
cp redis.conf redis_master.conf
cp redis.conf redis_slave.conf
vi redis_master.conf

로그 파일을 생성하고 master를 위한 conf파일과 slave를 위한 conf파일 두개를 만들어줍니다.

이때 테스트용으로 한 서버에 여러 레디스를 실행시킬것이라면 conf파일을 port를 통해 나누면 됩니다. (6300.conf, 6301.conf, 6302.conf) 등등.. 
bind 0.0.0.0
# 외부 서버에서 내부로 접근하려면 127.0.0.1이 아닌 0.0.0.0으로 해줘야 한다.
port [변수]
# 백그라운드에서 시작하도록 설정
daemonize yes
# 클러스터를 사용하겠다.
cluster-enabled yes
# 클러스터 구성 내용을 저장한는 파일명 지정 (자동 생성됨)
cluster-config-file nodes-[변수].conf
# 클러스터 노드가 다운되었는지 판단하는 시간 (3s)
cluster-node-timeout 3000
# Appendonly를 yes로 설정하면 rdb에 저장 안되고 aof에 저장됨
appendonly yes
# append only yes 시 해당 부분도 수정
appendfilename appendonly_[변수].aof
# 프로세스 아이디 저장 경로 설정
pidfile /var/run/redis_[변수].pid
# 로그 파일 저장 경로 지정
logfile logs/redis_[변수].log

변수부분에는 마스터노드의 conf파일의 경우 6300, 슬레이브 노드의 경우 6400을 넣어주면 됩니다.

만약 한 서버에서 테스트를 한다면 6301, 6401 ... 을 넣어서 구분해줍시다.

실행

src/redis-server redis_master.conf
src/redis-server redis_slave.conf

각 서버에서 마스터와 슬레이브 레디스를 하나씩 실행시켜 줍니다.

1, 2, 3번 서버에서 모두 레디스를 두개씩 실행시켜주면 총 6개의 레디스가 실행됩니다. 

 

클러스터링

# 마스터 설정 
redis-cli --cluster create 서버1_IP:6300 서버2_IP:6300 서버3_IP:6300
# 슬레이브 설정
redis-cli --cluster add-node 서버1_IP:6400 서버3_IP:6300 --cluster-slave
redis-cli --cluster add-node 서버2_IP:6400 서버1_IP:6300 --cluster-slave
redis-cli --cluster add-node 서버3_IP:6400 서버2_IP:6300 --cluster-slave

이 때 로컬에서는 서로 127.0.0.1로 해도 되지만 다른 서버와 연결을 해야할 때는 클러스터링을 거는 서버 또한 자신의 public IP를 써줘야 한다.

 

  • 클러스터링을 초기화 해야할 경우
redis-cli -p 6300 cluster reset

 

여기까지 실행시키면 레디스 클러스터링이 완성됩니다.

하지만 클러스터링은 완성 되었어도 막상 노드에 접근을 하게되면 (error) MOVED 에러가 뜨게됩니다.

키값 샤딩에 의해서 각 키값에 맞는 노드에 저장이 되어야하는데 레디스가 자동으로 해주지 않기 때문입니다.

이를 앱단위에서 처리할수도 있고, 서버단위에서 처리할수도 있는데 다음 포스팅에서 처리하는 방법에 대해 다루겠습니다.