ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 분산 시스템의 재앙, Split Brain: 원인 분석부터 글로벌 기업의 대응 전략까지
    Computer Science/Software Engineering 2026. 1. 22. 18:30

    오늘은 고가용성(HA, High Availability) 시스템을 설계하는 엔지니어라면 반드시 정복해야 할 숙제, Split Brain(스플릿 브레인) 현상을 심층적으로 다루어 보겠습니다.

    단순히 "서버가 두 개가 된다"는 수준을 넘어, 왜 이 현상이 데이터 정합성을 파괴하는지, 그리고 글로벌 기업들은 어떤 엔지니어링 기법으로 이를 방어하고 있는지 3,000자 분량의 가이드로 정리했습니다.


    1. Split Brain: 왜 분산 시스템의 '악몽'인가?

    1.1 개념 정의

    분산 시스템에서 Split Brain은 네트워크 단절(Network Partition)로 인해 클러스터가 두 개 이상의 독립적인 그룹으로 쪼개지고, 각 그룹이 서로의 존재를 알지 못한 채 스스로를 Master(Leader)로 승격시키는 현상을 말합니다.

    1.2 CAP 정리와 Partition Tolerance

    분산 시스템의 근간인 CAP 정리에 따르면, 네트워크 분절(P)이 발생했을 때 시스템은 일관성(C)과 가용성(A) 중 하나를 선택해야 합니다.
    Split Brain은 가용성을 억지로 유지하려다 일관성이 완전히 깨져버리는 시나리오입니다. 두 개의 Master가 각각 다른 쓰기 요청을 수락하면, 네트워크가 복구된 후 데이터는 복구 불가능한 '뇌 분리' 상태에 빠지게 됩니다.


    2. 글로벌 사례 분석: GitHub의 2018년 24시간 서비스 중단

    Split Brain이 실제 비즈니스에 어떤 타격을 주는지 보여주는 가장 유명한 사례는 2018년 10월 발생한 GitHub의 데이터베이스 장애입니다.

    🚩 장애 전개 (Timeline)

    1. 발단: US 동부와 US 서부 데이터센터 간의 광케이블 문제로 약 43초간 네트워크가 단절되었습니다.
    2. 현상: GitHub이 사용하는 MySQL HA 솔루션인 Orchestrator가 서부 노드와 통신이 끊기자, 동부 노드를 새로운 Master로 승격시켰습니다.
    3. 문제: 하지만 서부 노드(기존 Master)는 여전히 살아있었고, 일부 애플리케이션 서버는 여전히 서부 노드에 쓰기 요청을 보내고 있었습니다.
    4. 결과: 양쪽 데이터센터에 서로 다른 데이터가 쌓이는 데이터 정합성 오류가 발생했고, GitHub은 이를 수동으로 대조하여 복구하느라 24시간 넘게 서비스 장애를 겪었습니다.

    Key Insight: "Failover(장애 조치)는 빠를수록 좋지만, '정확하지 않은' Failover는 안 하느니만 못하다."


    3. 해결을 위한 엔지니어링 메커니즘

    3.1 분산 합의 알고리즘 (Raft & Paxos)

    현대 분산 시스템(etcd, Kubernetes, Consul 등)은 Raft 알고리즘을 통해 Split Brain을 방어합니다. 핵심은 Quorum(의사정족수)입니다.

    • 공식: $N/2 + 1$ (전체 노드의 과반수 동의 필요)
    • 노드가 3대라면, 최소 2대의 동의를 얻어야 Leader가 됩니다. 네트워크가 1:2로 쪼개지면 1대인 그룹은 절대 Leader가 될 수 없으므로 쓰기 작업을 중단합니다.

    3.2 I/O Fencing: "상대방의 손발을 묶어라"

    합의만으로는 부족할 때가 있습니다. 확실한 격리를 위해 Fencing(울타리 치기) 기법을 사용합니다.

    1. STONITH (Shoot The Other Node In The Head): 네트워크 응답이 없는 노드의 전원을 원격(IPMI 등)에서 강제로 꺼버립니다.
    2. Resource Fencing: 공유 스토리지 레벨에서 특정 노드의 접근 권한을 즉시 차단합니다.

    4. 실전 코드 및 설정 가이드

    4.1 Corosync/Pacemaker를 이용한 Quorum 설정

    리눅스 클러스터링 도구인 Corosync에서 Split Brain을 방지하기 위한 핵심 설정 예시입니다.

    # /etc/corosync/corosync.conf 핵심 설정
    
    totem {
        version: 2
        cluster_name: my_cluster
        transport: udpu
    }
    
    quorum {
        # 쿼럼 방식 설정
        provider: corosync_votequorum
        # 노드 수가 2개일 때 특별 처리 (가급적 3개 이상 권장)
        two_node: 0 
        # 과반수 미달 시 서비스 중단 여부 (중요!)
        last_man_standing: 1
        # 쿼럼을 잃었을 때 동작: 'stop'으로 설정하여 데이터 오염 방지
        wait_for_all: 1
    }

    4.2 Python으로 이해하는 Quorum 로직 (Pseudo-code)

    간단한 코드로 Leader 선출 시 Quorum을 체크하는 로직을 시뮬레이션해 보겠습니다.

    import time
    
    class Node:
        def __init__(self, node_id, total_nodes):
            self.node_id = node_id
            self.total_nodes = total_nodes
            self.votes = 0
            self.is_leader = False
    
        def request_vote(self):
            """
            다른 노드들에게 투표를 요청하는 메서드
            실제 환경에서는 RPC(Remote Procedure Call)로 구현됩니다.
            """
            # 네트워크 단절 상황을 가정한 투표 획득 로직
            self.votes = self.get_network_votes() 
    
            # 쿼럼 체크: 과반수(N/2 + 1)를 넘었는가?
            quorum_size = (self.total_nodes // 2) + 1
    
            if self.votes >= quorum_size:
                self.is_leader = True
                print(f"[Node {self.node_id}] Quorum 확보 성공! Leader로 승격합니다.")
            else:
                self.is_leader = False
                print(f"[Node {self.node_id}] Quorum 확보 실패 (표수: {self.votes}/{quorum_size}). Standby 유지.")
    
        def get_network_votes(self):
            # 네트워크 상황에 따라 연결 가능한 노드 수 반환
            pass
    
    # 3개의 노드 중 1개만 연결된 상황 시뮬레이션
    node_1 = Node(node_id=1, total_nodes=3)
    node_1.votes = 1 # 자신만 연결됨
    node_1.request_vote() # 결과: Standby 유지

    5. 엔지니어를 위한 Split Brain 방어 설계 원칙 ✅

    단순히 "서버를 여러 대 둔다"는 것만으로는 부족합니다. 실제 운영 환경에서 Split Brain을 원천 차단하거나 피해를 최소화하기 위한 3가지 핵심 설계 원칙을 제안합니다.

    5.1 홀수 노드 구성과 Quorum 알고리즘의 수학적 근거

    분산 시스템에서 노드 수를 홀수로 구성하는 것은 선택이 아닌 필수입니다.

    • 2개 노드 구성 시: 네트워크가 1:1로 단절되면 양쪽 모두 과반수(2/2=1)를 점유할 수 없어 전체 서비스가 중단되거나, 혹은 양쪽 모두 Master가 되는 Split Brain이 발생하기 쉽습니다.
    • 3개 노드 구성 시: 1:2로 단절될 경우, 2대인 그룹이 과반수($3/2 + 1 = 2$)를 확보하여 서비스를 이어가고, 1대인 노드는 스스로 격리됩니다.

    5.2 "안전하게 죽기(Fail-fast)" 전략

    시스템이 스스로의 상태를 확신할 수 없을 때는 과감하게 프로세스를 종료하는 것이 데이터를 오염시키는 것보다 훨씬 낫습니다.

    • Watchdog 활용: 하드웨어 또는 소프트웨어 Watchdog을 설정하여, 클러스터 엔진(Corosync 등)이 일정 시간 응답하지 않으면 커널 패닉(Kernel Panic)을 유발해 강제로 시스템을 리부트시킵니다.
    • Self-Fencing: 노드가 쿼럼을 잃었다고 판단되는 즉시 모든 I/O를 중단하고 Read-only 모드로 전환하거나 프로세스를 Kill 하는 로직을 애플리케이션 레벨에서 구현해야 합니다.

    5.3 지연 시간(Latency)과 타임아웃의 상관관계

    글로벌 서비스에서는 네트워크 지연이 일시적으로 발생할 수 있습니다. 이때 타임아웃 설정이 너무 짧으면 빈번한 Failover로 인해 오히려 Split Brain 위험이 커집니다.

    • Heartbeat Timeout > Network Jitter: 네트워크 미세 떨림보다 하트비트 임계치를 길게 설정하되,
    • Detection Time < Data Inconsistency Time: 데이터가 꼬이기 시작하는 시간보다는 빠르게 감지해야 합니다.

    6. [Advanced] Cloud Native 시대의 Split Brain

    최근 쿠버네티스(Kubernetes) 환경에서도 etcd 클러스터의 Split Brain은 매우 중요한 이슈입니다.

    etcd의 대응 방식

    쿠버네티스의 두뇌인 etcdRaft 알고리즘을 극단적으로 활용합니다. 만약 etcd가 Split Brain 상태에 빠지면, 쿠버네티스 API 서버는 상태를 업데이트할 수 없게 되어 클러스터 전체의 컨트롤 플레인이 마비됩니다.

    실제 클라우드 환경의 예 (AWS Multi-AZ):
    가용 영역(Availability Zone) 간의 네트워크 단절이 발생했을 때, AWS는 Elastic IPRoute53의 헬스 체크를 통해 트래픽을 한쪽으로 강제 유도하지만, DB 레벨에서는 여전히 Split Brain 위험이 존재합니다. 이때는 'Cloud-native Fencing'인 AWS API를 호출하여 반대편 노드의 인스턴스를 강제로 터미네이트(Terminate)하는 방식을 사용하기도 합니다.


    7. 결론 및 인사이트: "정합성은 엔지니어의 자존심이다" 💡

    Split Brain은 분산 시스템을 다루는 엔지니어에게 피할 수 없는 숙명과도 같습니다. 우리는 '절대 끊기지 않는 네트워크'를 만들 수 없기 때문입니다.

    📌 핵심 요약 (TL;DR)

    1. 현상: 네트워크 단절로 인해 다수의 Master가 발생하여 데이터 정합성이 깨지는 현상.
    2. 원인: 물리적 네트워크 장애, 과도한 시스템 부하로 인한 하트비트 응답 지연.
    3. 해결책: * 소프트웨어: Raft/Paxos 알고리즘을 통한 Quorum(다수결) 확보.
      • 하드웨어: STONITH 등 Fencing(강제 격리) 기법 적용.
      • 설계: 반드시 홀수 노드로 구성하고, 모호할 땐 Fail-fast 할 것.

    정리
    고가용성(HA)의 목적은 서비스의 영속성이지만, 그 기반에는 데이터의 무결성이 있어야 합니다. 잘못된 Failover로 데이터가 꼬이는 것보다, 차라리 잠시 서비스를 멈추고 데이터를 보호하는 것이 더 성숙한 엔지니어링 의사결정일 수 있습니다.


    🔗 함께 보면 좋은 글

    • [SRE 관점에서 본 장애 회고(Post-mortem) 작성법]
    • [etcd와 Raft 알고리즘: 쿠버네티스는 어떻게 합의하는가?]
    • [MySQL Group Replication으로 구현하는 무결성 클러스터]

    참조 및 출처

Designed by Tistory.