영어

한국어

DuckDB 내부 구조 완전 해부 - 고성능 아키텍처의 비밀

DuckDB 내부 구조 완전 해부 - 고성능 아키텍처의 비밀

날짜

August 4th, 2025

소요 시간

10분

서론

대용량 Parquet 파일을 DuckDB에 던졌는데, 몇 초 만에 결과가 돌아온 경험이 있다면, “이게 어떻게 가능한 거지?”라는 생각을 해본 적이 있을 겁니다. 이 놀라운 속도는 단순한 우연이 아니라, DuckDB만의 영리하고 의도적인 설계 선택들에서 비롯된 것입니다.

이번 탐구의 핵심은 DuckDB 성능의 세 가지 기둥:

  • Columnar Storage(컬럼형 저장 구조)
  • Vectorized Execution Engine(벡터화 실행 엔진)
  • Morsel-Driven Parallelism(모셀 기반 병렬 처리)

이 세 가지 아키텍처적 축에 있습니다.

DuckDB의 코어 기술이 어떻게 결합되어 로컬 환경에서도 혁신적인 데이터 분석 경험을 만들어내는지 함께 살펴보겠습니다.

1. 핵심 아키텍처 3요소: DuckDB 속도의 비밀

DuckDB가 빠른 이유는 단 하나의 요소 때문이 아닙니다. 그 비결은 서로 긴밀히 맞물려 작동하는 세 가지 핵심 구성요소 컬럼형 저장 구조(Columnar Storage), 벡터화 실행 엔진(Vectorized Execution Engine), 모셀 기반 병렬 처리(Morsel-Driven Parallelism)에 있습니다.

1.1. 컬럼형 저장 구조(Columnar Storage)

전통적인 데이터베이스(예: PostgreSQL, MySQL)는 데이터를 행(row) 단위로 저장합니다. 이 방식을 Row-based Storage라고 부르며, 각 행의 모든 값이 함께 저장됩니다. 예를 들어, [id_1, name_1, age_1], [id_2, name_2, age_2] 이런 식입니다.

이 구조는 특정 ID로 사용자를 조회하는 등, 한 행의 모든 데이터를 한 번에 읽어야 하는 경우에는 효율적입니다.

하지만 분석(analytic) 작업에서는 대부분 많은 행의 일부 컬럼만 필요합니다. 예를 들어 “제품별 총매출”을 계산하려면 50개의 컬럼 중 product_category와 sales_amount만 있으면 됩니다. 그러나 행 기반 구조에서는 여전히 전체 컬럼을 읽어야 하므로, I/O 낭비가 발생합니다.

DuckDB는 이 문제를 해결하기 위해 컬럼형 저장 구조(Columnar Storage)를 사용합니다. 이 방식에서는 데이터를 칼럼 별로 저장합니다: [id_1, id_2, ...], [name_1, name_2, ...], [age_1, age_2, ...].

이 구조에는 두 가지 주요 장점이 있습니다. 쿼리에서 필요한 컬럼만 읽기 때문에 시간과 메모리를 절약할 수 있습니다.

같은 컬럼 내 데이터는 유사한 값이 많아 압축 효율이 높습니다.

실제 예시: 50개의 컬럼을 가진 Parquet 파일 sales_records.parquet에서 제품 카테고리별 총매출을 계산한다고 가정합시다.

SQL
  -- DuckDB는 다음 쿼리 실행 시 두 컬럼만 읽습니다: ‘product_category’와 ‘sales_amount’  

  -- 나머지 48개의 컬럼은 디스크에서 읽지 않습니다.  

  SELECT product_category, SUM(sales_amount)  

  FROM 'sales_records.parquet'  

  GROUP BY product_category; 

이처럼 DuckDB는 필요한 데이터만 읽는 효율성 덕분에 “넓은 테이블(컬럼 수가 많은 데이터)”을 매우 빠르게 처리할 수 있습니다. 또한 Parquet 파일의 row-group metadata(예: 컬럼별 min/max 값)를 활용해, 필터링 시 불필요한 블록을 건너뛰는 Predicate Pushdown 기술도 사용합니다.

1.2. 벡터화 실행 엔진(Vectorized Execution Engine)

컬럼 단위로 데이터를 저장하는 것은 시작에 불과합니다. 이제 그 데이터를 어떻게 빠르게 처리할 것인가가 다음 과제입니다.

많은 전통적 시스템은 데이터를 한 행씩 처리합니다. 이를 Tuple-at-a-time execution이라고 하며, 각 행마다 CPU가 여러 번의 함수 호출을 수행합니다. 이 방식은 오버헤드가 커서 비효율적입니다.

한 번에 실행되는 튜플
한 번에 실행되는 튜플

DuckDB는 벡터화 실행(Vectorized Execution) 방식을 채택했습니다. 이는 데이터를 한 번에 한 값씩이 아니라, 1024개~2048개 정도의 값(batch)을 묶어서 처리합니다.

비유하자면,

  • 전통적인 방식은 의자 하나씩 완성하는 수작업이라면,
  • 벡터화 방식은 ‘조립 라인’처럼 한 번에 여러 작업을 병렬로 처리하는 것입니다.

이로 인해 함수 호출 오버헤드가 줄고, CPU 캐시 효율이 극대화됩니다.

1.3. 모셀 기반 병렬 처리(Morsel-Driven Parallelism)

현대 CPU는 다중 코어(Multi-core) 구조를 가지고 있지만, 이를 제대로 활용하지 못하는 시스템이 많습니다. DuckDB는 이를 극대화하기 위해 Morsel-Driven Parallelism이라는 독특한 병렬 처리 모델을 도입했습니다.

작동 방식은 다음과 같습니다.

  • DuckDB는 데이터를 작은 단위(morsel)로 분할합니다.
  • scan, filter, aggregate 등의 연산자(operators)로 실행 계획을 구성합니다.
  • 각 모셀을 모든 CPU 코어에 분배해 병렬 실행합니다.
모스엘 주도 병렬 처리
모스엘 주도 병렬 처리

각 코어는 동일한 실행 계획을 자신이 받은 데이터 조각에 대해 수행합니다. 이렇게 하면 사용자는 별도의 설정 없이도 CPU 자원을 자동으로 최대한 활용할 수 있습니다. 8코어 머신에서는 8개 코어를, 32코어 머신에서는 32개 코어를 모두 사용하여 거의 선형적으로 속도가 증가합니다.

즉,

  • 필요한 데이터만 읽고(Columnar),
  • 효율적으로 처리하며(Vectorized),
  • 가능한 모든 자원을 활용(Parallel) 하는 것

이 3요소가 DuckDB의 폭발적인 성능입니다.

2. 핵심을 넘어: 성능을 완성하는 다른 요소들

DuckDB의 속도는 위 세 가지 기둥이 중심이지만, 그 아래에는 이를 보완하는 설계 요소들이 더 있습니다.

2.1. 인프로세스 아키텍처 (In-Process Architecture)

DuckDB는 인프로세스 데이터베이스(in-process database)입니다. Python, Jupyter, R, C++ 같은 애플리케이션 내부에서 직접 실행됩니다. PostgreSQL이나 Snowflake처럼 별도의 서버나 네트워크 연결이 필요하지 않습니다.

이 설계는 다음과 같은 장점을 가집니다.

  • 네트워크 지연이 없습니다 (동일 프로세스 내 실행).
  • 즉시 시작 가능.
  • Pandas, NumPy, Apache Arrow 등과 데이터 복사 없이 자연스럽게 통합됩니다.

덕분에 DuckDB는 로컬 데이터 분석, 노트북 환경, 임베디드 데이터베이스 엔진으로 이상적입니다.

2.2. 지능형 메모리 관리: 버퍼 매니저 (Buffer Manager)

DuckDB에는 눈에 잘 띄지 않지만 핵심적인 구성요소인 Buffer Manager가 있습니다. 메인 메모리(RAM)와 디스크 저장소 사이의 중간 계층으로 작동합니다.

DuckDB가 Parquet 파일이나 자체 테이블 데이터를 조회할 때, Buffer Manager는 다음을 보장합니다:

  • 자주 사용하는 데이터는 RAM에 캐싱
  • 오래된 데이터 블록은 LRU(Least Recently Used) 알고리즘으로 교체
  • 이미 캐시에 있는 데이터는 디스크 재조회 방지

이를 통해 실제 환경에서는 다음과 같은 효과를 얻습니다.

  • 동일한 쿼리를 반복 실행할 때 두 번째부터 훨씬 빨라짐
  • 사용자가 직접 메모리 튜닝을 할 필요 없이 DuckDB가 자동으로 최적화

3. DuckDB를 사용하면 안 될 때는?

아무리 강력한 도구라도 모든 문제에 맞는 것은 아닙니다. 다음과 같은 경우에는 적합하지 않습니다.

3.1. 고빈도 트랜잭션 OLTP 시스템

예: 전자상거래 백엔드, 예약 시스템, 사용자 관리 등

이런 시스템은 초당 수천 건의 작은 쓰기/수정/삭제 작업을 처리해야 합니다.

3.1.1. 왜 적합하지 않은가?

DuckDB는 컬럼형 구조로 데이터를 저장하고, 배치 단위로 처리합니다.

즉, 대량의 데이터를 읽는 데는 뛰어나지만, 작은 단위로 잦은 쓰기 작업에는 비효율적입니다.

3.1.2. 대안은?

이 경우 행 기반(row-based) 데이터베이스를 사용해야 합니다.

  • PostgreSQL

  • MySQL

  • SQL Server

이들은 다수의 작은 트랜잭션을 처리하는 데 최적화되어 있습니다.

3.2. 중앙 집중형, 다중 사용자 데이터 웨어하우스

DuckDB는 단일 사용자와 단일 애플리케이션용으로 설계된 인프로세스 DB입니다. 조직 전체가 함께 사용하는 서버 기반 데이터 웨어하우스를 대체하기 위한 시스템은 아닙니다.

3.2.1. 왜 적합하지 않은가?

DuckDB의 동시성 모델은 단순합니다.

한 명의 writer와 여러 reader는 지원하지만, 수백 명이 동시에 접근하는 환경에는 부적합합니다.

3.2.2. 대안은?

조직 차원의 공유 시스템이 필요하다면 다음과 같은 클라우드 데이터 웨어하우스를 사용하는 것이 좋습니다.

이들은 수많은 사용자가 동시에 접근하는 환경에 최적화되어 있습니다.

결론

DuckDB는 데이터 생태계의 공백을 채운 혁신적인 존재입니다. 복잡한 서버 구성이나 클라우드 인프라 없이도, 로컬 환경에서 고성능 분석 데이터베이스의 힘을 바로 사용할 수 있게 해주죠.

컬럼형 저장 구조, 벡터화 실행, 효율적인 메모리 관리, 그리고 인프로세스 아키텍처까지 - DuckDB의 모든 설계는 단순함과 속도를 위해 최적화되어 있습니다.

이 글에서 소개한 원리를 이해하고 나면, 여러분도 DuckDB로 실제 데이터 문제를 더 빠르고 우아하게 해결할 수 있을 것입니다!

Newsletter

더 보기

안녕하세요 또는 XIN CHÀO

contact@upp-technology.com

+84 38 890 1954

대화하기

원하신 정보를 이메일로 보내드립니다

이메일을 입력해 주세요

원하시는 내용을 입력해 주세요

구독하기
KSA Cloud
ISO 9001:2015
ISO 27001:2022

Hanoi, Vietnam

Web3 Tower, No. 15, Alley 4, Duy Tan, Cau Giay, Hanoi, Vietnam

© 2025 UPP 글로벌 테크놀로지

솔루션을 찾고 계신가요? UPP를 찾으세요!

개인정보 보호정책