Skip to main content

Raft Consensus 알고리즘 완벽 가이드 – 분산 시스템에서 리더를 뽑는 가장 쉬운 방법 (50~60자)

Published 6 min readMarkdown

# 서론 – “왜 우리는 리더 선출 문제에 고민해야 할까?”

현대의 클라우드 서비스, 데이터베이스, 캐시 시스템 등 분산 시스템은 수많은 서버가 협업해 하나의 서비스를 제공하도록 설계됩니다.

그런데 서버 중 하나가 장애가 나면 어떻게 할까요?

  • 데이터 일관성을 유지해야 한다.

  • 클라이언트 요청을 지속적으로 처리해야 한다.

  • 시스템 전체가 멈추지 않아야 한다.

이 모든 요구를 만족하려면 ‘누가 현재 시스템을 이끌어야 하는가(리더)’를 명확히 정하고, 그 리더가 장애가 발생했을 때 빠르게 새로운 리더를 선출할 메커니즘이 필요합니다.

분산 시스템에서 리더를 선출하는 대표적인 방법이 바로 Raft Consensus 알고리즘입니다. 이 글에서는 Raft가 어떻게 동작하는지, 왜 이해하기 쉬운지, 실제 프로젝트에 어떻게 적용되는지를 초보자도 쉽게 따라올 수 있도록 2,000 단어 안팎으로 정리합니다.

핵심 키워드: Raft 알고리즘, 분산 시스템, 리더 선출


# 1. Raft란 무엇인가? – “쉽게 말해 ‘팀장 뽑기’ 게임”

Raft는 2013년 Diego Ongaro와 John Ousterhout가 발표한 분산 합의(Consensus) 알고리즘입니다. 기존에 복잡하고 이해하기 어려운 Paxos와 달리, Raft는 다음 세 가지 기본 목표를 내세워 설계되었습니다.

| 목표 | 설명 |

|------|------|

| 리더 선출 | 시스템에 하나의 리더만 존재하도록 보장 |

| 로그 복제 | 리더가 클라이언트 요청을 받아 로그에 기록하고, 이를 팔로워에게 복제 |

| 안전성 보장 | 어떤 상황에서도 일관된 상태(state)를 유지 |

즉, Raft는 “팀장이 정해지면 팀장이 모든 결정을 내리고, 팀원은 팀장의 명령을 그대로 따라한다”는 단순한 메커니즘을 구현합니다. 이 단순함이 바로 ‘초보자도 이해하기 쉬운’ 이유입니다.


# 2. Raft의 기본 구성 요소

# 2.1 서버 역할 – Leader, Follower, Candidate

  1. Follower

    • 기본 상태이며, 리더의 하트비트(heartbeat) 신호를 기다립니다.

    • 일정 시간 동안 하트비트를 받지 못하면 Candidate가 됩니다.

  2. Candidate

    • 선거를 시작하고, 다른 서버에게 투표를 요청합니다.

    • 과반수(> 50 %)의 표를 얻으면 Leader가 됩니다.

  3. Leader

    • 클라이언트 요청을 받아 로그(entry) 를 생성하고, 이를 모든 Follower에게 복제합니다.

    • 일정 주기로 하트비트를 전송해 자신이 살아 있음을 알립니다.

# 2.2 로그와 상태 머신

  • 로그(entry) : 클라이언트가 보낸 명령(예: “키‑값 저장”)을 순서대로 저장한 리스트.

  • 상태 머신 : 로그를 적용해 실제 데이터베이스나 파일 시스템을 업데이트하는 역할.

Raft는 ‘로그가 동일한 순서대로 적용될 때만 상태 머신이 동일해진다’는 원칙을 따릅니다. 따라서 로그 복제와 커밋(commit) 과정이 핵심입니다.


# 3. Raft 동작 흐름 – 단계별 설명

# 3.1 초기화와 하트비트

시스템이 시작되면 모든 서버는 Follower 상태이며, 임의의 타임아웃(election timeout)을 설정합니다. Leader가 존재하면 일정 주기(heartbeat interval)마다 AppendEntries RPC를 통해 하트비트를 전송합니다.

  • 하트비트 수신 → 타임아웃 재설정 → 그대로 Follower 유지

  • 하트비트 미수신 → 타임아웃 초과 → Candidate 전환

# 3.2 선거(Election) 과정

  1. Candidate 전환

    • 타임아웃이 끝나면 현재 term(선거 번호)를 증가시키고, 자신을 후보로 선언합니다.

    • RequestVote RPC를 모든 다른 서버에 전송합니다.

  2. 투표 규칙

    • 각 서버는 아직 투표하지 않았고, 후보의 로그가 자신의 로그보다 최신이면 투표합니다.

    • 최신성 판단은 (lastLogTerm, lastLogIndex) 쌍으로 비교합니다.

  3. 과반수 확보

    • Candidate가 과반수 표를 받으면 Leader가 됩니다.

    • 새로운 Leader는 즉시 AppendEntries(하트비트)와 함께 빈 로그를 전송해 자신이 Leader임을 알립니다.

Tip: 선거는 분산 시스템에서 가장 빠르게 수렴하도록 설계되었습니다. 대부분의 경우 1~2 라운드만에 Leader가 선출됩니다.

# 3.3 로그 복제와 커밋

  1. 클라이언트 요청 → Leader가 로그에 새로운 entry 추가

  2. AppendEntries RPC → Leader가 모든 Follower에게 새 entry 전송

  3. Follower 응답 → 성공 시 matchIndex 업데이트, 실패 시 nextIndex 감소 후 재시도

  4. 커밋

    • Leader는 대다수(majority) 서버가 해당 entry를 저장했는지 확인합니다.

    • 확인되면 해당 entry를 커밋하고, 상태 머신에 적용합니다.

    • 커밋된 entry는 CommitIndex에 기록됩니다.

# 3.4 장애 복구와 로그 일관성 보장

  • Follower가 뒤처졌을 때: Leader는 prevLogIndex와 prevLogTerm을 검증해 일치하지 않으면 log truncation(잘라내기) 후 재전송합니다.

  • Leader 장애: 하트비트가 사라지면 새로운 선거가 시작되고, 기존 로그를 보존한 최신 서버가 새로운 Leader가 됩니다.

이러한 메커니즘 덕분에 ‘어떤 서버가 죽어도 일관된 상태를 유지한다’는 안전성을 확보합니다.


# 4. Raft를 실제 서비스에 적용한 사례

| 프로젝트/툴 | 적용된 Raft 모듈 | 주요 활용 |

|------------|----------------|----------|

| etcd | Core Raft 구현 | 키‑값 저장소의 메타데이터 복제 |

| Consul | HashiCorp Raft | 서비스 디스커버리와 KV 스토어 |

| RethinkDB | 자체 Raft | 샤드 복제와 장애 복구 |

| TiKV | Rust‑based Raft | 분산 트랜잭션 스토리지 |

| CockroachDB | Go‑Raft | SQL 레이어 위에 일관된 트랜잭션 제공 |

이처럼 Raft는 데이터베이스, 키‑값 스토어, 서비스 레지스트리 등 다양한 분야에서 핵심 합의 메커니즘으로 활용됩니다. 특히 Go 언어와 Rust 같은 현대 언어에 최적화된 구현체가 풍부해, 개발자는 직접 Raft를 내 서비스에 끼워 넣는 것이 비교적 쉬워졌습니다.


# 5. Raft 구현 시 흔히 마주치는 고민과 해결책

# 5.1 타임아웃 설정

  • Election timeout은 보통 150 ms ~ 300 ms 사이로 랜덤하게 설정합니다.

  • Heartbeat interval은 50 ms 이하가 일반적이며, 네트워크 상황에 맞게 조정합니다.

팁: 타임아웃을 너무 짧게 하면 불필요한 선거가 빈번히 발생하고, 너무 길게 하면 장애 복구가 지연됩니다.

# 5.2 로그 압축(Snapshot)

로그가 무한히 커지는 것을 방지하기 위해 스냅샷을 주기적으로 생성합니다.

  1. Leader가 InstallSnapshot RPC를 통해 최신 상태를 전송

  2. Follower는 스냅샷을 적용하고, 이후부터는 로그 복제만 진행

스냅샷은 디스크 I/O와 네트워크 대역폭을 절약해 대규모 클러스터에서도 효율적으로 동작합니다.

# 5.3 멤버십 변화(Cluster Reconfiguration)

Raft는 동적 멤버십을 지원합니다.

  • Joint consensus 방식을 사용해 기존 구성과 새 구성을 동시에 유지하면서 안전하게 서버를 추가/제거합니다.

  • 이 과정에서도 다수결 원칙을 유지해 일관성을 보장합니다.


# 6. Raft와 다른 합의 알고리즘 비교

| 항목 | Raft | Paxos | ZAB (ZooKeeper) |

|------|------|-------|-----------------|

| 이해 난이도 | ★★★★★ (가장 쉬움) | ★★☆☆☆ | ★★★☆☆ |

| 리더 선출 | 명시적 선거 과정 | 암묵적(프로포저) | ZAB 자체 선출 |

| 로그 복제 | 단순 AppendEntries | 복잡한 프로포저/아코머 | ZAB 프로토콜 |

| 장애 복구 | 빠른 선거 | 복구 속도 느림 | 빠른 복구 |

| 구현 난이도 | 중간 | 높음 | 중간 |

Raft는 ‘쉽게 배우고 구현할 수 있는’ 장점 덕분에 초보자부터 대규모 서비스까지 폭넓게 채택되고 있습니다.


# 7. 직접 Raft를 구현해 보는 작은 프로젝트

# 7.1 목표

  • 3대 노드(서버)로 구성된 클러스터 만들기

  • Go 언어와 etcd/raft 패키지를 활용해 Leader 선출, 로그 복제 구현

# 7.2 주요 단계

  1. 프로젝트 초기화
bash

   go mod init raft-demo

   go get go.etcd.io/etcd/raft/v3
  1. Node 구조 정의
go

   type Node struct {

       id        uint64

       raftNode  raft.Node

       storage   *raft.MemoryStorage

       transport Transport // 네트워크 전송 추상화

   }
  1. Raft 초기화
go

   cfg := &raft.Config{

       ID:              nodeID,

       ElectionTick:    10,

       HeartbeatTick:   1,

       Storage:         storage,

       MaxSizePerMsg:   1024 * 1024,

       MaxInflightMsgs: 256,

   }

   node.raftNode = raft.StartNode(cfg, peers) // peers는 초기 클러스터 멤버
  1. 메시지 처리 루프
go

   go func() {

       for {

           select {

           case rd := <-node.raftNode.Ready():

               // 로그 저장, 스냅샷 적용, 메시지 전송 등

               node.storage.Append(rd.Entries)

               node.transport.Send(rd.Messages)

               node.raftNode.Advance()

           }

       }

   }()
  1. 클라이언트 요청

    • Leader에게 Propose 호출 → 로그에 entry 추가 → 복제 진행

위와 같은 최소 구현으로 리더 선출과 로그 복제를 체험할 수 있습니다. 실제 서비스에 적용하려면 스냅샷, 영속성, 보안 등을 추가해야 하지만, 초보자 입장에서는 충분히 학습용 프로젝트가 됩니다.


# 결론 – “Raft, 이제 직접 써볼 차례입니다”

  • Raft Consensus 알고리즘은 복잡한 분산 합의를 ‘리더 선출 → 로그 복제 → 커밋’이라는 세 단계로 단순화했습니다.

  • 이해하기 쉬운 구조와 풍부한 구현체 덕분에 초보자도 금방 적용 가능합니다.

  • 실제 서비스(예: etcd, Consul, CockroachDB)에서도 핵심 역할을 수행하고 있어, 분산 시스템을 설계하거나 운영하는 모든 개발자에게 필수 지식입니다.

다음 행동 권장

  1. 위에서 소개한 간단 Raft 프로젝트를 직접 구현해 보세요.

  2. GitHub에서 etcd/raft 혹은 rust-raft 같은 오픈소스 구현을 살펴보며 코드를 분석해 보세요.

  3. 현재 운영 중인 서비스에 Raft 기반 키‑값 스토어(예: etcd)를 도입해 고가용성을 검증해 보세요.

분산 시스템의 핵심은 ‘일관성과 가용성을 동시에 보장하는 메커니즘’에 있습니다. Raft는 그 메커니즘을 가장 직관적으로 제공하므로, 이제 여러분 차례입니다. Raft를 직접 다뤄보고, 여러분만의 견고한 분산 서비스를 구축해 보세요!


관련 링크: Raft Consensus in 2000 words (Reddit)

SEO 키워드: Raft 알고리즘, 분산 시스템, 리더 선출.

No comments yet. Be the first to comment.

More from this blog