싱글 컴퓨터로는 성능 향상에 한계가 있습니다. 만약 그 컴퓨터에 장애가 발생하면, 작동하던 서비스도 중단될 수밖에 없습니다.
이러한 문제를 해결하기 위해 복잡한 연산을 여러 컴퓨터가 나눠서 수행하고, 하나의 컴퓨터가 고장 나더라도 나머지 컴퓨터가 그 작업을 맡아서 처리할 수 있는 분산 환경(Distributed System)이 등장했습니다.
하지만 여러 컴퓨터가 하나의 시스템처럼 동작하기 위해서는, 모든 컴퓨터가 서로 어긋남 없이 하나의 상태를 공유해야 합니다. 이를 해결하기 위해 분산 환경에서 상태를 공유하는 알고리즘이 개발되었고, 이를 합의 알고리즘(Consensus Algorithm)이라고 부릅니다. 여기서 합의란 클라이언트와 서버가 동일한 데이터를 공유하는 상태(동기화)가 되는 것을 의미합니다.
합의 알고리즘은 분산 시스템에서 각 노드가 동일한 데이터 상태를 유지하도록 보장합니다. 이 과정은 다양한 네트워크 장애, 노드 오류, 메시지 지연 등과 같은 문제를 처리하면서 시스템의 일관성과 가용성을 확보하는 데 중요한 역할을 합니다. 대표적인 합의 알고리즘으로는 Paxos, Raft, Zookeeper 등이 있으며, 이들은 모두 시스템의 안정성과 신뢰성을 향상시키는 데 기여하고 있습니다.
Raft는 분산 시스템에서 합의를 형성하는 데 널리 사용되는 알고리즘으로, 특히 이해하기 쉽고 구현하기 용이하도록 설계되었습니다. Raft는 주로 분산 시스템의 일관성과 가용성을 보장하면서, 네트워크 분할 상황에서도 시스템의 복구 가능성을 높이는 것을 목표로 합니다.
Raft는 주로 세 가지 주요 구성 요소로 작동합니다:
리더 선출 (Leader Election):
로그 복제 (Log Replication):
안전성 보장 (Safety):
일관성 (Consistency): Raft는 시스템의 일관성을 보장합니다. 이는 리더가 결정한 로그가 시스템 내 모든 노드에 동일하게 반영된다는 것을 의미합니다. 시스템의 모든 노드는 항상 같은 상태를 유지하려고 하며, 리더의 로그가 커밋되면 이 상태가 전체 시스템에 퍼지게 됩니다.
가용성 (Availability): Raft는 특정 노드(리더)가 정상적으로 작동하면 클라이언트의 요청을 계속해서 처리할 수 있습니다. 하지만 네트워크 분할이나 리더의 장애 상황에서는 일시적으로 가용성이 낮아질 수 있습니다. 리더가 없는 동안에는 쓰기 요청을 처리할 수 없습니다.
분할내성 (Partition Tolerance): Raft는 네트워크 분할 상황에서도 시스템을 복구할 수 있습니다. 시스템이 분할되면 두 개의 하위 네트워크로 나뉘게 되고, 각 네트워크는 자체적인 리더를 선출하려고 시도합니다. 이 과정에서 더 많은 노드의 지지를 받은 네트워크만이 유효한 리더를 갖게 되고, 나머지 네트워크는 리더가 없는 상태로 대기합니다. 네트워크가 복구되면 시스템은 다시 정상적인 상태로 돌아갑니다.
Raft의 신뢰성을 높이기 위해서는 다음과 같은 방안이 고려될 수 있습니다:
정족수 기반의 합의: Raft는 정족수(대다수의 노드)가 로그 복제를 승인해야 합의가 이루어지도록 설계되어 있어, 시스템의 안전성을 보장합니다.
로그 일관성 보장: 리더는 로그의 일관성을 유지하기 위해 끊임없이 팔로워에게 하트비트를 전송하여, 팔로워들이 리더의 상태를 유지하도록 합니다.
장애 감지 및 복구: 노드의 상태를 주기적으로 모니터링하여 장애를 신속하게 감지하고, 새로운 리더를 빠르게 선출하여 시스템이 정상적으로 동작하도록 합니다.
Raft는 이러한 특징들을 통해 분산 시스템에서의 합의 형성에 신뢰성과 안정성을 제공합니다. 이는 특히 네트워크가 불안정하거나 장애가 발생할 가능성이 있는 환경에서 매우 유용합니다.
Raft 알고리즘에서는 분산 시스템의 모든 노드가 세 가지 상태 중 하나를 가집니다.
Term은 Raft 알고리즘에서 리더 선출 시 할당되는 일종의 일련번호로, 리더의 ID 역할을 합니다. Term은 시스템 내에서 리더의 상태와 그 유효성을 판단하는 중요한 지표로 사용됩니다.
리더의 ID 역할:
중복 투표 방지:
서버 간 통신에서의 역할:
Term 업데이트:
상태 전환:
오래된 Term에 대한 요청 거부:
이러한 기능을 통해 Raft의 Term은 분산 시스템에서 리더의 안정적인 선출과 상태 일관성을 유지하는 데 핵심적인 역할을 합니다. Term을 이용하여 시스템은 지속적으로 최신 상태를 반영하고, 분산 환경에서의 오류를 최소화합니다.
Raft 알고리즘에서 리더 선출 과정은 다음과 같이 진행됩니다:
초기 상태:
Election Timeout:
Candidate가 되는 과정:
RequestVotes
RPC를 보냅니다.투표 요청:
투표 응답:
리더가 되는 조건:
이 과정을 통해 Raft는 시스템 내의 모든 노드가 하나의 리더를 선택하고, 그 리더를 통해 일관된 상태를 유지할 수 있도록 보장합니다. 리더는 일정 주기마다 하트비트를 팔로워들에게 보내며, 리더의 상태를 지속적으로 유지합니다. 이로 인해 시스템은 높은 가용성과 신뢰성을 가지게 됩니다.
Raft 알고리즘에서 로그 복제는 분산 시스템의 모든 변경 사항이 리더를 통해 처리되고, 각 노드의 로그가 일관되도록 보장하는 중요한 과정입니다. 로그 복제는 리더가 클라이언트의 요청을 처리하고 이를 팔로워 노드에 복제함으로써 이루어집니다.
로그 엔트리는 일반적으로 다음 세 가지 정보를 포함합니다:
Term:
Index:
Data:
로그 복제 과정은 다음과 같이 진행됩니다:
클라이언트 요청:
로그 엔트리 저장:
AppendEntries 메시지 전송:
AppendEntries
메시지를 통해 자신의 로그 엔트리를 모든 팔로워에게 전달합니다.로그 엔트리 저장:
AppendEntries
메시지를 받은 팔로워는 새로운 로그 엔트리를 자신의 로그에 저장합니다.AppendEntriesResponse
메시지를 리더에게 보내, 로그 엔트리 저장 성공을 알립니다.과반수 응답:
클라이언트 응답:
팔로워에게 커밋 알림:
일관성 유지: 로그 복제는 시스템의 일관성을 유지하는 핵심 메커니즘입니다. 모든 노드가 동일한 로그를 갖도록 보장함으로써, 시스템 전체가 같은 상태를 유지할 수 있게 됩니다.
장애 복구: 리더가 실패하더라도 로그 복제를 통해 다른 팔로워들이 일관된 상태를 유지하므로, 새로운 리더가 쉽게 선출되고 시스템을 안정적으로 유지할 수 있습니다.
확장성: 로그 복제는 클러스터의 크기를 유연하게 확장할 수 있게 하며, 시스템의 처리 능력을 향상시킵니다.