티스토리 뷰

 

[Redis] Redis Sentinel vs Cluster

이전에 나는 면접에서 'Redis를 캐시로 사용했을 때, Redis가 멈출 수도 있는데 어떻게 대처하겠는가?'에 대한 질문을 받은 적이 있었다. 이 질문은 장애 대처 능력에 대해 물어본 것인데, 지식이 부

jojaeng2.tistory.com

Sentinel에 관련된 개념을 정리한 적이 있다. 이번에는 Redis Sentinel을 직접 사용해보기로 하자.

HA를 제대로 적용하기 위해서는 Master와 Slave를 물리적으로 다른 호스트에 둬야 한다. 하지만 나는 돈이 없고, 2개의 VM을 돌리기에는 노트북 사양이 부족하므로, 하나의 호스트에서 포트만 바꿔서 구축할 예정이다. 동작 프로세스에 대해 먼저 살펴보자.

한대의 Master Node를 두고, 2대의 Slave Node를 둔다. 각 호스트에 존재하는 Sentinel Node는 Master Node의 상태를 확인하는 역할을 수행한다.

만약 Master Node가 고장났다면, Sentinel Node는 투표를 진행한다. 이때 과반수 이상의 Node가 Master Node에서 장애가 발생했다고 판단한다면, Fail Over 작업을 시작한다. 그래서 기존의 Slave Node가 Master Node로 승격된다.

이제 기존의 Master Node가 다시 복구된다면, Slave Node가 되어 새로운 Master Node의 데이터를 복제한다. Redis Sentinel은 위와 같은 프로세스로 수행된다. 이제 실제로 구축을 해보자. Redis는 설치되어있으니, 바로 설정 파일을 건드려보자.

/opt/homebrew/etc

mac 기준으로 homebrew를 통해 redis를 설치했다면 위의 경로에서 설정 파일을 찾을 수 있다.

3대의 redis node를 사용할 것이므로, 설정 파일 3개를 만들어주자. 6380 포트로 띄운 redis를 Master Node로 사용할 것이다.

#6381.conf && 6382.conf

# replicaof <masterip> <masterport>
replicaof 127.0.0.1 6380


# repl-ping-replica-period 10
repl-ping-replica-period 10


# repl-timeout 60
repl-timeout 60

port 6381 || 6382

이제 6381, 6382.conf 파일을 위와같이 수정하고, redis를 띄워보자.

redis-server redis_6380.conf
redis-server redis_6381.conf
redis-server redis_6382.conf

Master Node인 6380으로 들어가서 데이터를 삽입해 보자.

redis-cli -p 6380
set master Done!

master node에서 정상적으로 데이터를 삽입했다. 과연 Slave node에서 데이터가 조회될까?

6381 redis node는 정상적으로 조회할 수 있고,

6382 redis node에서도 정상적으로 데이터를 조회할 수 있다.

그러면, Slave Node에서 데이터를 삽입해도 Master Node에서 조회할 수 있을까?

데이터를 삽입해 보면, Slave Node는 ReadOnly 설정이 되어있어 데이터를 write 할 수 없다고 한다.

그러면, 이제 Master Node가 죽었을 때, 어떤 일이 생기는지 살펴보기로 하자.

Master Node를 종료했다. 당연하게도 Master redis에서는 서버가 종료되어 명령어를 실행할 수 없다. 하지만, Slave Node들은 종료되지 않았기 때문에 명령어를 수행할 수 있다.

그리고 Slave Node에서는 여전히 데이터를 조회할 수 있다.

Slave Node들의 로그를 살펴보면, Master Node와 연결이 끊겨 계속해서 ping을 날리는 것을 볼 수 있다. 여기서 다시 종료된 Master Node를 켜주면,

다시 Master Node와 연결된 것을 볼 수 있다.

하지만, 이대로는 제대로 된 서비스를 수행할 수가 없다. Master Node가 죽으면, Slave Node에서는 Read만 가능하기 때문이다. 따라서 Master Node가 죽으면 Slave Node 중 하나를 Master Node로 승격시켜야 한다. 다시 Master Node를 죽이고, 6381 port로 열어놓은 redis에서 아래의 명령어를 입력해 보자.

127.0.0.1:6381> replicaof no one
OK
127.0.0.1:6381> config rewrite
OK

자신이 더 이상 Slave가 아니라는 설정이다.

127.0.0.1:6382> replicaof 127.0.0.1 6381
OK
127.0.0.1:6382> config rewrite
OK

그리고 6382로 열어놓은 redis에게 새로운 Master Node를 살려주는 설정이다.

그리고 이제 새로운 Master Node는 Read Only가 아니기에 데이터를 정상적으로 저장할 수 있다.

하지만, Master Node가 죽었을 때, 매번 Slave Node를 Master로 승격시키는 것은 매우 귀찮은 작업이고 실수하기도 쉽다. 따라서 Redis에서는 Master Node가 죽었을때, 자동으로 Slave 노드를 Master로 승격시켜주는 Sentinel Node를 제공하는데, 이를 적용해보기로 하자.

Sentinel

Sentinel은 Master와 Slave Node를 감시하고 있다가 Master가 종료되면 이를 감지해서 관리자의 개입 없이 자동으로 Slave를 Master로 승격시켜주는 도구이다.

위의 아키텍처처럼 3대의 Sentinel을 추가적으로 두어 master가 죽는다면 Slave를 자동으로 Master로 승격시키는 작업을 해보자.

Sentinel을 여러 대 두는 이유는 Sentinel 또한 장애가 발생할 수 있기 때문이고, 각각의 Sentinel이 Master가 다운되었는지 주기적으로 확인하는데, 이 결과를 통해 최종적으로 Master가 다운되었는지 아닌지 결정한다.

/opt/homebrew/etc

위의 경로에 들어가서, redis-sentinel.conf 파일을 찾은 후 복사를 수행하자.

$cp sentinel.conf /etc/redis/senti9000.conf

그리고 약간의 설정이 필요하다.

port 9000

...

# daemonized.
daemonize yes

먼저 sentinel이 사용할 포트 번호와 sentinel을 백그라운드로 실행시키기 위해 daemonize를 yes로 설정했다.

#sentinel monitor <master-name> <ip> <redis-port> <quorum>
sentinel monitor mymaster 127.0.0.1 6380 2

...

#sentinel down-after-milliseconds <master-name> <milliseconds>
sentinel down-after-milliseconds mymaster 10000

...

# sentinel parallel-syncs <master-name> <numreplicas>
sentinel parallel-syncs mymaster 1

...

# sentinel failover-timeout <master-name> <milliseconds>
sentinel failover-timeout mymaster 180000
  • sentinel monitor : Master Node의 ip와 port를 설정한다. quorum 값은 master가 최종적으로 다운되었다고 판단하기 위한 기준값이다. 예를 들어 현재 값을 2로 설정했기에, 3대의 sentinel 중 master가 다운되었다고 판단하는 sentinel이 2대 이상이면 최종적으로 master가 다운되었다고 판단한다.
  • sentinel paralllel-syncs : faliover가 발생했을 때 Master Node로부터 데이터를 가져오는 것을 시도하는 slave의 개수이다.
  • sentinel faliover-timeout : faliover의 timeout 값이다.

이제 이 설정 파일을 2개 더 복사해 주자.

cp redis-sentinel9000.conf redis-sentinel9001.conf
cp redis-sentinel9000.conf redis-sentinel9002.conf

그리고 설정 파일에 들어가서 port 번호만 9001, 9002로 변경하고, redis -> sntinel 순서로 전부 실행해 보자.

redis-server redis_6380.conf
redis-server redis_6381.conf
redis-server redis_6382.conf

redis-sentinel redis-sentinel9000.conf
redis-sentinel redis-sentinel9001.conf
redis-sentinel redis-sentinel9002.conf

sentinel까지 정상적으로 켰다면, 모든 설정이 끝난 것이다.

이제 sentinel까지 구축했으니, master가 다운되었을 때, 자동으로 Slave를 새로운 Master로 승격시키는지 확인해봐야 한다. 현재 Master Node인 6380번 redis를 다운시켜 보자.

그러자 6381번 포트를 사용하던 redis가 master로 승격되었다. 정말 그럴까? redis-cli에서 info replication 명령어를 사용하면 더 상세한 정보를 얻을 수 있다.

여기서 6380 redis를 다시 켠 후 상세 정보를 얻어보자.

6380이 slave가 되었고, master_port로 6381을 가리키는 것을 볼 수 있다. Master Node가 죽더라도, 자동으로 Slave Node를 Master로 유지할 수 있는 것이다.

Ref :

 

High availability with Redis Sentinel

High availability for non-clustered Redis

redis.io

 

'BackEnd > Redis' 카테고리의 다른 글

[Redis] Redis Sentinel vs Cluster  (0) 2023.01.07
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함