Hae-Riri / today-alcohol

오늘한주 - 술 레시피 공유 커뮤니티 모바일 앱
0 stars 0 forks source link

new redis cluster #25

Open Hae-Riri opened 3 years ago

Hae-Riri commented 3 years ago

Redis Cluster 101

그래서 Redis Cluster를 통해 얻는 게 뭔데?

Redis Cluster TCP ports

Redis Cluster Data Sharding

Redis Cluster는 consistent hashing을 사용하지 않는다. 대신 다른 형태의 샤딩을 쓰는데, 모든 키가 hash slot이란은 데의 일부로 저장되는, 그런 샤딩을 쓴다.

16384개의 해시 슬롯이 있고, 주어진 키가 어느 해시 슬롯으로 들어갈지 계산하기 위해 CRC16(key) 의 결과를 16384로 나눈 나머지를 취한다.

Node A contains hash slots from 0 to 5500. Node B contains hash slots from 5501 to 11000. Node C contains hash slots from 11001 to 16383.

위처럼 모든 노드는 해시 슬럿의 일부 집합을 맡고 있다. 이를 통해 클러스터에서 노드를 쉽게 추가하거나 삭제할 수 있다. 만약에 우리가 D라는 새 노드를 추가한다고 할 때, 우리는 몇몇 해시 슬롯을 A,B,C노드에서 D노드로 옮겨야 한다. 그리고 비슷하게 A 노드를 클러스터에서 제거한다면 우리는 A에 의해 제공되던 해시 슬롯을 B와 C로 옮길 수 있다. 그러면 A노드가 비어지면서 우리는 그걸 완전히 클러스터에서 없앨 수 있다.

노드에서 노드로 해시 슬롯을 옮기는 것은 연산을 멈추지 않기 때문에 노드를 추가하거나 삭제하거나 해시 슬롯 분포 퍼센티지를 바꾸는 것은 downtime이 생기지는 않는다.

해시태그?

해시태그를 사용해서 유저는 다수의 키를 강제로 같은 해시 슬롯으로 넣을 수 있다. 기본적으로 레디스 클러스터에서는 멀티 키 명령어를 쓸 수 없다. MSET 같은 거. 근데 해시 태그를 사용하면 할 수 있다. 이건 키의 일부를 {}로 감싸는 건데, 예를 들어 {user001}.following이랑 {user001}.followers가 같은 슬롯에 저장되는 것이다. 그리고 이 여러 키가 하나의 명령어로 처리될 수 있다.

Redis Cluster master-slave model

Redis Cluster는 마스터노드의 subset이 망가졌을 때 가용성을 유지하기 위해서 master-slave model을 사용하고, 모든 해시 슬롯이 master에 있는 자기 자신 하나와 N개의 추가 복제본 (slave)를 가진다.

A,B,C 라는 클러스터 노드가 있고, B가 죽었다고 치면 우리는 5501-11000까지의 해시 슬롯을 serve할 방법이 없다. 그러나 클러스터가 생성되거나 우리가 slave 노드를 모든 마스터에 추가해준다면, 최종 클러스터는 A,B,C,A1,B1,C1으로 구성될 것이다. 이러면 B노드가 죽더라도 시스템은 지속될 수 있다. 즉, B가 죽을때 클러스터는 B1을 마스터로 승격시켜서 연산을 지속한다. 하지만 만약 B랑 B1이 동시에 죽어버리면 레디스 클러스터는 더 이상 수행할 수 없게 된다.

Redis Cluster guarantees

strong consistency를 지원하진 않는다. 다시 말해 아래 조건에서는 레디스 클러스터가 write을 잃을 수 있다. 비동기 복제본을 쓰기 때문이다. write하는 도중에 아래 상황이 발생한다고 해보자.

이건 기존에 분산 시스템을 지원하지 않는 데이터베이스를 사용할 때에 이미 겪어봤을 텐데, 그래서 결국 지속성을 향상시키기 위해 데이터베이스에서 클라이언트에 응답하기 전에 먼저 disk에 데이터를 flush하기도 했었다. 그런데 이러면 굉장히 성능이 떨어진다. 이건 레디스 클러스터에서의 동기 복제와 맞먹는다.

퍼포먼스와 consistency사이에는 균형이 생긴다.