https://product.kyobobook.co.kr/detail/S000220221456
LUVIT EPL과 유튜브 데이터로 배우는 DuckDB | 이기준 - 교보문고
LUVIT EPL과 유튜브 데이터로 배우는 DuckDB | 복잡한 데이터 분석 흐름을 더 단순하게 만드는 DuckDB 최근 주목받고 있는 DuckDB를 활용해 SQL 기반 데이터 분석과 실전 프로젝트를 학습할 수 있도록 구
product.kyobobook.co.kr
예전에는 항상 혼자 헤엄치던 오리가 이제는 무리를 지어 헤엄칠 수 있게 되었다.
수년 동안 DuckDB에 대한 가장 큰 불만은 늘 같은 한 문장이었습니다.
“한 번에 하나의 작성자(writer)만 지원한다.”
데이터 엔지니어들은 DuckDB를 발견하고, 놀라울 정도로 빠른 컬럼형 SQL 성능에 매료되었습니다. 하지만 여러 프로세스가 동일한 데이터베이스에 동시에 데이터를 기록해야 하는 순간 이 한계에 부딪히곤 했습니다. 이를 해결하기 위한 우회 방법들도 계속 늘어났습니다. 직접 RPC 래퍼를 구현하거나, Arrow Flight SQL 기반의 중간 계층을 만들거나, pg_duckdb를 통해 PostgreSQL로 쓰기 작업을 우회하거나, 결국 더 무거운 데이터베이스 시스템으로 갈아타는 경우도 적지 않았습니다.
2026년 5월 12일, DuckDB 개발팀은 이에 대한 명확한 답을 내놓았습니다. 바로 Quack입니다. Quack은 여러 DuckDB 인스턴스가 서로 통신할 수 있도록 설계된 네이티브 클라이언트-서버 프로토콜로, 더 중요한 것은 여러 인스턴스가 동시에 동일한 데이터베이스에 쓰기 작업을 수행할 수 있도록 해줍니다.
이것은 단순한 릴리스 노트의 한 줄이 아닙니다.
DuckDB 아키텍처의 중요한 전환점입니다.
다중 쓰기가 어려웠던 이유 (그리고 DuckDB가 기다렸던 이유)
DuckDB는 처음부터 인프로세스(in-process) 분석 엔진으로 설계되었습니다. 별도의 서버 프로세스도 없고, 네트워크 왕복 통신도 없습니다. 대신 Python, R, Java, Go 애플리케이션 안에 라이브러리 형태로 직접 내장됩니다. 이러한 구조 덕분에 DuckDB는 뛰어난 속도와 단순함을 제공할 수 있었습니다. 예를 들어 Python 코드 두 줄만으로 S3에 저장된 Parquet 파일을 조회할 수 있으며, 별도의 데몬을 실행하거나 복잡한 연결 문자열을 설정할 필요도 없습니다.
하지만 그 대가도 있었습니다.
DuckDB는 상당한 양의 상태 정보를 메모리에 유지합니다. 만약 두 개의 서로 다른 프로세스가 동시에 쓰기 작업을 수행하려고 한다면, 각각은 자신만의 메모리 상태를 가지게 됩니다. 그리고 이 상태들을 서로 조정하고 일관성을 유지하려면 분산 조정(distributed coordination)이 필요합니다. 바로 DuckDB가 애초에 피하려고 했던 복잡성입니다.
그래서 DuckDB는 오랫동안 엄격한 규칙을 유지해 왔습니다.
하나의 쓰기 프로세스(writer process), 여러 개의 읽기 프로세스(reader process).
단일 프로세스 내부에서는 MVCC(Multi-Version Concurrency Control)를 활용해 여러 쓰기 스레드를 사용할 수 있으며, 데이터 추가(append) 작업도 충돌 없이 처리할 수 있습니다. 하지만 서로 다른 프로세스 간의 동시 쓰기 작업은 지원되지 않았습니다.
커뮤니티는 이 공백을 메우기 위해 다양한 해결책을 만들어냈습니다. 단순한 RPC 래퍼부터 시작해, MotherDuck이 구축한 전체 클라우드 플랫폼에 이르기까지 수많은 프로젝트가 등장했습니다. 모두 DuckDB의 이 한계를 우회하기 위한 시도였습니다.
DuckDB 개발팀은 이러한 생태계의 움직임을 중요한 신호로 받아들였습니다.
사용자들이 이미 답을 내린 것입니다.
Quack 등장: DuckDB가 DuckDB와 대화하다
"두 마리(혹은 그 이상)의 오리가 서로 이야기하고 싶다면 무엇을 할까요? 꽥꽥(Quack) 울겠죠!"
— DuckDB 개발팀
Quack 프로토콜의 개념은 놀라울 정도로 단순합니다. 하나의 DuckDB 인스턴스는 서버 역할을 수행하고, 다른 DuckDB 인스턴스는 클라이언트 역할을 수행합니다. 중요한 점은 둘 다 완전한 DuckDB 인스턴스라는 것입니다.
서버는 변경 가능한 상태(mutable state)를 보유하며, 모든 쓰기 작업을 순차적으로 처리하고 쿼리에 응답합니다. 클라이언트는 서버에 원격으로 연결한 뒤, 마치 로컬에 연결된 데이터베이스처럼 사용할 수 있습니다.
가장 기본적인 설정은 다음과 같습니다.
Server Side (DuckDB #1)
INSTALL quack FROM core_nightly;
LOAD quack;
CALL quack_serve(
'quack:localhost',
token = 'super_secret'
);
CREATE TABLE telemetry AS
FROM VALUES ('event_1', NOW()) v(name, ts);
Client Side (DuckDB #2 — or #3, #4, #N…)
INSTALL quack FROM core_nightly;
LOAD quack;
CREATE SECRET (
TYPE quack,
TOKEN 'super_secret'
);
ATTACH 'quack:localhost' AS remote;
-- Write from this process
INSERT INTO remote.telemetry VALUES ('event_2', NOW());
-- Query it
FROM remote.telemetry;
서버 측에서 실행하려는 복잡한 쿼리의 경우:
FROM remote.query(
'SELECT name, COUNT(*) as cnt FROM telemetry GROUP BY 1'
);
이 방법은 대규모 데이터셋을 다룰 때 중요합니다. 복잡한 연산 작업은 서버로 넘기고, 결과만 가져오면 됩니다.
프로토콜 자체: HTTP를 가장 실용적으로 활용하다
DuckDB 개발팀은 2026년에 데이터베이스 프로토콜을 사실상 처음부터 설계할 수 있는 드문 기회를 가졌습니다. 기존 시스템과의 호환성이나 레거시 제약에 얽매일 필요가 없었던 것입니다.
그들이 선택한 해법은 무엇이었을까요?
Quack을 HTTP 위에 직접 구축하는 것이었습니다.
이는 매우 실용적이면서도 영리한 결정입니다.
모든 로드 밸런서(load balancer), 방화벽(firewall), 인증 프록시(auth proxy)는 이미 HTTP를 사용합니다. 따라서 새로운 인프라 기술을 사용할 필요가 없습니다.
DuckDB-Wasm 역시 Quack을 네이티브로 지원할 수 있습니다. 즉, 웹 브라우저 내부에서 실행되는 DuckDB 인스턴스가 EC2 인스턴스에서 실행 중인 DuckDB 서버에 직접 연결할 수 있다는 의미입니다.
또한 HTTP/2와 HTTP/3의 성능 최적화를 그대로 활용할 수 있습니다. 대규모 결과 집합을 여러 스레드에서 병렬로 가져오는 기능 역시 자연스럽게 지원됩니다.
상호작용 모델은 클라이언트가 주도하는 전통적인 요청-응답(request-response) 방식입니다. 여기에는 토큰 기반 인증을 포함한 연결 요청, 쿼리 실행 요청, 그리고 대용량 결과를 전송하기 위한 청크(chunk) 단위 결과 가져오기 메시지 등이 포함됩니다.
Quack이 열어주는 새로운 활용 사례
데이터 엔지니어라면 이 부분에 특히 주목해야 합니다.
Quack은 단순히 오래된 제약 하나를 해결한 것이 아닙니다. 이전까지는 DuckDB로는 아예 구현할 수 없었던 새로운 아키텍처 패턴을 가능하게 만들었습니다.
이제 DuckDB는 더 이상 단일 프로세스 안에서만 동작하는 분석 엔진에 머무르지 않습니다. 여러 클라이언트가 하나의 DuckDB 서버에 연결해 동시에 작업할 수 있는 새로운 활용 방식이 등장하게 된 것입니다.
1. 실시간 대시보드를 위한 다중 프로세스 텔레메트리 수집
DuckDB 개발팀이 직접 제시한 대표적인 활용 사례입니다.
수십 개의 프로세스가 텔레메트리 데이터를 수집하면서 동시에 대시보드가 동일한 테이블을 실시간으로 조회하는 시나리오입니다.
기존에는 이런 구조를 구현하려면 일반적으로 다음과 같은 아키텍처가 필요했습니다.
Telemetry Producers → Kafka → OLAP 데이터베이스 → BI 도구
[Worker 1] → INSERT INTO quack_server.events
[Worker 2] → INSERT INTO quack_server.events
[Worker 3] → INSERT INTO quack_server.events
[Dashboard] → SELECT * FROM quack_server.events WHERE ts > NOW() - INTERVAL '5 min'
모두 동일한 DuckDB 서버를 대상으로 합니다. 중간 규모의 워크로드에는 중간 큐가 필요하지 않습니다.
2. 병렬 ETL 작성자와 단일 분석 저장소
전형적인 ETL 시나리오를 생각해 보겠습니다. 8개의 Python 워커가 있고, 각 워커는 데이터의 서로 다른 파티션을 병렬로 처리합니다.
이전에는 각 워커가 별도의 DuckDB 파일에 결과를 기록한 뒤, 나중에 이 파일들을 하나로 병합해야 했습니다.
이제는 모든 워커가 동일한 DuckDB 서버에 동시에 데이터를 기록할 수 있습니다.
# In each parallel worker
import duckdb
conn = duckdb.connect()
conn.execute("INSTALL quack FROM core_nightly; LOAD quack;")
conn.execute("CREATE SECRET (TYPE quack, TOKEN 'my_token');")
conn.execute("ATTACH 'quack:etl-server:5432' AS warehouse;")
# Each worker writes its partition
conn.execute(f"""
INSERT INTO warehouse.processed_orders
SELECT * FROM read_parquet('s3://bucket/partition_{worker_id}/*.parquet')
""")
DB파일을 병합할 필요도 없고, 임시 파일도 사용할 필요가 없습니다. 작성자들은 서버에서 동시에 작업을 수행하며, 서버가 커밋을 순차적으로 처리합니다.
3. 분석 백엔드를 공유하는 마이크로서비스
여러 서비스로 구성된 경량 SaaS나 내부 도구를 구축하는 경우, Quack을 사용하면 각 서비스가 로컬 쿼리를 위해 자체 DuckDB를 유지하면서 공유 분석 레이어에 대한 읽기/쓰기 작업도 수행할 수 있습니다:
[Auth Service] → local DuckDB + reads from quack_server.user_events
[Billing Service] → local DuckDB + writes to quack_server.transactions
[Analytics API] → local DuckDB + reads quack_server.* for dashboards
이전에는 “EleDucken” 패턴(Postgres 내부의 DuckDB)이 이를 위한 임시 해결책이었지만, Quack은 DuckDB의 자체 솔루션입니다.
4. 브라우저-서버 직접 분석 (DuckDB-Wasm의 가능성)
이 부분은 정말 새로운 영역입니다.
DuckDB-Wasm이 Quack을 네이티브로 지원하기 때문에 다음과 같은 분석 애플리케이션을 구축할 수 있습니다.
- 브라우저에서는 DuckDB-Wasm이 실행되어 로컬 쿼리 성능을 가속화
- 서버 측 DuckDB와 Quack을 통해 직접 연결
- 공유 데이터와 영구 저장 데이터를 조회하고 수정
그리고 프런트엔드와 데이터 계층 사이에 별도의 REST API 레이어가 필요하지 않습니다.
5. 엣지(Edge)에서 중앙 서버로의 데이터 수집
Quack은 IoT 환경이나 분산 데이터 수집 시스템에서도 새로운 가능성을 제공합니다.
[Edge Node A] → DuckDB in-process → periodically flushes to quack:central-server
[Edge Node B] → DuckDB in-process → periodically flushes to quack:central-server
[Central Server] → DuckDB serving Quack → runs scheduled rollup queries
DuckDB는 용량이 작아 엣지 하드웨어에서도 원활하게 구동됩니다. Quack은 네이티브 동기화 메커니즘을 통해 이를 완벽하게 보완합니다.
이것이 여러분의 데이터 스택에 의미하는 것
이제 Quack의 장단점을 솔직하게 이야기해 보겠습니다.
지연 시간(Latency)
Quack은 네트워크를 통해 데이터를 전송합니다. 설령 localhost에서 실행하더라도 말입니다. 따라서 기존의 순수 인프로세스 DuckDB가 제공하던 "사실상 지연 시간이 없는(zero-latency)" 장점은 일부 사라집니다.
특히 대규모 데이터 적재 작업에서는 DuckDB 블로그에서 권장하는 remote.query() 사용이 매우 중요합니다. 이 방식은 클라이언트가 원시 데이터를 모두 가져와 처리하는 대신, 서버가 직접 작업을 수행하도록 지시합니다. 결과적으로 불필요한 네트워크 전송을 줄이고 성능을 크게 개선할 수 있습니다.
PostgreSQL을 대체하는 것은 아니다
Quack이 추가되었다고 해서 DuckDB가 PostgreSQL을 대체하는 OLTP 데이터베이스가 된 것은 아닙니다.
많은 수의 짧고 빈번한 트랜잭션이 발생하는 고전적인 OLTP 환경에서는 PostgreSQL과 같은 시스템이 여전히 더 적합합니다.
DuckDB는 지금도 대량의 데이터를 분석하는 OLAP 워크로드에 최적화되어 있습니다. DuckDB 개발팀 역시 이 점을 명확하게 인정하고 있습니다.
DuckLake와도 다르다
Quack은 DuckLake와 PostgreSQL 카탈로그 조합과도 다른 개념입니다.
DuckLake는 Unity Catalog나 PostgreSQL을 이용해 충돌을 조정하면서 레이크하우스 포맷에 대한 다중 작성자 환경을 제공하는 것이 목적입니다.
반면 Quack은 하나의 DuckDB 서버 인스턴스에 여러 클라이언트가 직접 연결하는 클라이언트-서버 프로토콜입니다.
즉,
- DuckLake = 레이크하우스 기반 다중 작성자 아키텍처
- Quack = 단일 DuckDB 서버에 대한 원격 접근 프로토콜
이라고 이해할 수 있습니다.
Quack의 진정한 활용 영역
Quack이 가장 빛을 발하는 영역은 기존에 다음 두 가지 중 하나를 선택해야 했던 분석 워크로드입니다.
첫째, ClickHouse나 Redshift 같은 보다 무거운 OLAP 데이터베이스를 도입하는 경우
둘째, 여러 DuckDB 파일을 생성하고 나중에 병합하는 복잡한 파이프라인을 구축하는 경우
만약 여러분의 환경이 다음 조건에 해당한다면 Quack은 매우 매력적인 선택지가 될 수 있습니다.
- 쓰기 빈도는 중간~높은 수준이다.
- 하지만 마이크로초 단위의 초고속 트랜잭션 처리는 필요하지 않다.
- 주요 작업은 분석 쿼리다.
- 인프라 운영 복잡도를 최소화하고 싶다.
Quack은 바로 이 영역을 겨냥하고 있습니다.
데이터 엔지니어에게 주는 의미
특히 다음과 같은 시스템을 구축하는 데이터 엔지니어라면 Quack에 주목할 만합니다.
- 다수의 고객사나 조직을 지원하는 리포팅 플랫폼
- ERP 분석 시스템
- 운영 모니터링 및 텔레메트리 플랫폼
- SaaS 분석 서비스
- 중규모 데이터 웨어하우스
이러한 환경에서는 DuckDB의 낮은 운영 비용과 Quack의 다중 작성자 기능이 결합되면서 매우 강력한 대안이 됩니다.
이전에는 이러한 요구사항이 생기면 자연스럽게 ClickHouse, Redshift, 혹은 별도의 데이터 웨어하우스 플랫폼을 고려해야 했습니다.
하지만 이제는 상당수의 중간 규모 워크로드에서 DuckDB + Quack 조합만으로도 충분히 경쟁력 있는 아키텍처를 구축할 수 있게 되었습니다.
Quack의 진정한 의미는 단순히 "여러 명이 동시에 쓸 수 있다"가 아닙니다.
DuckDB가 로컬 분석 엔진에서 벗어나, 실제 서비스 환경에서 운영 가능한 경량 분석 데이터베이스 플랫폼으로 한 단계 진화했다는 데 있습니다.
지금 바로 시작하기
Quack은 DuckDB v1.5.2부터 사용할 수 있으며, core_nightly 확장 저장소를 통해 제공됩니다.
-- On both client and server
INSTALL quack FROM core_nightly;
LOAD quack;
더 큰 그림
DuckDB는 “분석 분야의 SQLite”가 되고자 하는 연구 프로젝트로 시작했습니다. 이러한 비전은 여전히 유효하지만, Quack은 DuckDB가 한 단계 성숙했음을 보여줍니다. DuckDB는 이제 인-프로세스(in-process) 방식의 본질을 버리지 않으면서도, 사용 사례가 요구할 경우 서버로 작동할 준비가 되어 있습니다.
인-프로세스 모델은 여전히 기본 설정으로 유지됩니다. Quack은 다중 프로세스 쓰기가 진정으로 필요할 때 추가하는 선택적 확장 기능입니다. 이것이 바로 올바른 엔지니어링 철학입니다. 기본적으로는 단순하고, 필요할 때는 확장 가능한 구조죠.
오리가 성장했습니다. 이제 무리를 지어 헤엄칠 수 있게 되었습니다.
'EPL과 유튜브 데이터로 배우는 DuckDB' 카테고리의 다른 글
| DuckDB 속도 비밀: 2026년을 위한 10가지 팁 (0) | 2026.05.31 |
|---|---|
| Python 분석을 강화하는 DuckDB 활용 팁 10가지 (0) | 2026.05.31 |
| 고급 SQL 분석(Analytics)을 마스터하는 9가지 방법 (0) | 2026.05.28 |
| DuckDB Row Group과 statistics: pruning으로 밀리초 단위 성능 달성하기 (0) | 2026.05.26 |
| 컬럼형 저장방식의 작동 원리 (0) | 2026.05.23 |
댓글