
데이터 엔지니어 맷 마틴(Matt Martin)은 스프레드시트 보고서를 자동화하며 경력을 시작해 Teradata, BigQuery, Spark를 거쳤다. 그는 복잡한 인프라 없이 익숙한 SQL로 분석할 수 있다는 점에서 DuckDB를, 메타데이터를 SQL 데이터베이스에 저장하는 방식에서 DuckLake의 장점을 찾았다고 말한다.
맷은 2008년 Excel, Microsoft Access, SQL Server 사이에서 데이터를 복사해 보고서를 만드는 일을 했다. 보고서 하나를 만드는 데 세 시간이 걸렸고, 실수가 나면 처음부터 다시 해야 했다. 아버지에게 VBA 매크로를 배운 뒤 SQL Server와 Oracle 데이터베이스를 직접 조회하기 시작했고, 매크로는 예약 저장 프로시저와 자동화 파이프라인으로 발전했다. 처음에는 매일 오전 10시까지 20~30개 보고서를 내던 팀이 자동화 이후에는 오전 6시에 보고서를 배포하게 됐다.
이후 Teradata에서 대규모 병렬 처리와 노드 간 작업 분산을 경험했고, 2016년 무렵 The Home Depot에서 Google BigQuery로 옮겼다. 당시 BigQuery는 저장 프로시저를 지원하지 않아 Python과 pandas를 익혔고, 나중에는 Apache Spark도 사용했다. Spark는 강력했지만 JVM과 Spark 버전을 맞추고 긴 오류 추적 정보를 살펴야 했으며, 수백 개 파일을 처리하기 전에 클러스터가 준비될 때까지 3~5분을 기다리는 일도 있었다.
맷은 항공우주, 사기 탐지, 고빈도 거래 같은 일부 분야를 제외하면 페타바이트 데이터를 빠르게 처리해야 하는 작업이 흔하지 않다고 본다. 실시간 데이터가 필요하다고 말한 뒤 실제로는 월간 보고서에 쓰는 경우도 있다고 덧붙였다.
그는 2022년 무렵 DuckDB를 처음 접했다. DuckDB를 설치한 뒤 두 줄로 CSV 파일을 읽을 수 있다는 점에 관심을 가졌다고 한다.
import duckdb
duckdb.sql("FROM 'sales.csv'").show()
로컬 파일에서 시작해 Amazon S3의 파일을 조회하고, CSV와 Parquet, Iceberg 테이블을 한 쿼리에서 결합하는 방식으로 사용 범위를 넓혔다. S3 접근에는 s3:// 프로토콜을 활용한다.
CREATE SECRET (TYPE s3, PROVIDER credential_chain);
SELECT count(*) AS num_rows FROM 's3://bucket/exports/*.parquet';
INSTALL iceberg;
LOAD iceberg;
SELECT
o.order_id,
c.customer_name,
p.product_name
FROM iceberg_scan('s3://bucket/warehouse/orders') AS o
JOIN 's3://bucket/customers.parquet' AS c
ON o.customer_id = c.customer_id
JOIN 'products.csv' AS p
ON o.product_id = p.product_id;
맷이 꼽은 장점은 간결한 사용 방식과 SQL 지원이다. 그는 서비스 수준 목표(SLA)를 충족한다면 마찰이 적은 경험을 중요하게 여기며, DuckDB가 자신이 익힌 SQL 문법을 대부분 지원한다고 설명했다. 개인 재정 관리에도 DuckDB를 사용해 은행 거래 내역 CSV를 로컬에서 분석한다.
SELECT
date_trunc('month', transaction_date) AS month,
category,
sum(amount) AS total
FROM 'transactions_*.csv'
GROUP BY ALL
ORDER BY month, total;
그는 대규모 데이터와 버전 이력을 관리하기 위해 Apache Iceberg와 Delta Lake도 다뤘다. 다만 Iceberg는 트랜잭션마다 메타데이터 JSON, 매니페스트 목록, 매니페스트 등 여러 파일을 기록한다. 메타데이터가 커지면 쿼리 계획에 필요한 파일을 확인하는 데 시간이 늘어날 수 있다고 맷은 설명한다.
DuckLake는 메타데이터를 SQL 데이터베이스에 저장한다. 맷은 자신의 경험상 Iceberg에서 몇 초 걸리는 카탈로그 작업이 DuckLake에서는 1밀리초 미만에 끝난다고 말했다. 인덱스가 있는 테이블을 조회하기 때문이라는 설명이다. 다만 이는 맷의 경험에 근거한 비교다.
그는 오브젝트 스토리지에 DuckLake를 연결하는 설정이 간단하다는 점도 장점으로 들었다. 아래 예시처럼 버킷용 비밀 정보를 만들고 저장소를 연결할 수 있으며, DuckLake가 아직 없으면 DuckDB가 생성해 곧바로 테이블을 만들 수 있다고 설명했다.
CREATE SECRET (TYPE s3, PROVIDER credential_chain);
ATTACH 'ducklake:metadata.ducklake' AS my_lake (
DATA_PATH 's3://bucket/prefix/'
);
AWS Glue의 기존 Iceberg 카탈로그를 조회하는 설정도 DuckDB의 Iceberg 확장을 이용하면 세 문장으로 작성할 수 있다고 맷은 설명했다.
INSTALL iceberg;
LOAD iceberg;
ATTACH 'aws_account_id' AS glue_catalog (
TYPE iceberg,
ENDPOINT_TYPE glue
);
맷은 DuckDB v2.0 알파를 테스트하고 있으며, 지금까지 회귀 문제를 발견하지 못했다고 밝혔다. 그가 주목한 기능 중 하나는 동적으로 작성하는 ATTACH 문이다. v1.5까지는 경로를 리터럴로 지정해야 해 계정 번호를 스크립트에 직접 넣어야 했고, getenv를 호출하면 오류가 났다고 한다. v2.0에서는 표현식을 사용할 수 있어 계정 ID, 사용자 이름, 비밀번호, 연결 문자열을 환경 변수에서 실행 시점에 가져올 수 있다.
ATTACH getenv('AWS_ACCOUNT_ID') AS glue_catalog (
TYPE iceberg,
ENDPOINT_TYPE glue
);
또 다른 기능은 비동기 입출력이다. 맷이 Substack에 공개한 벤치마크에서는 Amazon S3에서 파일 1,000개와 10,000개를 읽을 때 v2.0 알파가 일관되게 67~70% 적은 시간을 기록했다. 이 수치는 맷이 공개한 벤치마크 결과다. 기존에는 파일 목록을 가져오고 파일을 읽는 요청이 순차적으로 이뤄졌지만, v2.0에서는 백그라운드에서 요청을 처리한다고 그는 설명했다. 쿼리 코드를 바꾸지 않아도 된다는 것이 그의 설명이다.
SELECT count(*) AS num_events FROM read_json('s3://bucket/logs/*.json');
맷은 S3, Google Cloud Storage, Azure에 있는 대량의 원시 파일을 분석하는 작업에서 DuckDB 단일 프로세스가 기존의 대형 Spark 클러스터를 대신할 수 있다고 본다. 이는 그의 전망이며, 모든 작업에 적용된다는 의미는 아니다.
Quack 원격 프로토콜은 DuckDB 인스턴스를 HTTP로 다른 DuckDB 인스턴스가 접속할 수 있는 서버로 만든다. 맷은 v2.0에서 연결과 해제 구문이 더 간결해지고 DuckLake를 공식 지원하는 점을 들었다. Amazon EC2에서 Quack으로 DuckLake를 제공하는 방법도 소개했다. 이 구성에서는 최종 사용자가 Quack 주소와 토큰만 있으면 되며, AWS 자격 증명이나 DuckLake에 대한 지식은 필요하지 않다고 설명한다. 그는 이 구성 위에 DuckDB-Wasm 대시보드도 만들었으며, 대시보드의 Wasm 빌드는 아직 v1.5를 사용하고 있어 v2.0 출시에 맞춰 업데이트할 계획이라고 밝혔다.
맷의 경험이 분산 시스템이 불필요하다는 뜻은 아니다. 그는 먼저 작업 요구사항을 살피고, 필요한 경우에만 인프라를 추가해야 한다는 원칙을 강조한다. DuckDB와 DuckLake에 관한 그의 글은 Substack에서 볼 수 있다.
댓글 (0)
로그인하면 이 기사에 내 생각을 남길 수 있어요