데이터 중심 애플리케이션 설계의 '복제' 챕터를 읽으면서 정족수에 대해 설명하고 있기에 cassandra에서는 어떻게 이를 구현하는지 알아보도록 하겠습니다.
w+r > n 이면 읽을 때 최신 값을 얻을 것으로 기대한다. (w개의노드에서 성공해야 쓰기 확정, 모든 읽기는 최소한 r개의 노드에 질의, n개의 복제 서버)
최소한 r개의 노드 중 하나에서 최신 값을 읽을 수 있기 때문.
보통 n은 홀수개로 하고, w = r = (n+1)/2(반올림)로 설정한다. 이는 n/2 노드 장애까지 허용해도 w + r > n 이 보장되기 때문.
r,w를 정족수 읽기와 쓰기라 부른다.
만약, 쓰기가 적고 읽기가 많은 작업 부하는 w=n, r=1로 설정하면 좋다. 이렇게되면 노드 하나가 고장나면 모든 DB 쓰기가 실패한다는 단점이 있다.
정족수 조건이 w+r > n 이면 다음과 같이 사용 불가능한 노드를 용인한다.
- w < n 이면 하나를 사용할 수 없어도 여전히 쓰기 가능
- r < n 이면 하나를 사용할 수 없어도 여전히 읽기 가능
- n = 3, w = 2, r = 2이면 사용 불가능한 노드 하나를 용인
- n = 5, w = 3, r = 3이면 사용 불가능한 노드 둘 용인.
- 일반적으로 읽기와 쓰기는 항상 모든 n개 복제 서버에 병렬로 전송. 파라미터 w,r은 얼마나 많은 노드를 기다릴지 결정한다. 즉, 읽기나 쓰기가 성공했다고 간주하려면 n개의 노드 중 몇 개의 노드에서 성공을 확인해야 하는지를 나타냄.
Cassandra에서는 Consistency Level을 설치 시에도 입맛에 맞게 설정가능합니다. Read Consistency Level, Write Consistency Level로 설정할 수 있으며 두 값 모두 기본은 ONE입니다.
cqlsh -u ${USER_NAME} -p ${PASSWORD}
cqlsh> CONSISTENCY;
위 명령어로 현재 사용중인 Cassandra 클러스터의 Consistency Level을 볼 수 있습니다.
아무 생각 없이 ONE으로 설정하면 Production Level에서 사용했을 때 원하는 상황이 연출되지 않을 수 있습니다. 예를 들면, Read Repair를 기대했지만 전혀 되고 있지 않아 정합성이 깨지는 이슈가 발생할 수 있지요.. 실제로 저는 같은 상황이 연출되었기도 합니다.
Cassandra 4.0 공식 문서에서 다음과 같이 Read Consistency Level을 설명하고 있습니다.
Read Repair based on Read Consistency Level
ONE | Read repair is not performed as the data from the first direct read request satisfies the consistency level ONE. No digest read requests are involved for finding mismatches in data. |
TWO | Read repair is performed if inconsistencies in data are found as determined by the direct and digest read requests. |
THREE | Read repair is performed if inconsistencies in data are found as determined by the direct and digest read requests. |
LOCAL_ONE | Read repair is not performed as the data from the direct read request from the closest replica satisfies the consistency level LOCAL_ONE.No digest read requests are involved for finding mismatches in data. |
LOCAL_QUORUM | Read repair is performed if inconsistencies in data are found as determined by the direct and digest read requests. |
QUORUM | Read repair is performed if inconsistencies in data are found as determined by the direct and digest read requests. |
여기서 중요한 점은 Read Repair는 ONE consistency level인 경우 수행되지 않는다는 점입니다. 당연한 예상할 수 있겠지만 카산드라를 설치 하면서 Consistency Level을 따로 조정해주지 않았다면 왜 Read Repair가 수행되지 않나.. 살펴보는 상황이 벌어지고 결국 C.L에서 답을 찾게됩니다.
물론, C.L이 ONE인 경우 Read, Write 속도가 매우 빨라지겠지만(한 노드에만 기록되거나 읽기가 성공하면 성공한 것이니..) 성능의 이점을 가지는 대신 데이터 불일치가 노드간 발생했을 경우 Read Repair의 동작을 기대하기는 힘들 것입니다.
Hinted Handoff
만약, replication factor가 3이고 Consistency Level이 LOCAL_QUORUM인 경우의 클러스터라고 생각해봅시다.
write시 2개 노드에서 write이 성공하면 성공응답이 반환됩니다. 이때 3개의 replica를 두어야 하는데, 한 노드에서 장애가 난 상황을 생각해봅시다. 이때는 1개의 노드에서 replication 저장에 실패했지만, 성공이 응답으로 반환될 것입니다. 이럴 때 Cassandra는 Hint라는 곳에 실패한 내역을 기록하는 작업을 수행하게됩니다.
Hint는 쓰기 작업 중에 적용되는 데이터 복구 기술입니다. Replica Node가 오류로 인해 mutation을 허용할 수 없는 경우, 복제본에 쓰기를 시도하는 coordinatior node는 사용할 수 없는 복제본에 나중에 적용하기 위한 일종으로 로컬 파일 시스템에 hint에 저장합니다. 노드가 다시 정상으로 돌아오면, coordinator node는 hint를 replay해서 놓친 작업들을 처리하게 되는 것입다. (3h의 제한이 있습니다.) 물론 anti-entropy repair처럼 최종적 일관성을 보장하지는 않습니다. 이건 단지 inconsistency를 줄여나가려는 카산드라 클러스터의 노력이라고 보면 되겠지요.
Cassandra 클러스터를 운영하면서 든 생각은 기존 Master-slave 구조의 RDB에서 Masterless한 NoSQL Database를 운영하니 여러가지 고려해야할 사항이 많은 것 같습니다. 그냥 되겠지~라는 생각보다는 하나하나 따져보고 설치했어야 하는게 맞는것 같다고도 생각할 때도 생깁니다. 저또한 Cassandra 운영경험이 1년 미만이기에(약 1년?) 잘못 생각한 점도 많을 수 있고 새로 알게되는 것도 많은 것 같습니다. 그래도 Cassandra를 운영하고 살펴보면서 얻는 지식들이 많아 재미있긴 합니다. 다음번엔 어떻게 Cassandra Operator를 통해 Cassandra Cluster를 k8s에 설치하고, statefulset을 통한 cassandra cluster 설치 시와 어떻게 다른지 살펴보겠습니다.
출처
데이터 중심 애플리케이션 설계 도서
https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html
https://cassandra.apache.org/doc/4.1/cassandra/operating/hints.html#hinted-handoff
'DB' 카테고리의 다른 글
Cassandra Operator 심화 (0) | 2023.02.26 |
---|---|
Cassandra Operator (0) | 2022.11.24 |
Cassandra 기본 (0) | 2022.09.14 |