RocksDB, Raft와 리전

TiDB에 대한 소개

앞에서 데이터의 격납 및 키 밸류를 설명하였다. 이번 RocksDB, Raft와 리전을 소개하겠다.

RocksDB

지속 가능한 스토리지 엔진은 데이터를 디스크에 저장한다. TiKV도 예외는 아니다. 그러나 TiKV는 디스크에 직접 데이터를 쓰지 않는다. 먼저 TiKV가 RocksDB에 데이터를 저장하고 RocksDB가 데이터 저장을 수행한다. 독립 실행형(Stand-alone) 스토리지 엔진(특히 고성능 독립 실행형 엔진)의 개발은 상당한 비용이 들기 때문이다. 다양한 최적화 처리에 다가서는 것이다.

PingCAP회사는 RocksDB가 모든 요구 사항을 충족하는 탁월한 오픈 소스 독립형 스토리지 엔진임을 발견하였다. Facebook팀이 이 엔진의 최적화에 매진하고 있는 동안, PingCAP사는 그렇게 어려움이 없이 개량이 진행되는 강력한 독립형 엔진을 즐길 수 있다는 장점도 있다. 물론, PingCAP사도 RocksDB에 대해서 약간의 코드 제공하고는 있지만, 이 프로젝트의 추가 개선이 기대하기는 힘들다. 간단히 말해 RocksDB는 독립형 키-벨류 맵으로 볼 수 있다.

Raft

이 복합 프로젝트의 첫번째로 중요한 단계는, 안정적이고 효과적인 로컬 스토리지 솔루션을 찾는 것이었다. 다음은 1대의 컴퓨터가 정지할 때 데이터의 무결성과 정확성을 어떻게 보호하는가에 대한 비교적 어려운 과제이다. 효과적인 것은 데이터를 여러 대의 컴퓨터에 복제하는 방법이다.

그렇게 되면 1대의 컴퓨터가 충돌할 경우, 다른 컴퓨터의 복제본을 사용할 수 있다. 그러나, 복제 솔루션은 유효하지 않은 복제본이 있는 상황에 대응할 수 있는 안정적이고 효과적이어야 한다. 어려울 것 같지만 Raft를 이용하면 실현할 수 있다. Raft는 Paxos보다 이해하기 쉬운 Paxos와 동등한 합의 알고리즘이다. Raft에 관심이 있으시면 Raft의 논문을 읽으시면 자세한 내용을 볼 수 있다. 이 외부 Raft 보고서는 기본적인 솔루션만을 제시하고 있으며, 이 보고서를 엄격하게 준수하면 성능이 낮아진다는 것을 지적한다. PingCAP는 Raft를 구현하기 위해 다양한 최적화를 수행하였다.

Raft는 합의 알고리즘이며, 다음과 같은 세 가지 중요한 기능이 있다.

  • 리더 선출
  • 멤버십 변경
  • 로그 복제

TiDB Raft

TiKV는 Raft를 사용하여 데이터를 복제한다. 각 데이터 변경은 Raft 로그로 기록된다. 데이터는 Raft의 로그 복제 기능을 통해 Raft 그룹의 여러 노드와 안전하고 안정적으로 동기화된다.

요약하면 독립 실행형 RocksDB를 사용하면 데이터를 디스크에 빠르게 저장할 수 있다. Raft를 사용하면 시스템 장애에 대비하여 여러 시스템에 데이터를 복제할 수 있다. 데이터는 RocksDB에 대한 것이 아니라 Raft 인터페이스를 통해 기록된다. Raft 구현 덕분에 분산형 키-밸류 시스템을 이용할 수 있게 되어, 이제는 컴퓨터의 장애에 대해 걱정할 필요가 없다.

Region

이 섹션에서는 매우 중요한 개념 “리전(지역, region)“에 대해 소개한다. 리전은 일련의 메커니즘을 이해하는데 있어서 기초가 된다. 이 개념을 고려하기 전에 Raft를 잊어 버리고 모든 데이터에 복제본이 하나만 있다는 상황을 상상해보자.

앞서 언급했듯이 TiKV는 순서가 지정된 거대한 키-벨류 맵으로 볼 수 있다. 스토리지의 수평 확장성을 얻으려면 여러 시스템에 데이터를 분산시켜야 한다.

키-벨류 시스템에는 여러 컴퓨터에 데이터를 분산시키는 두 가지 일반적인 솔루션이 있다. 하나는 해시를 만들고 해시 값을 기반으로 해당 스토리지 노드를 선택하는 솔루션이다. 다른 하나는 범위를 사용하고 직렬 키 세그먼트를 스토리지 노드에 저장하는 솔루션이다. TiKV는 두 번째 솔루션을 선택하고 전체 키 가치 공간을 여러 세그먼트로 나눈다. 각 세그먼트는 인접한 키 세트로 구성된다. 이러한 세그먼트를 당사는 ‘리전’이라고 부른다. 각 리전이 저장할 수 있는 데이터의 크기에는 상한이 있다(기본값은 64MB, 이 사이즈는 설정 가능). 각 리전은, 왼쪽이 열리고 오른쪽이 닫힌 구간(StartKey로부터 EndKey까지)에 의해 표현할 수 있다.

TiKV과 Region

지금 여기서 말하고 있는 리전은 SQL의 테이블과는 아무 관계도 없다! 지금은 SQL을 잠시 잊고 키-벨류에 집중하자.

데이터를 리전으로 분할한 후 다음과 같은 두 가지 중요한 작업을 수행한다.

  • 클러스터의 모든 노드에 데이터를 분산하고 지역을 데이터 이동의 기본 단위로 사용한다. 각 노드의 리전 수가 거의 같은지 확인해야 합니다.
  • 지역에서 Raft를 통한 복제 및 멤버십 관리.

이 두 가지 작업은 매우 중요하기 때문에 하나씩 설명한다.

첫 번째 태스크에서는 키를 기반으로 데이터를 여러 리전으로 나누고, 각 리전의 모든 데이터를 하나의 노드에 저장한다. 모든 클러스터 노드에 대한 지역의 균등 분산은 당사 시스템의 한 구성 요소가 담당한다. 그 결과, 스토리지 용량의 수평 확장성이 제공된다(새 노드가 추가될 때 시스템이 자동으로 다른 노드에서 리전을 스케줄대로 처리한다). 반면에 부하 분산도 달성된다(즉, 한 노드에 많은 데이터가 배치되고, 다른 노드에는 적게 배치되는 상황이 발생하지 않음). 동시에 상위 클라이언트가 필요한 데이터에 액세스할 수 있도록 하기 위해 다른 구성 요소(component)가 여러 노드에 걸쳐서 리전의 분산을 기록한다. 즉, 사용자는 키의 정확한 리전과 키를 통해 배치된 해당 리전의 노드를 조회할 수 있다. 이 두 가지 구성 요소는 나중에 자세히 설명한다.

두 번째 작업으로 이동하자. TiKV는 리전의 데이터를 복제한다. 즉, 하나의 리전의 데이터에는 “Replica"라는 이름의 여러 복제본이 있다. 복제본 간의 데이터 일관성을 달성하려면 Raft가 사용된다. 한 리전의 여러 복제본이 여러 개의 다른 노드에 저장되고 Raft 그룹을 구성한다. 한 복제본이 그룹의 리더 역할을 하고 다른 복제본이 팔로어가 된다. 읽기와 쓰기는 모두 리더를 통해 이루어지며 리더가 팔로어에 복제한다.

다음 그림은 리전과 Raft 그룹의 전체 이미지를 표시해주고 있다.

리전과 Raft 그룹

리전에서 데이터를 분산 및 복제할 때는 어느 정도 재해 복구 능력을 가진 분산형 키 밸류 시스템을 활용할 수 있다. 이제 사용자는 용량이나 디스크 장애로 인한 데이터 손실 문제로 고민할 필요가 없다. 이것은 훌륭하지만 완벽하지는 않다. 필요한 기능이 있다.


이번에는 RocksDB, Raft 및 Region의 개념을 설명했습니다. 다음번은 초보자를 향한 TiDB의 학습 ~스토리지편 제3회~ 에서 MVCC와 트랜잭션을 설명합니다.