러스트(Rust)로 개발된 임베디드 컬럼형 데이터베이스 'Frigatebird'는 푸시 기반(Push-based) 쿼리 실행 모델을 사용함
io_uring, SIMD, LZ4 압축 등 다양한 기술을 활용하여 I/O 성능을 최적화하고, 3단계 캐싱(Three-tier Caching)을 통해 데이터 접근 속도를 향상시킴
데이터베이스 설계 시 비동기/대기(Async/Await) 대신 멀티 스레딩(Multi-threading)을 선택한 배경을 설명함
SQL 지원, WAL(Write-Ahead Logging) 기반의 데이터 내구성(Data Durability), 다양한 데이터 타입(Data Types) 지원
Frigatebird는 푸시 기반(Push-based) 실행 모델을 채택하여 각 연산자가 데이터를 하위 단계로 전달한다. 이러한 방식은 병렬 처리(Parallel Processing)를 자연스럽게 가능하게 하며, 데이터는 50,000행 단위의 '모르셀(Morsel)'로 처리된다. 특히, 각 단계는 독립적으로 실행되므로, 여러 워커(Worker) 간의 병렬 처리를 통해 쿼리 성능을 극대화한다.
Frigatebird는 Late Materialization 기법을 사용하여 필요한 열(Column)만 로드한다. 예를 들어, 187,000행의 데이터에서 age, city, name 열을 선택하는 경우, Late Materialization을 사용하면 226,000개의 값만 로드하여 70%의 데이터 로딩 감소 효과를 얻을 수 있다. 이는 I/O 부하를 줄여 쿼리 성능을 향상시키는 핵심 요소이다.
Frigatebird는 io_uring과 O_DIRECT를 사용하여 OS 페이지 캐시(Page Cache)를 우회하는 비동기 I/O(Asynchronous I/O)를 구현했다. 이를 통해 디스크 I/O 성능을 향상시키고, 쓰기-선행 로그(Write-Ahead Logging, WAL)를 통해 데이터 내구성을 보장한다. 또한, LZ4 압축을 사용하여 데이터 저장 공간을 효율적으로 관리한다.
Frigatebird는 SIMD(Single Instruction, Multiple Data)를 활용하여 비트맵 연산을 통해 CPU 사이클 당 64개의 행을 처리한다. 또한, 낮은 카디널리티(Cardinality)의 문자열 열에 대해 딕셔너리 인코딩(Dictionary Encoding)을 적용하여 데이터 압축 효율을 높인다. 이러한 기술들은 쿼리 처리 속도를 향상시키는 데 기여한다.
저자는 Frigatebird 개발 시 비동기/대기(Async/Await) 대신 멀티 스레딩(Multi-threading)을 선택했다. 이는 io_uring의 복잡성을 관리하고, 락(Lock) 기반의 동기화(Synchronization)를 통해 데이터 일관성을 유지하기 위한 결정이었다. 멀티 스레딩은 모르셀(Morsel) 단위의 병렬 처리를 가능하게 하여, 데이터베이스의 전반적인 성능을 향상시킨다.