레디스란

레디스는 인메모리에 키 벨류 데이터를 저장하는 구조를 가진다. 레디스는 데이터베이스 캐시 등 많은 용도로 사용하고 있고, 데이터의 높은 스피드 접근성을 제공한다.

레디스 센티넬이란

레디스 센티널은 레디스가 제공하는 것들을 분리해 놓은 프로세스이다. 레디스 인스턴스의 가용성이나, 마스터 디스커버리, 자동 페일오버(failover) 그리고 마스터 선출에 관한 모니터링을 한다. 한마디로 센티널은 분산환경에서 고가용성이나 페일오버 같은 추가적인 기능을 제공하는 레디스라고 보면 된다. 레디스 센티널은 일반적인 레디스와 결합한다.

레디스 클러스터는 더욱 확장 가능한 개발 전략이다. 센티널과 유사하게 페일오버와 설정 관리를 한다. 차이점은 최대 1000개 노드까지 선형적으로 용량을 확장할 수 있는 샤딩 기능이다.

기능

데이터베이스

레디스는 다수의 논리적인 데이터베이스를 지원한다. 비록 아직까지는 같은 파일에 유지되지만, 각 데이터베이스마다 서로 다른 밸류를 가지는 동일한 키를 사용할 수 있다. 서로 다른 데이터베이스 스키마와 같다.

기본적으로 레디스는 16개 논리적 데이터베이스를 제공하지만 사용자가 이 숫자를 바꿀 수 있다. 이러한 데이터베이스 들은 0부터 시작하는 인덱스로 식별할 수 있다.

레디스는 단일 스레드 데이터 저장소다. 따라서 모든 데이터베이스 작업은 같은 실행 파이프라인으로 이동된다.

해쉬 슬롯(Hash Slots)

레디스 클러스터는 일반적인 레디스와는 조금 다르게 작동한다. 예를들어 데이터 자동적으로 샤드를 하고 클러스터의 여러 노드에 분산한다, 레디스 클러스터는 이른바 해쉬 슬롯을 사용한다.

레디스 클러스터는 분산 잡을 일관된 해싱을 사용하여 작업하지 않는다. 대신 해쉬 슬롯을 사용한다. 각 클러스터는 모든 노드에 분산될 수 있는 16384 해쉬 슬롯을 가진다. 모든 작업동안 레디스 클라이언트는 키모듈 16384의 CRC16를 사용하여 해시를 계산한다. 그런 다음 이 명령을 사용하여 올바른 노드로 명령을 라우트한다.

각 노드에는 해쉬 슬롯의 하위 집합이 할당되어 있다. 그리고 리샤딩과 리밸런스 작업을 통해 슬롯을 노드들로 이동실 수 있다. 비록 이 접근 방식의 특수성을 고려할 때, 레디스 클러스터는 노드당 여러개 논리적 데이터베이스를 허용하지 않는다.

마지막으로 해쉬 슬롯에 있는 키의 분산 때문에, 레디스 클러스터는 여러 키와 관련된 작업은 주의 해야한다. 관련 키가 모든 키가 동일한 해쉬 슬롯에 있어야 이러한 작업을 계속 할 수 있다. 그렇지 않다면 레디스가 요청을 거부할 수 있다.

해쉬 태그(Hash Tags)

이 메커니즘은 사용자가 키 그룹이 동일한 해쉬 슬롯에 가도록 보장하는데 도움이 된다. 해쉬 태그를 정의하려면 사용자는 키에서도 괄호 사이에 하위 문자열을 추가해야한다. 예를들어 app{user:123}.mykey1, app{user:123}.mykey2는 같은 해쉬슬롯으로 갈것이다.

이렇게 하면 레디스는 하위 문자열을 사용하여 해쉬키를 생성하고 결과적으로 모든 키를 같은 해쉬 슬롯으로 라우팅 할 것이다.

비동기 복제(Asynchronous Replication)

레디스 클러스터와 일반적인 레디스는 비동기 복제를 사용한다. 이것은 레디스는 복제되는 것을 알려고 기다리지 않는다.

게다가 오류로 인해 쓰기 작업이 손실될 수 있는 작은 시간이 존재한다. 그러나 이러한 것을 최대한 완화할 수 있는 방법이 있다. 하지만 다시한번 말하지만 위험은 항상 존재하기 때문에 Redis는 강력한 일관성을 보장하지않는다.

페일오버(Failover)

레디스는 장애를 처리하고 어느정도 내결합성을 보장하는 다양한 메커니즘을 제공한다. 레디스 클러스터와 센티넬을 사용하는 표준 클러스터 모두 이러한 도구를 사용한다. 이러한 시스템에는 상태 점검 및 시간 초과에 기반한 장애 감지기가 제공된다.

레디스 클러스터는 하트 비트 및 가십 프로토콜을 사용한다. 각 노드는 다른 노드와 통신하고 메타데이터와 패킷을 교환하며 특정 노드가 응답하지 않을 경우를 대비하여 일부 시간 초과를 계산한다.

센티넬과 관련하여 각 센티넬 인스턴스는 레디스 인스턴스를 모니터링 한다. 센티넬 인스턴스도 서로 통신하며, 구성에 따라 통신 및 시간 초과 문제로 인해 failover를 실행할 수 있다.

마스터 선출(Master Election)

레디스 클러스터와 센티넬 모두 마스터 선출에 대한 전략을 가지고 있고 서로 다른 프로세스를 가진다. 그러나 주요 목표는 failover가 발생해야 하는지 여부와 어떤 것을 promote 해야하는지 결정하는 것이다.

센티넬은 quorum 개념과 함께 작동한다. quorum은 마스터 노드에 도달한지 아닌지 합의를 해야하는 센티넬 인스턴스의 최소 개수이다.

마스터가 실패로 표시되는 경우에 장애 조치 프로세스가 시작된다. 그 다음 센티넬의 과반 이상이 failover를 승인하고 failover를 담당하는 sentinel 인스턴스를 선택해야한다. 그런 다음 인스턴스는 승격할 최상의 읽기 복제본을 선택하고 오류 해결을 실행한다. 마지막으로 인스턴스는 새 설정을 다른 sentinel 인스턴스로 broadcast하기 시작한다.

레디스 클러스터의 경우 프로세스가 조금 다르다. 이번에는 복제본 노드가 담당한다. 이 경우 모든 노드는 노드간 통신을 하므로 하나 이상의 복제본이 장애를 감지하면 선출을 시작할 수 있다. 그 다음 단계는 마스터 선출을 요청하는 것이다. 선출이 시작되면 복제본은 장애 조치 권한을 받는다.

이러한 투표 메커니즘의 특성을 고려할 때, 레디스는 항상 클러스터에서 홀수의 노드를 사용할 것을 권장하며, 이는 두 구현 모두에 적용된다.

네트워크 파티션(Network Partition)

레디스는 다양한 장애를 극복할 수 있으며 노드가 다운된 경우에도 지속적인 작동을 제공할 수 있을 정도로 설계가 견고하다. 그러나 우리가 직면할 수 있는 중요한 문제는 네트워크 파티션이다.

split brain이라고 불리는 문제는 가장 직접정인 문제중 하나이다. 다음 예를 보자

image

여기서는 네트워크 파티션이 있고 한쪽에서는 클라이언트가 클러스터와 통신하고 있지만 이제는 1과 2의 두 인스턴스에만 연결 할 수 있다.

반면에 다른 클라이언트는 파티션에서 3과 4에만 연결 할 수있는 다른 파티션과 통신한다. quorom이 2개라고 가정하면 어느 시점에서 failover가 오른쪽에서 발생하고 다음과 같은 결과를 얻을 수 있다.

image

이제 redis3이 마스터로 승격된 두개의 클러스터가 있다. 네트워크 파티션이 사라지면 양쪽에 같은 키가 다른 값으로 작성된 경우 클러스터에 문제가 발생할 수 있다.

레디스 클러스터에도 동일한 원칙을 적용할 수 있고, 결과는 유사하다. 이것은 홀수가 권장되고 최소 복제본 대 쓰기와 같은 구성이 레디스에서 사용되는 이유를 보여준다. 이 방법은 항상 과반수만이 failover를 수행할 수 있는 다수 및 소수 파티션을 사용하는 것이다.

우리가 상상할 수 있듯이, 네트워크 파티션을 분할하는 동안 가능한 많은 다른 가능한 많은 다른 시나리오가 있다. 따라서 어떤 옵션을 선택하든 클러스터를 설계할 때 반드시 이해하고 염두에 두어야한다.

레디스 센티널 vs 레디스 클러스터

image

레디스 클러스터의 모든 세부 사항은 레디스 센티넬과 결합된 표준 구현을 사용하여 점을 연결할 수 있다

센티넬이 모니터링 내결함성 및 알림을 제공한다는 결론을 내릴 수 있다. 또한 인증 기능과 클라이언트 서비스 검색 기능을 제공할 수 있다. 클러스터에 16개 논리적 데이터베이스, 비동기 복제 및 고가용성을 제공할 수 있다. 클러스터에 16개의 논리적 데이터베이스, 비동기 복제 및 고가용성을 제공할 수 있다.

그럼에도 불구하고 redis의 단일 스레드 특성과 수직 확장의 장벽은 sentinel의 확장 기능을 제한하는 요인이다. 그러나 중소규모 프로젝트의 경우 이상적일 수 있다.

출처

[Redis Sentinel vs Clustering Baeldung](https://www.baeldung.com/redis-sentinel-vs-clustering)