Gidhub BE Developer

Redis Master/Slave와 Cluster

2019-02-13
goodGid

  • Redis Master-slave 및 Redis Cluster를 분석한다.

Redis Master/Slave

  • Redis Master-slave는 Redis에서 제공하는 가장 기본적인 Replication 기법이다.

  • 위의 그림은 Redis Master-slave 구성시 Architecture를 나타내고 있다.

  • Redis의 Master-Slave 기법은 MySQL의 Master-slave Replication 기법과 유사하다.

  • 하나의 Master에 다수의 Slave가 붙을 수 있다.

  • Master는 Read-Write Mode로 동작하고 Slave는 Read-Only Mode로 동작한다.

  • Redis Client는 필요에 따라서 Master에 붙어 Write 동작을 수행하거나

  • 적절한 Master or Slave에 붙어 Read 동작을 수행할 수 있다.


  • Master-slave 사이의 Replication은 Async 방식을 이용한다.

  • Master는 Data 변경시 변경 내용을 backlog에 기록한다.

  • Slave는 Master에 접속하여 backlog의 내용을 바탕으로 Replication을 수행한다.

  • Async이기 때문에 Master에 저장된 Data가 Slave에는 잠깐동안 저장되지 않을 수 있다.

  • 따라서 Redis Client(App)는 Slave에서 Data를 Read시 Async 특징을 반드시 고려해야한다.


  • Master가 죽을경우 Slave는 Master에게 주기적으로 Connection을 요청하며 Master가 되살아 날때까지 대기한다.

  • Master가 살아나면 Slave는 Replication을 수행하여 Master와 동기화를 맞춘다.

  • Master의 복구가 힘든 경우 Redis 관리자는 Slave 중에서 하나를 수동으로 Master로 승격시키고

  • 나머지 Slave들을 새로운 Master로부터 Replication 하도록 설정 해야한다.

  • Master가 바뀐뒤에는 죽었던 Master는 새로운 Master의 Slave로 설정하여 이용한다.

Sentinel

  • Master의 동작이 멈출경우 Redis Client는 Slave를 통해서 Read 동작을 수행 할 수 있지만 Write 동작을 수행 할 수 없다.

  • 따라서 Master의 Downtime은 Redis Cluster의 가용성을 떨어트린다.

  • 이러한 가용성 문제를 해결을 도와주는 App이 Sentinel이다.

  • Sentinel은 Master가 죽는지 감지하고 Master가 죽었을경우 Slave 중 하나를 Master로 승격시키고 기존의 Master는 Slave로 강등시킨다.

  • Redis 관리자의 간섭없이 자동으로 이루어지기 때문에 Master의 Downtime을 최소화하여 HA(High Availabilty)를 가능하게 만든다.

  • Sentinel은 일반적으로 홀수개로 구성하여 Split-brain을 방지한다.

  • 위의 그림에서는 Sentinal을 Redis와 별도의 Node에 구성하여 이용하는 모습을 나타내고 있지만

  • Sentinel을 Redis와 동일한 Node에 구성하여 이용하여도 문제없다.

  • Sentinel 설정에는 Quorum이란 설정값이 존재한다.

  • Quorum은 특정 Redis에 장애 발생시 몇 개의 Sentinel이 특정 Redis의 장애 발생을 감지해야 장애라고 판별하는지를 결정하는 기준값이다.

  • 예를들어 Quorum 값을 2로 설정하였을 경우

  • 2개 이상의 Sentienl이 특정 Redis에 장애가 발생하였다고 판별해야 Sentinel은 해당 Redis에 대한 장애 대응을 수행한다.


HAProxy

  • Redis Master-slave 구성시 Master는 RW(Read/Write) Mode로 동작하고 Slave는 RO(ReadOnly) Mode로 동작하기 때문에 Client는 Master의 IP/Port / Slave의 IP/Port를 알고 필요에 따라 적절한 Master 또는 Slave에 붙어 동작을 수행해야 한다.

  • 따라서 Master의 장애 발생시 Master가 교체되면 그에 따라 Client의 Redis 설정도 바뀌어야한다.

  • 하지만 Master가 교체될때 마다 Redis를 이용하는 모든 Client의 설정을 바꾸는 일은 쉬운일이 아니다.

  • 이러한 문제를 해결하기 위해서 일반적으로 HAProxy를 이용한다.

  • Haproxy는 Client에게 Redis의 Master, Slave에 일정하게 접근 할 수 있는 End-point를 제공한다.

  • 위의 그림에서 Port X 는 Master에게 접근 할 수 있는 Port를 나타내고

  • Port Y는 Slave에게 접근 할 수 있는 Port를 나타낸다.

  • HAProxy는 tcp-check를 이용하여 주기적으로 각 Redis가 Master로 동작하는지 또는 Slave 동작하는지 파악하고 그에따라 동적으로 Routing Rule을 설정한다.

  • 따라서 Master가 교체되어도 Haproxy는 일정한 End-point를 Client에게 제공 할 수 있다.


Redis Cluster

  • Redis Cluster는 Redis에서 제공하는 Replication 및 Sharding 기법이다.

  • 위의 그림은 Redis Cluster 구성시 Architecture를 나타낸다.

  • Cluster를 구성하는 각 Redis는 다른 모든 Redis들과 직접 연결하여 gossip Protocol을 통해 통신한다.

  • gossip Protocol을 통해서 각 Redis는 Redis 상태 정보를 교환한다.

  • gossip Protocl은 Redis Client가 이용하는 Port번호보다 10000이 높은 번호를 Port로 이용한다.

  • Redis Client가 이용하는 기본 Port 번호는 6379를 이용하기 때문에 gossip Protocol이 이용하는 기본 Port번호는 16379가 된다.

  • Client 또한 Cluster를 구성하는 모든 Redis와 직접 연결하여 Data를 주고 받는다.

  • Redis Cluster는 Multi-master, Multi-slave 구조를 갖으며 각 Redis는 Master 또는 Slave로 동작한다.

  • 각 Master는 Hash Slot이라는 Data 저장구역을 다른 Master와 나누어 소유한다.

  • Hash Slot은 0부터 16384까지의 주소를 가지고 있다.

  • 위의 그림은 각 Master가 Hash Slot을 3개로 균등하게 분활해서 구성한 모습을 나타내고 있다.

  • Key-value Data가 이용할 Hash Slot은 Data의 Key를 Hashing한 결과값을 이용한다.

  • Hashing은 CRC16 및 Moduler 연산자를 이용하여 Data가 각 Hash Slot에 균등하게 배분되도록 한다.

  • 따라서 Data는 각 Master의 Hash Slot의 크기에 비례하여 Data를 저장하게 된다.


  • 각 Master에 할당한 Hash Slot은 Redis 관리자에 의해서 동적으로 변경이 가능하다.

  • 따라서 동적으로 Master를 추가하거나 제거하는것도 가능하다.

  • 각 Master는 다수의 Slave를 갖을 수 있다.

  • 위의 그림에서는 각 Master가 하나의 Slave를 갖고 있는 모습을 나타내고 있다.

  • Master와 Slave 사이의 Replication은 Redis Master-slave 구성과 동일하게 Async 방식으로 이루어진다.

  • 따라서 Slave도 동적으로 자유롭게 추가하거나 제거하는것이 가능하다.


  • Client는 Master, Slave 또는 Master가 가지고 있는 Hash Slot에 관계없이 Cluster에 포함된 아무 Redis에게 Data/Write 요청을 보낼 수 있다.

  • Redis는 자신이 처리 할 수 있는 요청은 직접 처리하고 Client에게 처리 결과를 전달한다.

  • 만약 자신이 처리 할 수 없는 요청이라면 해당 요청을 처리할 수 있는 Redis의 정보를 Client에게 전달한다.

  • Client는 Redis가 전달해준 다른 Redis에게 동일 요청을 다시 보내서 Data를 처리한다.

  • 예를들어 Slave Redis에게 Write 요청을 보내면 Slave Redis는 해당 요청을 처리 할 수 있는 Master Redis의 정보를 Client에게 넘겨준다.

  • 이러한 요청 Redirection으로 인해서 Client는 Redis Cluster 이용시 Redis Cluster를 지원하는 Library를 이용해야한다.


  • Master Redis가 죽을경우 죽은 Master의 Slave Redis는 gossip Protocol을 통해서 Master의 죽음을 파악한뒤 스스로 Master로 승격하여 Master를 대신한다.

  • 그 후 죽은 Master가 살아나서 동작하는 경우 스스로 Slave로 강등하여 동작한다.

  • Master와 Slave사이의 Replication은 Async 방식으로 이루어지기 때문에 Master의 죽음은 Master와 Slave 사이의 Data 정합성을 깰 수 있다.

  • 깨진 Data 정합성으로 인해서 Master와 Slave 사이의 Data 충돌이 발생하는 경우 무조건 나중에 Master가 된 Data를 기준으로 정합성을 맞춘다.


Reference


Index