yoongrammer

Raft Consensus Algorithm 알아보기 본문

분산컴퓨팅

Raft Consensus Algorithm 알아보기

yoongrammer 2021. 1. 20. 13:42
728x90

목차

    Raft Consensus Algorithm 알아보기


    Raft는 이해하기 쉽도록 설계된 분산 합의 알고리즘입니다.

    여러 서버들 중 일부 서버에 장애가 발생하더라도 기능을 유지하도록 하는 내결함성을 가지고 있습니다.

    분산 합의(Distributed Consensus)란?


    하나의 클라이언트와 서버가 있고 클라이언트가 서버에게 데이터를 전달한다고 가정해보겠습니다. 서버는 하나의 노드로 이루어져 있기 때문에 합의가 이루어지는 건 아주 쉬운 문제입니다.

    여기서 합의란 클라이언트와 서버가 동일한 데이터를 공유하는 상태(동기화)가 되는 것을 의미합니다.

    만일 위 그림처럼 여러 노드로 이루어진 분산 서버에서 합의를 할 때 발생하는 문제를 distributed consensus problem이라고 합니다.

    Raft 작동방식


    Raft상에서 서버 노드는 세 가지 상태 중 하나를 가지게 됩니다.

    • Follower state - leader로부터 AppendEntry메시지를 받아 처리하는 상태입니다. 일정 시간이 이상 AppendEntry 메시지를 받지 못하면 상태를 cadidate로 변경합니다.
    • Candidate state - leader로 선출될 수 있는 후보군으로 Candidate 노드는 투표 요청 메시지(Vote request)를 다른 노드에 보내서 과반수 이상의 노드들로부터 투표를 받게 되면 새로운 리더가 됩니다.
    • Leader state - leader로 선출된 상태, 변경 내역은 leader를 통해서만 follower에게 전달하여 반영합니다. 어느 시점에서든 최대 하나의 리더만 있을 수 있습니다.
    • 아래 그림은 서버 노드의 상태 전환 flow입니다.

    Term


    Term은 Leader 선출 시에 할당되는 1씩 증가하는 Sequence번호로써 Leader에 ID역할을 합니다.

    Term은 Leader가 변경 될 때까지 유지되고 서버 간의 통신 중에 전달됩니다.

    Term은 리더 선출(leader election) 때 투표의 중복을 피하기 위해 사용됩니다.

     

    Term은 다음과 같은 작업을 수행합니다.

    • Term이 다른 서버의 term보다 작은 경우 서버는 term을 업데이트합니다.
    • Candidate 또는 Leader의 term이 다른 노드보다 작다면 Follower로 됩니다.
    • 오래된 term으로 요청이 오면 해당 요청은 거부됩니다.

    프로토콜


    Raft는 두 가지 유형의 RPC 프로토콜을 사용합니다.

    • RequestVotes - Candidate 노드에 의해 전달되고 선거기간 동안 투표를 얻기 위해 사용됩니다.
    • AppendEntries - Leader 노드에 의해 전달되고 로그 항목을 복제하기 위해 사용되거나 하트비트 메커니즘으로도 사용됩니다. (하트비트 메커니즘으로 사용될 땐 빈 AppendEntries를 사용합니다.)
    728x90

    리더 선출(leader election)


    리더 선출 과정은 다음과 같습니다.

    1. 모든 노드는 follower 상태에서 시작합니다. election timeout 후 follower가 candidate가 되어 새로운 선거 기간(Term)을 시작합니다.
      • election timeout - 팔로워가 후보자가 될 때까지 기다리는 시간입니다. (150ms~ 300ms사이로 무작위로 지정됨)
    2. Candidate 노드는 자신에게 투표하고 RequestVotes RPC를 follower에게 보냅니다.
    3. Follower가 현재 term내에 투표한 적이 없다면 곧바로 투표 요청을 Candidate에게 응답(Vote)을 합니다.
      • 모든 노드는 term당 한번의 투표만 할 수 있습니다.
      • 응답을 한 Follower는 election timeout을 초기화합니다.
    4. 과반수 이상의 투표를 받은 Candidate는 Leader가 됩니다.

    리더 선출 후, Leader는 Follower에게 AppendEntries 메시지를 보내기 시작합니다.

    이러한 메시지는 Heartbeat timeout 에 지정된 간격으로 전송됩니다.

    Follower는 election timeout을 초기화하고 각 AppendEntries 메시지에 응답합니다.

    이 선거 기간(Term)은 Follower가 Heartbeat 수신을 중단하고 Candidate가 될 때까지 계속됩니다.

     

    리더 선출 과정에는 여러 가지 상황이 있을 수 있습니다.

    re-election 상황


    재 선거 과정은 다음과 같습니다.

    1. Leader 노드가 죽어 더 이상 AppendEntries메시지 보내지 못합니다. election timeout 후 Follower가 Candidate가 되어 새로운 선거 기간(Term)을 시작합니다.
    2. Candidate 노드는 자신에게 투표하고 RequestVotes RPC를 Follower에게 보냅니다.
    3. Follower가 현재 term내에 투표한 적이 없다면 곧바로 투표 요청을 Candidate에게 응답(Vote)을 합니다.
    4. 과반수 이상의 투표를 받은 candidate는 leader가 됩니다.

    Term 당 하나의 Leader만 선출될 수 있습니다.

    두 노드가 동시에 Candidate가 되는 상황


    두 노드가 동시에 Candidate가 되는 경우 다음과 같은 과정을 거칩니다.

    1. election timeout 후 동시에 두 개의 Follower가 Candidate가 되어 새로운 선거 기간(Term)을 시작합니다
    2. Candidate 노드 각각은 자신에게 투표하고 RequestVotes RPC를 각 노드에 보냅니다.
    3. Candidate 노드 각각은 다른 하나보다 먼저 단일 Follower 노드에 도달합니다.
    4. Follower가 현재 term내에 투표한 적이 없다면 곧바로 투표 요청을 Candidate에게 응답(Vote)을 합니다.
      • 노드는 term 당 한 번만 투표(Vote) 할 수 있습니다.
    5. 과반수를 얻지 못해 Leader를 선출하지 못했다면 election timeout 후 다시 새로운 선거 기간(Term)을 시작합니다.
    6. 이번에는 하나의 노드만 Candidate가 되어 투표를 진행합니다.
    7. 이전 선거에서 Candidate였던 노드 D는 더 높은 Term의 RequestVotes 메시지를 받았기 때문에 Follower로 상태를 변경하고 Candidate에게 응답(Vote)을 합니다.
    8. 과반수 이상의 투표를 받은 candidate는 leader가 됩니다.

    Leader election은 하나의 Leader를 선출할 때까지 1~4를 계속 반복하게 됩니다.

    로그 복제(log replication)


    이제 시스템에 대한 모든 변경 사항이 Leader를 통하게 됩니다.

    각 변경 사항은 노드의 로그 엔트리(Log Entries)에 추가되고 다른 노드(Follower)에 복제됩니다.

    이는 AppendEntry 메시지를 사용하여 수행됩니다.

    Leader는 Heartbeat timeout 주기마다 한 번씩 AppendEntries 메시지를 Follower에게 전달합니다.

     

    일반적으로 로그 엔트리는 다음 세 가지 정보가 포함됩니다.

    • Term - Leader 선출 시에 할당되는 1씩 증가하는 Sequence 번호
    • Index - Log가 저장될 때마다 1씩 증가하는 Sequence 번호 (인덱스는 1부터 시작함)
    • Data

    로그 복제과정은 다음과 같습니다.

    1. 먼저 클라이언트가 Leader에게 변경 사항을 보냅니다.
    2. 변경 사항은 Leader의 Log Entry에 저장됩니다.
    3. Leader는 다음 heartbeat에 log를 AppendEntry 메시지 형태로 Follower에게 전달합니다.
    4. AppendEntry메시지를 받은 Follower는 새로운 Log entry를 저장하고 AppendEntryResponse메시지로 성공 응답을 보냅니다.
    5. 과반수 응답을 받았다면 Leader는 자신의 entry를 commit 하고 Client에게 응답 메시지를 보냅니다.
    6. 그리고 Follower들에게도 변경 사항이 commit 되었음을 알리고 알림을 받은 Follower들은 커밋을 합니다.

     

    참고:

    https://raft.github.io/

    www.geeksforgeeks.org/raft-consensus-algorithm/

    thesecretlivesofdata.com/raft/

    728x90

    '분산컴퓨팅' 카테고리의 다른 글

    JSON 알아보기  (0) 2020.12.28
    gRPC 란?  (0) 2020.11.11
    RPC (Remote Procedure Calls) 란?  (0) 2020.11.10
    Protocol Buffer 란?  (0) 2020.11.09
    Comments