Raft: 리더·임기·로그가 합의를 구성하는 방식
Raft는 복제된 명령 로그를 여러 노드가 일관되게 유지하도록 하는 합의 알고리즘이다. 리더 선출, 로그 복제, 안전성이라는 문제를 분리해 이해하기 쉽게 구성한다. 일반적인 모델은 노드 중단과 메시지 지연을 고려하며 악의적 노드의 임의 행동까지 처리하는 비잔틴 합의는 아니다.
Raft의 안전성은 다수 복제와 함께 임기·로그 최신성·지속 저장 규칙에 의존한다.
임기가 오래된 권한을 구별한다
노드는 팔로워, 후보, 리더 역할을 갖는다. 리더의 소식을 일정 시간 듣지 못하면 후보가 되어 임기를 늘리고 투표를 요청한다. 노드는 한 임기에 최대 한 후보에게 투표하며, 다수를 얻은 후보가 리더가 된다. 더 높은 임기를 알게 된 노드는 이전 권한을 내려놓는다.
타임아웃을 무작위로 두면 후보들이 동시에 시작해 표가 갈리는 빈도를 줄인다. 그러나 타임아웃만으로 안전성이 생기는 것은 아니다. 투표를 줄 때 후보의 로그가 충분히 최신인지 확인하여 이미 확정된 명령을 잃는 선출을 막는다.
로그를 복제한 뒤 커밋한다
클라이언트 명령을 받은 리더는 자신의 로그에 기록하고 팔로워에 AppendEntries를 보낸다. 이전 로그 위치와 임기가 맞는지 확인해 공통 접두사를 유지하고, 충돌하는 미확정 항목은 리더의 로그에 맞춰 수정한다.
Five-node cluster: A is leader.
A appends entry (index 7, term 4, command X).
B and C durably acknowledge that entry.
A+B+C form a majority of 3.
A may commit the current-term entry and apply command X.
D and E may catch up later.
현재 임기의 항목을 다수에 복제하여 커밋하면 그 이전 로그도 함께 확정된다. 이전 임기 항목을 단순히 사본 수만 보고 새로 커밋하는 규칙은 안전하지 않다. 커밋 조건에서 임기가 등장하는 이유를 놓치면 잘못된 구현이 된다.
새 리더도 확정된 역사를 보존한다
다수 집합끼리는 적어도 하나가 겹친다. 투표의 로그 최신성 규칙과 로그 접두사 조건이 결합되어 새 리더가 확정된 기록을 보존하도록 한다. 다수 교집합만 있다고 모든 합의 프로토콜이 자동으로 안전한 것은 아니다.
고정된 5노드에서 보통 3노드가 정상 통신하면 진행할 수 있다. 더 적으면 새 명령을 확정하지 못할 수 있지만 안전성을 포기해 두 갈래로 커밋하면 안 된다. 멤버십 변경은 별도 절차로 다수의 의미가 갑자기 바뀌지 않도록 처리한다.
임기, 투표 대상, 로그의 중요한 상태는 중단 후에도 보존되어야 한다. 재시작한 노드가 같은 임기에 다시 투표하면 안전성 근거가 깨진다. 스냅샷과 로그 압축은 긴 기록을 관리하지만 확정된 상태의 의미를 유지해야 한다.
리더라는 이유만으로 오래된 읽기를 안전하게 반환할 수 있는 것은 아니다. 분리된 이전 리더가 최신 권한을 확인하는 읽기 절차도 필요하다. Raft는 명령 순서의 합의를 제공하며 클라이언트 재시도의 중복 효과나 외부 부수 효과는 상태 기계와 서비스 API에서 추가로 다뤄야 한다.