쿼럼은 단순히 살아 있는 노드의 개수가 아니라, 서로 충돌할 수 있는 결정 집합이 공통 참여자를 갖도록 만드는 규칙입니다. 그 공통 참여자가 이전 기록을 내구적으로 기억하고 새 리더가 이를 계승해야 안전성이 생기며, 통신 가능한 수가 부족하면 안전성을 지키기 위해 진행을 멈출 수 있습니다. 이 노트는 복제 사본 수, 장애 모델, 장애 영역 배치, 강제 복구를 한 계산으로 뭉치지 않고 각각의 계약으로 분리합니다.
복제 사본과 확정 쓰기의 구분
A가 x=1을 일부 replica에 보내고 고립된 뒤 B가 새 리더라고 주장하며 x=2를 받는다고 합시다. 복제는 데이터를 여러 곳에 보관하는 책임이고 합의는 지연·장애 속에서 어떤 결정과 순서를 보존할지 정하는 책임입니다. 사본 수만 늘리면 두 리더의 충돌이 자동 해결되는 것은 아닙니다.
Raft·Paxos 같은 합의는 정해진 장애 모델에서 같은 로그 위치에 서로 다른 값을 확정하지 않도록 약속·투표·로그 규칙을 사용합니다. 합의 로그에 같은 사용자 요청이 두 번 들어가는 문제나 외부 결제·메일의 중복은 별도 멱등 경계입니다.
과반 교집합과 내구적 기록 계승
고정 N개 투표자의 과반은 floor(N/2)+1입니다. 두 과반은 적어도 한 노드를 공유합니다. 그러나 교집합 노드가 이전 투표·수락 로그를 재시작 때 잊으면 그 공유만으로 충돌을 막지 못합니다. 응답 전에 필요한 약속·로그를 내구화하고 새 리더가 이전 확정을 이어받는 규칙이 필요합니다.
| 투표자 수 | 과반 | 남은 노드가 통신·저장 가능할 때 허용 손실 |
|---|---|---|
| 3 | 2 | 1 |
| 4 | 3 | 1 |
| 5 | 3 | 2 |
프로세스가 살아 있다는 것과 쿼럼에 참여할 수 있다는 것은 다릅니다. 디스크 지연·일방향 네트워크·스케줄 정지가 있으면 ping이 성공해도 필요한 응답을 제때 내지 못할 수 있습니다. node 수 증가마다 장애 허용 수가 하나씩 늘지도 않습니다.
그림을 글로 읽기
- 과반 Q1 = A,B
- 과반 Q2 = B,C
- 공통 참여자 B: 이전 투표·수락을 기억
- 과반 Q1 = A,B → 공통 참여자 B: 포함
- 과반 Q2 = B,C → 공통 참여자 B: 포함
Follower 손실과 리더 고립의 복구 경로
상태 trace를 두 갈래로 적어 보면 차이가 선명합니다. A가 leader이고 B,C가 follower일 때 C만 사라지면 A-B가 과반을 유지해 새 로그를 확정할 수 있습니다. 반대로 A만 고립되면 A는 로컬에서 leader처럼 보일 수 있지만 B-C 쪽의 새 term과 과반 확인 없이는 확정할 수 없습니다. 이때 A의 로컬 read는 최신 확정 상태가 아닐 수 있으므로 read 계약에 선형화·stale 표시를 명시합니다.
A 리더와 B·C에서 C만 사라지고 A·B가 정상 통신하면 과반으로 계속 진행할 수 있습니다. A가 고립되고 B·C가 연결되면 B·C 쪽의 선거·새 권위 확인이 필요합니다. A는 새 term을 아직 몰라 자신을 리더라고 생각할 수 있어도 과반 없이 새 쓰기를 확정해서는 안 됩니다.
옛 A가 로컬 읽기를 반환하면 새 리더의 완료된 쓰기보다 낡을 수 있습니다. 선형화 읽기에는 현재 권위·안전 읽기 위치·로컬 apply 확인이 필요하고, stale read는 별도의 표시·API 계약으로만 허용합니다. 리더를 자처하는 프로세스가 잠깐 둘이라는 것과 서로 다른 확정값이 둘 생겼다는 것은 다릅니다.
Crash 모델과 Byzantine 모델의 장애 가정
일반 Raft·Paxos의 crash/recovery 모델은 참여자가 프로토콜을 지키지만 중단·복구·메시지 유실·지연이 생기는 상황을 다룹니다. 참여자가 서로 다른 상대에게 모순된 거짓 정보를 보내는 Byzantine 행동을 같은 알고리즘이 자동 견딘다고 말하지 않습니다.
Byzantine 프로토콜의 필요 노드 수·쿼럼·서명·동기성 가정은 알고리즘별로 다릅니다. 흔한 BFT의 3f+1 같은 수치를 모든 모델에 보편 적용하지 않습니다. 서명은 누가 메시지를 보냈는지 확인할 수 있어도 그 주장의 진실성을 보장하지 않습니다. 내부 신뢰 모델에 맞는 알고리즘과 자격·운영 통제가 필요합니다.
장애 영역별 생존 용량과 지연 예산
선택 전에 노드 수 → 장애 영역별 동시 손실 → 남은 통신·저장 가능 투표자 수 → 과반 충족 여부 → 예상 왕복·commit 지연을 표로 계산합니다. 노드 수를 늘렸어도 같은 rack에 몰려 있으면 생존 용량은 늘지 않습니다. 반대로 지역을 나누면 공통 장애에는 유리하지만 정상 경로의 지연 예산을 소비하므로 안전성만 보고 배치를 결정하지 않습니다.
5개 투표자 중 A·B·C가 한 랙에 몰려 있으면, 그 랙 하나가 끊길 때 살아 있는 D·E만 남아 과반 3을 채우지 못합니다. 배치표에 rack·host·전원·zone별 동시 손실을 표시한 뒤, 각 장애 뒤 실제로 통신하고 저장할 수 있는 투표자 수가 3 이상인지 계산합니다. 여러 지역에 분산하면 장애 독립성을 높일 수 있지만, 지역 사이 WAN 왕복과 디스크 응답 시간이 commit 지연에 추가됩니다.
안전성은 서로 다른 값을 같은 로그 위치에 확정하지 않는 성질이고, 진행성은 필요한 조건이 갖춰졌을 때 새 결정을 계속 만들 수 있는 성질로 나누어 봅니다. 네트워크 지연이나 선거 경쟁이 길어지면 충돌 확정은 막아도 결정을 못 할 수 있으므로, 안정된 리더·통신·저장 조건과 timeout·backoff가 모두 필요합니다. 모든 노드의 응답을 기다리면 한 노드 장애에도 멈출 수 있지만, 과반을 잃은 한 노드가 혼자 확정하는 것은 정상 합의가 아닙니다.
강제 복구와 기존 기록 손실 수용 절차
3개 중 둘을 영구 잃은 뒤 생존 노드의 구성만 1개로 바꾸는 것은 정상적인 쿼럼 승인 구성 변경이 아닙니다. 생존 로그·백업·클라이언트 성공 기록·외부 원장을 대조해 어떤 확정이 빠졌을 수 있는지 분류하고 새 권위·허용 손실을 승인해야 합니다.
옛 클러스터가 돌아와 쓰지 못하게 network·자격·cluster generation·저장소 fencing을 차단합니다. 최신처럼 보이는 한 로그를 무조건 전체 정답으로 선언하지 않습니다. 불확정 요청과 이미 외부에 준 성공을 대사·보정하고 사용자에게 결과를 명확히 합니다.
테스트는 follower 손실·리더 고립·디스크 지연·비대칭 통신·과반 영구 손실을 분리합니다. 현재 작업에서는 합의 클러스터의 장애·강제 복구를 실행하지 않았습니다. 본문은 프로토콜 가정과 운영 보장 범위의 설명입니다.