Raft Consensus를 이용한 동기화 이해하기

Raft Consensus를 이용한 동기화 개요

이 글에서는 Raft 상에서 데이터가 어떻게 저장되고, 어떻게 노드(서버)간에 동기화 되는지에 대해 개념적으로 설명하려고 한다. AERGO를 위한 Raft Consensus 전반에 관한 내용은 이전 글(AERGO Private Environment를 위한 합의)을 참고하기 바란다.

Raft Consensus는 각 노드를 State machine으로 생각하고 이 노드들이 동일한 State를 가질 수 있도록 동기화하는 합의 알고리즘을 제공한다. 이를 위해 State machine 상의 변경사항을 Log로 기록하고 전체 노드가 동일한 Log를 동일한 순서로 적용 할 수 있도록 제어하는 역할을 한다.

AERGO의 각 노드는 State machine에 해당하고, 각 높이에 저장된 블록을 State로 이해하면 된다. 이러한 형태로 동작하기 위해 블록이 Raft Log에 Data로 포함되는 구조를 가진다.
Raft가 동작 하기 위해서는 하나의 가정이 필요하다.

각 노드는 거짓말을 하지 않는 정직한 노드이어야 한다. 

노드 간에 메시지로 전달되는 정보는 항상 정확한 정보이어야 한다. 다시 말하면, Raft는 Byzantine Fault Tolerant하지 않다. 예를 들어, Leader가 아닌 노드는 Leader인 것처럼 메시지를 전송해서는 안된다. 따라서 Raft는 보안이 확보되어 악의적인 노드가 Cluster에 포함될 확률이 낮은 private chain에 적합한 consensus 알고리즘이다. 그럼 이제 Raft consensus 상에서 데이터가 어떤 형태로 저장되는지 살펴보자

Raft Consensus Data 저장

Raft Consensus를 위해 저장하는 데이터는 크게 Raft Log와 블록 관련 Data로 나누어 진다. 이 데이터들은 Raft protocol을 이용해 전파되고 각 서버의 저장소에 저장된다. 블록은 Raft Log의 Data 형태로 저장된다. 저장된 블록은 Commit 과정을 거친 후 블록체인에 추가될 때에 관련 Account 정보와 Chain 연결 정보 등이 저장된다.


Fig 1. Raft에 저장되는 Log 개념도

Raft Log entry는 아래와 같은 속성을 가진다.
– Term
– Index
– Data

Term은 Leader 선출 시에 할당되는 1씩 증가하는 Sequence 번호이다. 따라서 각 Leader에 붙은 ID 역할을 한다. Index는 새로운 Log가 저장될 때마다 1씩 증가하는 Sequence 번호이다. Leader는 해당 Term의 특정 index에 하나의 log만을 생성하기 때문에 Term과 Index로 Log를 Unique하게 구분 할 수 있다.

Data는 Raft를 통해 공유되는 정보를 말하며 AERGO에서는 블록이 그 대상이 된다.

Term은 Leader가 변경 될 때까지 유지되기 때문에 동일 Term으로 Log가 생성되는 기간은 Term마다 다를 수 있다.


Fig 2. Term이 바뀌는 상황에서의 Log 상태 예제

Raft Log에는 중요한 특징이 하나 있다. Raft protocol에 의해 commit된 Log는 절대 삭제되거나 변경되지 않는다는 것이다. 즉 Leader가 변경되거나 장애 상황이 발생해도 이미 commit된 Log는 유실되거나 다른 Log에 의해 대체되지 않는다. 이 특성으로 인해 블록이 chain에 추가되는 즉시 finality가 보장되는 것이다.

Raft Protocol을 이용한 노드 간 동기화

이제 Raft protocol이 노드 간 Log를 어떻게 동기화하는지 살펴보자.

Raft가 사용하는 protocol은 복잡한 context를 유지하지 않아도 되도록 Simple하게 정의되어 있다.

핵심적인 protocol은 Leader로부터 Follower에 전송되는 두 type의 메시지로 이루어진다.

Raft Message
– AppendEntry
– Heartbeat

AppendEntry 메시지는 Leader가 Log를 Follower에 전파하고 동기화가 되어 있지 않은 경우 동기화 시점을 찾기 위해서 사용된다. Log에는 블록이 포함되어 있으므로, Log를 저장하면 블록도 함께 저장된다. 단 이 때 블록은 Log에만 저장되고 블록체인에는 연결되지 않는다.

Heartbeat 메시지는 Leader와 Follower사이에 liveness를 체크하고, commit 정보를 전달하기 위해 주기적으로 Leader에서 Follower로 전달된다. commit정보를 받은 후 commit된 Log에 저장된 블록을 실행하여 블록체인에 추가하게 된다.

AppendEntry를 이용한 동기화 과정을 살펴보자

핵심은 두 가지 이다.
– Follower에서 Leader로부터 새 Log를 받아 적용하기 위해서는 바로 전 Log까지 적용되어 있어야 한다.
– 바로 전 Log까지 저장된 상황이 아니라면 Leader에 현재 저장된 Log 상태를 힌트로 전달하여 Leader가 적절한 Log를 다시 보낼 수 있게 한다.

어떤 방식으로 동기화 point를 찾게 되는지 알아보자.

1. Leader는 새로 발생한 Log를 AppendEntry 메시지로 보낸다. AppendEntry메시지를 새로운 Log 정보와 함께 Previous Entry(새 Log entry의바로 전 Log)의 Meta정보(Term/Index)를 함께 보낸다.

2. Follower는 Previous Entry의 Meta 정보가 Log 저장소에 저장된 마지막 로그와 일치 하는지 검사한다.

3. 일치하면 새로운 Log entry를 저장하고 AppendEntryResponse 메시지로 성공응답을 보낸다.


Fig 3. 새 Log의 AppendEntry 성공 사례

4. 일치하지 않는다면 AppendEntryResponse 메시지로 실패 응답을 보내고 힌트로 저장된 마지막 Log의 Meta정보를 보낸다. 힌트에는 Previous index(Reject) 와 마지막 저장된 index(Last)를 보내주어 Leader가 다음 요청을 보낼 때 적절한 Log를 보낼 수 있게 한다.

5. Leader는 Follower의 응답이 실패한 경우, Follower가 보낸 마지막 Log 정보를 보고 적절한 Log를 새로운 AppendEntry로 보낸다.


Fig 4. 새 Log의 AppendEntry 실패 예제

Fig 4의 사례를 살펴보면 Previous Entry (2/6) Log가 Follower에 저장되어 있지 않다. 따라서 match 실패로 판단해 에러를 리턴한다. 이때 다음 요청을 위해 match 실패한 index(6)와 Follower의 마지막 log(3)을 전달한다. Leader는 hint를 이용해서 다음 AppendEntry 요청에 Log Entry (2/4)를 보내준다면 다음 요청은 성공할 것이다.

위 과정을 반복하게 되면 Leader는 Follower와 마지막으로 동기화된 Log point를 찾게 되고, 해당 Log 이후 부터는 차례대로 동기화를 수행한다.

Leader가 변경된 상황에 대한 처리

Leader가 변경된 경우 이전 Leader가 생성한 Log와 새로운 Leader가 생성한 Log가 충돌 할 수 있다. 이런 상황은 network 단절과 같은 장애로 인해 이전 Leader의 마지막 Log가 일부 노드들로 전달되지 않아 commit이 되지 않았을 때 발생할 수 있다. 


Fig 5. Leader 변경으로 Log가 대체되는 예제Fig 5의 경우를 보면 Follower노드는 이전 Leader(term1)가 생성한 로그(1/6)을 포함하고 있지만 새로운 Log(2/6)를 받으면 이전 Leader가 생성한 로그를 대체하여 저장한다.

Summary

Raft Consensus는 AppendEntry 메시지를 보내고 응답을 받는 과정을 반복하는 단순한 프로토콜로 노드간의 동기화를 실행한다. Simple하고 이해하기 쉽다는 장점은 안정적인 구현체를 개발하기 용이하다는 뜻이다. 이는 Raft의 강력한 장점이라고 볼 수 있다.

Raft를 이해함으로써 분산 환경에서의 동기화에 대한 개념을 잡고, 다른 Consensus 프로토콜들을 접할 때에도 도움이 되었으면 한다.

AERGO를 위한 Raft Consensus에 대해 더 상세히 알고 싶다면 Raft : Consensus for AERGO Private Environment 문서를 참고하도록 하자.

Raft를 더욱 쉽고 깊이 있게 이해서는 아래 글들을 읽어보면 도움이 될것이다.
Raft 동기화를 애니메이션으로 보여주는 다음 site를 참고하면 동기화 과정을 눈으로 볼수 있다.
Raft에 대한 자세한 내용은 Diego Ongaro and John Ousterhout의 slide를 참고하자

Raft : AERGO Private Environment를 위한 합의(Consensus)
Hyperledger Fabric 비교 – 1편

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다

필수 입력 사항입니다.
필수 입력 사항입니다.
유효한 이메일 주소를 입력해주세요.
You need to agree with the terms to proceed

메뉴