안녕하세요 잼니크입니다.
이번 글에서는 Redis의 운영 방식에 대한 이야기를 하려 합니다.
지난 글 Redis 개발 환경 만들기: 설치에서 Redis 설치한 다음 동작하는지 확인했습니다.
이전 글이 궁금하시면 아래 링크를 클릭해 주세요!
그 다음 설정 파일을 만들어야 하는데... 설정을 하기 위해 Redis의 운영방식을 이해하고 장단점을 비교하려고 합니다.
오픈소스 Redis를 기준으로 standalone, sentinel, cluster 세 가지 선택지가 있습니다.
바쁘신 분들을 위해 각 선택지마다의 특징을 한 문장으로 정리하겠습니다
Standalone
독립적으로 동작하는 단순한구조, 설정이 간단, 장애가 발생했을 때 대응이 불가능, 신뢰도가 낮고 성능이 낮다
Sentinel
Master-Replica 구조에 Sentinel이 장애 발생을 체크하는 구조, 장애가 발생하더라도 서비스가 가능한 고가용성 구조, 단일 마스터로 인한 성능 문제, 클라이언트는 Sentinel의 존재를 알아야만 장애를 대응할 수 있음. 데이터베이스를 16개까지 나눠서 쓸 수 있는 장점(하지만...?)
Cluster
여려개의 Master와 Master를 지원하는 Replica가 서로를 감시하는 구조, Master는 Sharding(샤딩)을 지원해서 데이터를 분산 저장하고 분산 저장한 부분을 Replica를 통해서 장애가 발생하더라도 대응 가능. 단일 데이터베이스만 지원하지만 여러 개의 마스터가 분산 처리하기 때문에 확장성이 큼.
위 간단하게 정리한 내용은 아래에서 하나씩 설명하도록 하겠습니다.
1. Standalone(독립형 구조)
독립형 구조의 가장 큰 장점은 간단하다는 것 입니다. 특별하게 설정할 필요 없고, 테스트하기 좋지만 단일 인스턴스의 단점이 동일하게 적용 됩니다.
만약 위 그림에서 네트워크가 단절되어 접근이 불가능하거나, 오류 등으로 인해 실패가 발생하거나 프로그램이 종료돼버리면 데이터가 유실되거나 Redis의 서비스가 중단되게 됩니다. 따라서 독립형 구조는 가용성(Availability)이 가장 낮기 때문에 개발이나 테스트 환경에는 적합하지만, 상용서비스가 이루어지는 환경에는 사용할 수 없습니다.
상용 서비스 환경에서는 서비스 중단이 없도록 이중화 또는 다중화를 이용하여 고가용성(High Availability)을 만족 했습니다. 간단하게 설명하면 독립형 구조에서 처럼 하나의 서버가 요청을 처리하다가 문제가 생기면 다른 서버가 대기하고 있다가 요청을 받아서 대신 처리하는 방법을 사용합니다. 서버는 죽었지만 클라이언트 입장에서는 서비스가 중단이 없기 때문에 고 가용성을 만족하게 됩니다.
하지만 여기서 문제가 하나 있습니다. 문제가 생기면 대기하고 있는 서버에게 대신 처리할 수 있도록 만들어야 합니다.
관리자가 직접 나서서 할까요? 가능은 하지만...... 서버에 문제가 있는지 24/7 상시 대기하는 것이 비효율적일 겁니다. Redis에서는 관리자 대신 센티널이 대기 함으로써 문제를 해결합니다.
2. Sentinel (센티널 구조)
앞에서 언급한 고 가용성의 이야기를 기술적인 용어를 섞어 이야기 해 보겠습니다. 원래 서비스를 처리하던 서버를 master(마스터), 대기하고 있는 서버를 replica(레플리카)라고 하겠습니다. 좀 더 범용적인 언어로는 마스터와 레플리카 대신 Active와 Stanby라는 단어가 있지만 Redis에서 사용하는 언어를 사용하겠습니다.
위 그림에서 왼쪽은 정상인 상황입니다. 마스터가 서비스를 처리하면서, 대기하고 있는 레플리카에 데이터를 동기화 합니다. 그러다 갑자기 마스터가 실패가 발생하면, 위 그림의 우측처럼 대기하고 있던 레플리카가 마스터로 승격되어 서비스를 처리해서 가용성을 만족합니다. 이때 마스터를 감시하고 승격시키는 존재가 Sentinel(센티널)입니다.
센티널은 단어의 원 뜻인 보초 처럼 마스터에 문제가 없는지 주기적으로 PING 메시지를 보내고 마스터는 문제가 없다는 뜻으로 응답인 PONG을 보냅니다. 아래 그림을 보면서 설명을 이어 나가겠습니다.
위 그림의 왼쪽처럼 센티널은 PING 메시지를 보내고 PONG 메시지를 받고 있다가 가운데 그림처럼 마스터로부터 일정 시간 동안 PONG 메시지가 없으면 마스터에 문제가 있다고 판단하고 오른쪽 그림 처럼 여러 개의 센티널이 마스터에 문제가 있다고 합의하면 레플리카를 새로운 마스터로 승격시킵니다.
여기서 잠깐 짚고 넘어가야 할 것이 있습니다. 과반수와 정족수에 대한 내용입니다. 정족수의 사전적 의미는 의사결정을 하는데 필요한 최소한의 수입니다. 위 예제처럼 정족수가 과반수 이상, 즉 2일 경우도 있지만, 정족수가 과반수와 달라질 수 있습니다. 우선은 간단하게 이해를 하기 위해 과반수 이상=정족수라고 하고 넘어갑니다.
자 이제 그럼 새로운 마스터가 생겼습니다. 그런데 여기서 문제가 생깁니다. 클라이언트는 새로 마스터가 생겼다고 알려주지 않으면 응답이 없는 예전 마스터에 접근을 하려 하게 됩니다. 그래서 센티널 구조에서는 클라이언트가 마스터에 접근하기 위해서 센티널에게 마스터의 주소를 먼저 물어보고 마스터에 접근하게 됩니다. 그리고 원래 있던 마스터가 센티널에 응답하면, 센티널은 원래 마스터를 레플리카로 바꿔줍니다.
정리하면 센티널 구조의 장점은 Standalone 구조에서 고가용성을 추가로 만족할 수 있습니다. 또한, 이후에 이야기할 클러스터 구조와 다르게 Standalone의 모든 기능을 사용할 수 있지만 문제가 있습니다.
마스터는 1개만 있을 수 있기 때문에 쓰기 요청이 늘어날 경우 부하가 마스터에게만 몰려서 성능 문제가 발생할 수 있습니다.
3. Cluster(클러스터 구조)
클러스터 구조에서는 여러개의 마스터를 가질 수 있기 때문에 센티널 구조와 다르게 쓰기가 많이 발생하더라도 분산이 되기 때문에 문제가 발생할 가능성이 적어집니다. 하지만 특이사항으로 최소 6개의 노드가 필요하고, 각 마스터는 완전한 데이터의 복제본을 보관할 수 없습니다. 이게 무슨 이야기 인지 아래 그림을 보면서 클러스터를 설명드리겠습니다.
레디스 클러스터는 구성하기 위해서는 위 그림 처럼 최소 6개의 노드가 필요합니다. 그 중 3개의 노드는 마스터로서 동작하고, 나머지 3개는 마스터의 레플리카로서 동작합니다. 한 가지 특이한 사항은 각 마스터는 중복된 데이터를 저장하지 않고 데이터의 일부만 가지고 있습니다.
위 그림처럼 마스터가 3개 있을 경우 3개의 마스터가 모두 모여야 전제 데이터가 완성됩니다. 레디스에서는 마스터마다 저장할 데이터를 정하기 위해 Hash Slot(해시 슬롯)을 기준으로 마스터를 할당하고, 하나의 레플리카는 특정한 마스터의 복제본만 가지고 있습니다. 예를 들어 위 그림에서는 레플리카 1이 마스터 1의 데이터의 복제본을 저장하고 있습니다.
잠시 해시 슬롯에 대해 언급하고 넘어가겠습니다. 원래 해시에서 이야기하는 슬롯은 해시 테이블에서 데이터를 저장할 수 있는 공간입니다. 예를 들어 제가 '잼니크'라는 데이터를 해시로 돌린 값으로 저장할 해시 슬롯을 찾아 저장합니다. 레디스 클러스터에서는 해시 슬롯 번호를 기준으로 데이터가 어떤 마스터에 속할지, 혹은 속해 있는지를 알 수 있습니다.
해시 슬롯을 설명하기 위해 키-값을 저장하고 불러오는 예를 들어보겠습니다. 한 사용자가 '사용자 잼니크' 라는 키와 값을 저장하려고 하는데 키의 해시 연산의 결과로써 슬롯 번호가 5000이라고 나왔다면, 이 데이터는 마스터 1에 저장할 것입니다. 다른 사용자가 사용자라는 키의 값을 요청하면, 이 데이터의 값이 5000 인 것을 알 수 있기 때문에, 5000 마스터 1에 데이터가 있다는 것을 알고 사용자가 접근할 수 있습니다.
그런데 여기서 한가지 예상되는 문제가 있습니다. 만약 마스터 1에 이상이 생겨 중단이 된다면, 마스터 1의 데이터를 가지고 있는 레플리카 1이 마스터로 승격되어 동작이 되어야 하는데 클러스터에서는 마스터가 중단되었는지를 알고 승격을 시켜줄 센티널이 없습니다.
클러스터 구조에서는 센티널 대신 클러스터에 연결 된 모든 서버가 마스터의 중단을 알아차리고, 마스터들이 레플리카를 마스터로 승격할 수 있습니다. 클러스터 구조에서는 클러스터를 구성하는 모든 레디스 서버가 클러스터 버스를 통해 연결되어 있습니다. 만약, 위 그림처럼 한 서버가 특정한 서버에 문제가 있다는 것을 마스터와 레플리카 중 누군가가 알아차리면, 문제가 있다는 것을 클러스터 버스를 통해 서로에게 전파해서 클러스터 전체에 특정한 서버가 중단되었음을 알아차릴 수 있습니다. 만약 중단된 서버가 마스터 중 하나라면, 남아 있는 마스터가 센티널처럼 의사결정을 합니다. 정족수 이상의 마스터가 특정한 마스터의 중단이 있다고 판단하면, 중단된 마스터의 데이터를 저장한 레플리카를 마스터로 승격시키게 됩니다.
다음 글에서는 이 3가지 운영 방식으로 Redis를 설정하는 글로 넘어갑니다!
감사합니다!
끝!
이후에 이어지는 글
'IT > Redis' 카테고리의 다른 글
Redis standalone 모드 설정 (0) | 2022.06.12 |
---|---|
Redis 개발 환경 만들기: 설치 (0) | 2022.05.17 |