클라우드브레이크 — 수평적 확장이 용이한 솔라나의 상태 아키텍쳐

솔라나를 세계 최고 성능의 블록체인으로 만들어준 8가지 핵심 기술 중 하나인 클라우드브레이크에 대해 소개 드립니다

GM Chung
솔라나 한국
6 min readJul 6, 2020

--

솔라나는 세계 최고의 성능을 자랑하는 무허가형 블록체인입니다. 현재 진행 중인 솔라나의 테스트넷은 200개의 독립된 GPU 노드들로 구성되었으며, GPU를 통해 초당 50,000건의 트랜잭션을 처리하고 있습니다. 높은 성능을 달성하기 위해 여러 최적화 및 새로운 기술이 필요로 했으며, 그 결과 블록체인 개발 분야에 있어 기존에는 찾아보지 못할 수준의 네트워크 수용력을 이뤄냈습니다.

솔라나 네트워크를 가능하게 해준 8가지 주요 혁신들은 다음과 같습니다:

이번 블로그 포스트에선 수평적으로 확장하는 솔라나의 상태 아키텍쳐 클라우드브레이크(Cloudbreak)에 대해 알아보겠습니다.

개요: RAM, SSD, 그리고 스레드

샤딩(Sharding) 없이 블록체인이 확장성을 달성하고자 한다면, 연산력 확장만으론 이를 이룰 수 없습니다. 계정 추적에 사용되는 메모리는 크기와 속도 면에서 곧장 병목현상을 초래합니다. 예시는 다음과 같습니다: 많은 블록체인들이 활용하는 로컬 데이터베이스 엔진인 LevelDB는 단일 기기상에서 5,000 TPS 이상 지원할 수 없다는 것이 중론입니다. 그 이유는 가상 머신은 데이터베이스 추상화를 통해 계정 상태에 대한 동시적 읽기 및 쓰기 접근을 할 수 없기 때문입니다.

이에 대한 안일한 해결책으로 글로벌 상태를 RAM에 저장하는 것이 있습니다. 하지만, 상용 기기에 글로벌 상태를 담을 수 있을 만큼의 RAM이 있다는 가정은 비현실적입니다. 다른 옵션은 SSD를 활용하는 것입니다. SSD를 활용하면 바이트 당 비용을 30배 이상 줄일 수 있지만, RAM과 비교하면 1,000배가량 느립니다. 아래는 현재 시중에서 가장 빠른 SSD 중 하나인 삼성의 최신 SSD에 대한 데이터시트(datasheet)입니다.

일회성 트랜잭션은 2개의 계정을 읽고 1개의 계정에 쓰기를 필요로 합니다. 계정 키는 암호화된 공개키이며, 완전히 무작위적임으로 진정한 데이터 로컬리티(Locality)가 없습니다. 사용자의 지갑은 다수의 계정 주소를 지니고 있을 것이고, 각 주소의 부분들은 다른 주소들과 일말의 연관성도 가지지 않습니다. 계정 간 로컬리티는 존재하지 않기 때문에, 서로 비슷한 것들을 취급하듯이 메모리에 저장할 수 없습니다.

15,000 TPS를 최대치로 보고, 안일하게 단일 SSD를 사용하는 계정 데이터베이스에 단일 스레드를 적용한다면, 이는 최대 7,500의 TPS를 지원할 수 있을 것입니다. 현 SSD들은 32개의 동시 스레드를 지원함으로, 초당 37만 쓰기, 또는, 약 185,000 TPS를 달성할 수 있습니다.

클라우드브레이크(Cloudbreak)

솔라나의 디자인 철칙은 하드웨어가 100% 가동될 수 있도록 소프트웨어가 양보해야 한다는 것입니다.

32개 스레드 사이에서 동시에 읽기 및 쓰기가 가능한 계정 데이터베이스를 꾸리는 것은 어려운 일입니다. LevelDB와 같은 기본 오픈소스 데이터베이스가 병목현상을 겪는 이유는 블록체인 환경 상에서 위와 같은 상황에 최적화되어있지 않기 때문입니다. 위의 문제 해결에 대해 솔라나는 통상적인 데이터베이스를 쓰지 않고, 운영 체제에서 활용되는 여러 메커니즘을 사용하고 있습니다.

첫째로, 저희는 메모리 맵핑된 파일(Memory-mapped files)을 활용합니다. 메모리 맵핑된 파일이란 프로세스의 가상 주소에 바이트가 맵핑된 파일을 뜻합니다. 맵핑된 파일은 여타 메모리처럼 활동할 수 있습니다. 커널이 RAM에 캐시된 메모리를 조금 가지고 있을 수도, 없을 수도 있지만, 실제 메모리량은 RAM이 아닌 디스크 용량에 의해 제한됩니다. 읽기와 쓰기는 당연히 디스크의 성능을 따르게 됩니다.

디자인에 두 번째로 고려해야 하는 사항은 랜덤한 수행보다 순차적 수행이 훨씬 빠르다는 것입니다. 이는 SSD뿐만 아니라, 가상 메모리 스택 전체에 해당되는 사항입니다. CPU는 순차적으로 접근된 메모리를 불러오는데 뛰어나고, 운영 체제들은 순차적 페이지 장애를 잘 다룰 수 있습니다. 이런 특성을 활용하기 위해 저희는 계정 데이터 구조를 다음과 같이 대략적으로 구분합니다:

  1. 계정의 인덱스와 분기들은 RAM에 저장됩니다.
  2. 계정들은 메모리 맵핑된 파일로, 4MB까지의 크기로 저장됩니다.
  3. 각 메모리 맵은 유일하게 제안된 분기의 계정만 저장합니다.
  4. 맵은 최대한 많은 SSD들에 걸쳐 랜덤하게 배포됩니다.
  5. Copy-on-write 시멘틱스(Semantics)가 사용됩니다.
  6. 쓰기는 같은 분기의 랜덤 메모리 맵에 추가됩니다.
  7. 각 쓰기가 완료된 후 인덱스는 업데이트됩니다.

계정 업데이트는 Copy-on-write이고 랜덤한 SSD에 추가되기 때문에, 솔라나는 순차적 쓰기에서 오는 성능 혜택과, 수많은 SSD에 걸친 쓰기를 통한 동시적 트랜잭션 처리에서 오는 수평적 확장의 혜택 모두를 누리게 됩니다. 읽기에 대해선 여전히 랜덤한 접근을 하지만, 주어지는 분기의 상태 업데이트는 다수의 SSD에 걸쳐 저장되어 있기에, 읽기 또한 수평적으로 확장됩니다.

또한 클라우드브레이크는 가비지 컬렉션(Garbage collection)과 같은 작업을 실행할 수 있습니다. 분기들이 롤백 가능한 시점을 넘어 확정되고, 계정들도 그에 맞게 업데이트되면, 무효한 이전 계정들에겐 가비지 컬렉션이 실행되고, 이에 대한 메모리 할당은 초기화됩니다.

이러한 아키텍쳐는 또 하나의 장점을 지니고 있습니다: 바로 주어지는 어떠한 분기의 상태 업데이트에 대한 머클 루트(Merkle root) 연산도 다수의 SSD에 걸쳐 수평적으로 확장된 순차적 읽기로 가능하다는 것입니다. 이 접근 방식의 단점으로 데이터의 일반성을 놓친다는 것입니다. 이 방식은 커스텀 레이아웃과 데이터 구조를 가지고 있기 때문에, 데이터 쿼리와 편집에 다목적 데이터베이스 추상화를 쓸 수 없습니다. 다행히 지금은 개발이 끝났지만, 저희는 이 모든 것을 밑바닥부터 시작해야 했습니다.

클라우드브레이크 벤치마크

계정 데이터베이스는 RAM에 있고, 가용한 코어 수가 증가할수록 출력은 RAM의 접근 시간에 맞춰가는 것을 알아볼 수 있습니다. 계정이 1천만 개일 시, 데이터베이스는 더 이상 RAM에 담을 수 없게 됩니다. 하지만 성능은 단일 SSD로 초당 1백만 번가량의 쓰기가 나오게 됩니다.

솔라나 공식 커뮤니티에 참여하세요

공식 홈페이지 | 텔레그램 | 디스코드 | 트위터

--

--