개발놀이터

나는 왜 Redis Cluster 대신 Redis Sentinel을 사용하였는가. 본문

CS 지식/데이터베이스

나는 왜 Redis Cluster 대신 Redis Sentinel을 사용하였는가.

마늘냄새폴폴 2024. 8. 12. 20:10

이번 포스팅에선 Redis Cluster에 대해서 깊이있게 공부해볼겸 왜 제가 Redis Cluster 대신 Redis Sentinel을 사용하게 되었는지 정리해보는 시간을 가져볼까합니다. 

 

Redis Cluster

Redis Cluster는 Redis Sentinel의 상위호환이라며 Redis의 고가용성을 위해서라면 Cluster를 사용해야한다는 포스팅을 어디선가 봤습니다. Cluster가 Sentinel과 어떻게 다르길래 이런말이 나오는지 자세히 알아봤습니다. 

 

Sentinel에 대해서는 아래의 링크에 자세히 설명되어있으니 짚고넘어가지 않습니다!

 

https://coding-review.tistory.com/472

 

Redis 장애시 RDBMS의 연쇄적인 장애에 대응하기 위한 전략

만약 캐싱 솔루션으로 Redis를 사용하고 있다면 Redis가 장애상황으로 죽어버리는 경우 RDBMS에 부하가 심하게 발생하여 RDBMS까지 연쇄적으로 장애가 발생하는 상황이 충분히 있을 수 있습니다. 저

coding-review.tistory.com

 

 

Cluster는 하나의 마스터노드와 최소 하나의 슬레이브노드가 쌍을 이뤄 클러스터를 이루고 이런 클러스터가 여러개 있는 형태를 말합니다. 

 

Hash Slot

Redis Cluster는 Hash Slot이라고 부르는 슬롯에 키를 저장하는데요. Hash Slot은 총 16384개를 가질 수 있고 이론적으로는 이 슬롯 하나에 하나의 노드를 가질 수 있어 총 1만6천개가량의 노드를 가질 수 있습니다...만! 

 

Redis 공식 문서에 따르면 노드는 최대 1000개를 넘기지 않는 것이 좋다고 하네요. 

 

어떤 키가 해쉬 슬롯에 저장되는 순서를 한번 알아봤습니다. 

 

  1. 키가 저장된다. (e.g. user:1000)
  2. 해당 키는 해쉬함수를 거쳐 어떤 값을 가지게 된다. (e.g. 123456789) 
  3. 이 값을 16384로 나누고 나머지를 계산한다. (e.g. 1567)
  4. 이 키는 1567번째 해쉬 슬롯에 저장된다. 

 

이때 해쉬 함수는 CRC16을 사용한다고 하네요. 

 

그럼 키가 조회할 때는 어떤 순서로 조회되는지 알아봤습니다. 

 

  1. user:1000라는 키가 조회된다.
  2. Cluster는 해당 키가 어떤 슬롯에 있는지 검사한다. 
  3. 1567번 슬롯을 관리하는 클러스터를 호출한다.
  4. 해당 클러스터에서 값을 가져온다. 

 

이렇게 하면 성능에 문제가 되지 않을까요? Redis 공식 문서에 따르면 Cluster로 구성한 것과 Standalone으로 구성한 것의 성능 차이는 미미하다고 하네요. (진짜..?)

 

아무리 해시함수가 빠르다고는 하지만 해싱을 하는 과정이 일반적인 과정보다는 latency가 있을 것 같은데 말이죠...

 

At the same time the query is usually performed in a single round trip, since clients usually retain persistent connections with the nodes, so latency figures are also the same as the single standalone Redis node case. 

- Redis 공식문서 발췌 -

 

뭐 그렇다고 하니 넘어가도록 합시다.

 

Hash Tag

해시 슬롯과 따라다니는 개념이 해시태그입니다. 이 해시태그가 SNS에서 사용하는 해시태그와 의미가 같은건지 잘 모르겠네요. SNS에서 해시태그가 가지는 의미와 어느정도 일맥상통하는 느낌이 있긴 합니다. 

 

Redis의 Hash Tag는 어떤 값을 해시슬롯에 넣을지 결정하는 일종의 라벨입니다. 이 태그가 붙어있는 것은 해시슬롯에 들어가며 Redis Cluster의 관리를 받습니다.

 

Redis Cluster에서의 해시태그는 중괄호 { } 안에 들어가는 값이 해싱함수를 거쳐 해시슬롯에 저장됩니다.

 

즉, {user:1000} 이렇게 키를 저장하면 user:1000이 해시슬롯에 들어간다는 의미입니다. 

 

이 때, Redis에서는 키에 중괄호가 들어가는 상황을 대비해 여러가지 규칙이 있었습니다. 예를 들어서 {{user:1000}}이렇게 키를 설정하면 첫번째 열린 중괄호를 기준으로 두번째 열린 중괄호는 무시하고 첫번째로 나온 닫는 중괄호까지 해시슬롯에 저장합니다.

 

그러니까 이때는 {user:1000 이렇게 해시슬롯에 저장한다는 의미이죠.

 

또한, 키를 {user:1000}.publisher 와 {user:1000}.subscriber 는 키는 다르지만 해시슬롯에 들어가는 값은 똑같아진다고 하네요.

 

High Scalability and Automatic Sharding

이런 일련의 과정을 자동으로 처리해주고 이 과정을 오토샤딩이라고 부릅니다. 이런 강력한 능력 덕분에 높은 확장성을 보여주는데요. 그냥 클러스터를 옆으로 늘리기만 하면 데이터도 알아서 해시슬롯에 보관되고 성능까지 올라가게 됩니다. 

 

"와... 이렇게 완벽할 수가 있나요? 그럼 당장 쓰자!"

 

샤딩은 디버깅을 힘들게하고 유지보수측면에서 최악인 기술중 하나입니다. 오죽했으면 MongoDB 공식 문서에서도 다음과 같은 문장이 있습니다. 

 

"샤딩은 최후의 방법으로 고려해봐라"

 

컴퓨팅 파워도 늘려보고 Replication도 해보고 모든 짓을 다해보고도 그 이상의 확장성이 필요하다면 그 때 샤딩을 고려하라는 말이 적혀있습니다.

 

그만큼 샤딩은 데이터를 관리하는 것이 굉장히 까다롭다는 말이 됩니다.

 

 

Automatic Failover

확장까지 유연한데 자동으로 장애회복까지 가능하다는 것이 믿기힘들지만 사실입니다.

 

만약 마스터 노드가 다운된 상태에서 뒤에서 대기하고 있던 슬레이브 노드가 마스터로 승격되는 과정을 거침으로써 고가용성을 챙길 수 있습니다.

 

또한, Redis 공식문서에 따르면 슬레이브노드가 마스터로 승격되는 데에 1~2초밖에 소요되지 않는다고 하네요. (진짜..?)

 

진짜라고 하니까 넘어가겠습니다...

 

이는 실습으로 한번 확인을 해보긴 해야겠네요. 

 

Redis Cluster는 서로 ping pong을 주고받으면서 서로의 생사를 확인하는데 이를 심장박동에 비유해 Heartbeat message 라고 표현하더군요. 

 

ping pong을 날려가면서 생사를 확인하고 생사가 불분명하다면 레플리카를 승격시키는 것이죠. 이때 생사가 불분명하지만 죽은 것 같아! 라는 의미의 PFAIL, 확실히 죽었어! 라는 의미의 FAIL 태그를 서버 이마에 붙여가면서 생사를 서로 판단하고 선출하는 과정을 거칩니다. 

 

이는 Redis Sentinel의 sdown, odown과 일맥상통하네요. 

 

Redis Cluster... 너무 완벽해...

사실 너무 완벽해서 공식문서를 읽는 중간부터는 이놈의 단점을 찾는데 혈안이 되었습니다. 이렇게 완벽한 솔루션은 있을 수 없어!!! 라는 고요속의 외침과 함께 단점을 찾아뒤지기 시작했습니다. 

 

Sharding은 Sharding이다

앞서서도 언급했지만 샤딩은 결국 샤딩입니다. 샤딩은 디버깅이 힘들고 관리하기가 굉장히 까다로워집니다. 데이터들이 해시함수를 타고 여기저기 왔다갔다 하면서 어디로 데이터가 저장되는지도 모르고 찾기가 힘들어진다는게 가장 큰 단점이지 않을까 싶네요. 

 

앞선 언급과 마찬가지로 샤딩은 최후의 최후까지 고려하지 않는 마지막 수단이어야할 것 같습니다. 

 

기본으로 내야하는 서버비가 6대라고?

미쳤다고밖에 할 말이 없는 유지비가 두번째 단점입니다. Redis 공식문서에서 추천하는 Redis Cluster의 개수는 세개입니다. 즉, 하나의 마스터노드와 최소 한개의 슬레이브노드가 쌍을 이룬 것이 세개 있어야 하니 총 여섯개의 서버가 필요하죠. 

 

그리고 뒤에서 더 자세히 설명하겠지만 사실 6대도 아니고 7대입니다. Redis Cluster를 구축할 때 고려해야할 사항 중 하나인 Split Brain 현상 때문에 노드를 홀수개로 유지해야하거든요. 그럼 7대가 Redis Cluster를 운영하기위한 최소 서버 대수입니다. 

 

이런 상황이다보니 Redis서버를 일곱대나 운영할 정도로 대규모 서비스가 아니라면 고려대상조차 안됩니다. 배보다 배꼽이 더 커지는 효과가 있죠. 

 

공식문서에서도 Sentinel은 소, 중규모의 서비스에서 Cluster는 대규모 서비스에서 사용하는 것을 추천한다고 나와있습니다. 

 

완벽한 HA는 아니다. 

만약 서버가 일곱대라고 가정하였을 때, 이 중 서버 두 대에 장애가 발생했습니다. 이때 이 두 대의 서버가 모두 살아날 확률은 얼마나 될까요? 

 

엥? 확률? 그냥 두 대가 죽었으면 두대가 살아나는거 아니야? 

 

정답은 90퍼센트입니다. 왜 10퍼센트의 확률로 두 대가 살아남지 못할까요? 

 

왜냐하면 Redis Cluster는 마스터와 슬레이브가 쌍을 이루는 하나의 클러스터로 이루어졌기 때문입니다. 이를 이해하기 위해선 상황을 가정해야합니다. 

 

총 노드가 7개이고 마스터가 3개 슬레이브가 4개인 상황을 가정해보도록 하겠습니다. 

 

마스터 노드는 M1, M2, M3 / 슬레이브 노드는 S1a, S1b, S2a, S3a 이렇게 있다고 가정하겠습니다. 

 

만약 M1, S2a가 죽었다면 어떻게 될까요? 

 

M1을 대신할 슬레이브 둘 중 하나를 선출하고 S2a는 원래부터 슬레이브 노드였으니까 문제없이 돌아갑니다. 

 

M1, M2가 죽은 상황은요? 

 

마찬가지로 각각의 슬레이브에서 하나씩 선출해서 마스터로 승격시키면 아무문제없습니다. 

 

하지만!

 

M3, S3a 이렇게 쌍으로 죽어버리면?

 

그럼 이 클러스터를 살릴 수 있는 것은 아무것도 없습니다. 이게 Redis Sentinel과 Redis Cluster의 가장 두드러지는 차이 중 하나입니다. 

 

Redis Sentinel은 몇대가 죽던간에 남아있는 슬레이브 중에서 마스터로 승격시킵니다. 모든 노드가 다 죽어버리지 않는 이상 Redis Sentinel은 살아있습니다. 

 

고려할 것이 또 있다. Split Brain 현상

네트워크가 불안정해 클러스터끼리의 통신이 불안정하다면 이 클러스터들이 쪼개지는 현상이 발생합니다. 

 

이런 상황을 가정해보겠습니다. 

 

 

이렇게 둘로 쪼개진 상황이라면 어떻게 될까요? 

 

Replica1 입장에선 마스터가 없습니다. 그럼 본인이 마스터로 승격되죠. Replica2, Replica3도 마찬가지입니다. 그럼 이 상황은 이런 결과를 초래합니다. 

 

 

이 상태를 냅두면 어떻게될까요? 

 

 

이렇게 서로 다른 네트워크에서 마스터 노드들이 앞다투어 데이터를 쓰게 되고 이 네트워크가 정상적으로 돌아와서 다시 합쳐지는 순간 대환장파티가 벌어집니다. 

 

Key_A가 abc야? def야? 이런 상황이 벌어지죠. 

 

이것이 바로 Split Brain 상황입니다. 

 

이 때문에 Redis Cluster는 홀수개의 노드를 구축함으로써 이 문제를 최소화하였습니다. 

 

 

이렇게 홀수개로 노드를 구성하면 Redis Cluster는 노드의 개수가 어느쪽이 많은지 확인할 수 있습니다. 이때 더 많은 쪽에서는 슬레이브를 마스터로 승격시키지만 더 적은 쪽에서는 슬레이브를 마스터로 승격시키지 않는 전략을 사용할 수 있습니다. 

 

그럼 슬레이브가 제멋대로 마스터로 승격되는 것을 방지할 수 있습니다. 

 

 

마치며

이제 결론입니다. 나는 왜 프로젝트에 Redis Sentinel을 썼는가? 저는 샤딩도 샤딩이지만 조금 더 높은 가용성을 선택하는 것이 조금 더 합리적인 선택이지 않나 싶습니다. (절대 서버 7대 살 비용 없어서 그런거 아닙니다)

 

온라인 쇼핑몰의 특성상 Redis에 의존하는 부분이 많아 Redis가 죽으면 뒤에 있는 RDBMS까지 죽어버려서 서비스 전체 장애로 이어질 가능성이 높은 상황이라 Redis의 생존 여부는 제 프로젝트에서 큰 영향을 미칩니다. 

 

또한, 본문에서는 설명하지 않았지만 Redis Sentinel은 자체적인 Notification을 가지고 있습니다. 물론 CloudWatch나 SNS를 이용하면 해결할 수 있지만 그에따른 추가적인 비용도 생각해봤을 때 Redis Sentinel이 적합한 판단이라고 생각합니다.

 

이렇게 Redis Cluster에 대해 포스팅 해보고 Redis Sentinel과 어떤 부분이 다른지 포스팅해봤습니다. 긴 글 읽어주셔서 감사합니다. 오늘도 즐거운 하루 되세요!

 

출처

https://semaphoreci.com/blog/redis-architectures

 

Understanding Redis High-Availability Architectures - Semaphore

This article covers Redis high-availability architectures, discussing pros and cons and offering guidance on the best fit for each use case.

semaphoreci.com

https://redis.io/docs/latest/operate/oss_and_stack/reference/cluster-spec/#performance

 

Redis cluster specification

Detailed specification for Redis cluster

redis.io

https://s-core.co.kr/insight/view/redis-%ED%81%B4%EB%9F%AC%EC%8A%A4%ED%84%B0%EC%97%90%EC%84%9C-split-brain-%EC%83%81%ED%99%A9%EC%9D%98-%EB%8C%80%EB%B9%84%EC%B1%85/

 

에스코어

에스코어는 디지털 혁신을 위한 고급 프로페셔널 서비스를 제공합니다. 매니지먼트 컨설팅과 소프트웨어 테크놀로지 서비스 오퍼링을 살펴보세요.

s-core.co.kr