파티션 쓰기와 오브젝트 스토리지
Hive partitioning, S3 secrets, multipart write, small files 문제를 DuckDB 운영 기준으로 정리합니다.
핵심 요약
- httpfs extension으로 S3 호환 스토리지를 읽고 쓰며, 인증은 DuckDB Secrets Manager(credential_chain, SCOPE)를 표준으로 둡니다.
- persistent secret은 암호화되지 않은 binary로 디스크에 남을 수 있어, 공유·개발 장비에서는 session secret이나 cloud role을 먼저 씁니다.
- hive_partitioning=true와 partition key filter는 파일 skip으로 이어지지만, 파티션을 너무 많이 만들면 파일 수와 object listing 비용이 커집니다.
- PARTITION_BY에는 expression을 직접 넣을 수 없으므로 query 안에서 year/month 파티션 컬럼을 만든 뒤 쓰고, partition당 최소 100MB 이상을 권장합니다.
- COPY는 object storage의 atomic directory publish까지 풀어주지 않으므로, run id staging prefix에 먼저 쓴 뒤 manifest·pointer를 바꿔 노출합니다.
DuckDB는 로컬 파일뿐 아니라 S3 호환 오브젝트 스토리지에 직접 읽고 씁니다. 덕분에 분석 batch가 단순해지지만, DBA 관점에서는 credential, overwrite, small files, partition cardinality를 분명히 챙겨야 합니다.
S3 secret
httpfs extension은 S3 API 기반 스토리지 읽기, 쓰기, globbing을 지원합니다. 인증은 DuckDB Secrets Manager를 표준으로 둡니다.
INSTALL httpfs;
LOAD httpfs;
CREATE OR REPLACE SECRET lake_s3 (
TYPE s3,
PROVIDER credential_chain,
REGION 'ap-northeast-2',
SCOPE 's3://company-lake/'
);
SELECT *
FROM read_parquet('s3://company-lake/events/dt=2026-05-14/*.parquet');persistent secret은 암호화되지 않은 binary format으로 디스크에 남을 수 있습니다. 공유 노트북이나 개발 장비라면 session secret이나 cloud role을 먼저 씁니다.
Hive partitioning 읽기
SELECT *
FROM read_parquet(
's3://company-lake/orders/year=*/month=*/*.parquet',
hive_partitioning = true
)
WHERE year = 2026
AND month = 5;partition key filter는 불필요한 파일을 건너뛰게 해줍니다. 다만 파티션 컬럼을 너무 많이 만들면 파일 수와 object listing 비용이 커집니다.
Partitioned write
COPY (
SELECT
*,
year(order_date) AS year,
month(order_date) AS month
FROM orders
) TO 's3://company-lake/curated/orders'
(FORMAT parquet, PARTITION_BY (year, month), COMPRESSION zstd);PARTITION_BY에는 expression을 직접 넣을 수 없으므로, 위처럼 query 안에서 파티션 컬럼을 만든 뒤 씁니다.
Small files 기준
DuckDB 문서는 작은 partition을 많이 쓰면 비용이 크다고 보고, 보통 partition당 최소 100MB 이상을 권장합니다.
| 증상 | 원인 | 대응 |
|---|---|---|
| 파일 수가 partition마다 thread 수만큼 늘어남 | partitioned write가 directory별로 file을 생성 | threads 조정, 후속 compaction |
| object listing이 느림 | 너무 많은 partition과 file | partition key 줄이기 |
| selective query가 느림 | partition key가 filter와 맞지 않음 | 날짜/tenant 등 실제 필터 기준으로 재설계 |
| overwrite가 위험함 | object storage는 directory transaction이 아님 | staging prefix 후 promote |
안전한 publish 패턴
DuckDB의 COPY는 파일을 잘 써주지만, object storage의 atomic directory publish까지 풀어주지는 않습니다. production에서는 final path에 바로 쓰지 말고,
run id가 붙은 staging prefix에 먼저 쓴 다음 manifest, catalog, pointer를 바꿔서 노출합니다.