DuckDB Quack 协议完全指南:两只鸭子聊天的正确姿势 HN 189 分 2026
发布: 2026-05-13 阅读: 14 分钟 数据库 / DuckDB
2026 年 5 月 12 日 DuckDB 团队发布了一个大新闻:DuckDB v1.5.2 正式引入 Quack 远程协议。这是 DuckDB 从纯 in-process 数据库迈向原生客户端-服务器架构的关键一步,在 Hacker News 上获得了 189 分和 42 条评论的热烈讨论。
本文是对 Quack 协议的全面解读:从设计哲学到协议细节,从五分钟上手到与 PostgreSQL / Arrow Flight 的基准对比。
INSTALL quack FROM core_nightly; LOAD quack; CALL quack_serve(...) 即可启动。
为什么 DuckDB 需要客户端-服务器协议?
DuckDB 自 2019 年诞生以来一直坚持 in-process 架构——数据库运行在应用程序进程内,通过低级别 API 直接访问数据,没有客户端和服务器之分,没有协议开销。这种设计在数据科学交互分析(Python notebook 中直接查询)和嵌入式 SQL 场景中表现出色。
但 in-process 架构有个天然短板:无法从多个进程同时修改同一个数据库文件。实践中有很多场景需要这种能力——比如一组进程采集遥测数据写入数据库,同时仪表盘需要查询同一张表。
此前用户有各种变通方案:自定义 RPC 方案、Arrow Flight SQL、MotherDuck 的自有协议,甚至有人把 DuckDB 塞进 PostgreSQL(即所谓的"EleDucken")——用 pg_duckdb 扩展 让 PostgreSQL 在内核中调用 DuckDB。
"这些变通方案之多终于让我们确信——用户真的需要这个功能。"DuckDB 团队在公告中写道。于是,Quack 诞生了。
Quack 协议:五分钟上手
Quack 的使用非常简洁。你需要两个 DuckDB 实例(可以是同一台机器的两个终端,也可以分布在世界各地)。
步骤一:安装 Quack 扩展
目前 Quack 在 core_nightly 仓库中,兼容 DuckDB v1.5.2:
INSTALL quack FROM core_nightly;
LOAD quack;步骤二:启动服务器
在 DuckDB #1(服务器端)执行:
CALL quack_serve(
'quack:localhost',
token = 'super_secret'
);
CREATE TABLE hello AS
FROM VALUES ('world') v(s);步骤三:客户端连接
在 DuckDB #2(客户端)执行:
INSTALL quack FROM core_nightly;
LOAD quack;
CREATE SECRET (
TYPE quack,
TOKEN 'super_secret'
);
ATTACH 'quack:localhost' AS remote;
FROM remote.hello;就这样——客户端 #2 能读到服务器 #1 的 hello 表中的 world。反过来客户端也能写入:
-- 在客户端 (#2) 执行
CREATE TABLE remote.hello2 AS
FROM VALUES ('world2') v(s);
-- 在服务器 (#1) 查看
FROM hello2;
-- → 'world2'你也可以通过 remote.query('SELECT s FROM hello') 将完整查询发送到远程端执行,适合复杂查询和大数据集。
协议设计深度解析
基于 HTTP
Quack 构建在 HTTP 之上,而不是从零发明传输协议。理由很实在:HTTP 是互联网的事实标准协议层,负载均衡、防火墙、认证、入侵检测等基础设施对 HTTP 有成熟的支持。"在 2026 年不在 HTTP 之上构建数据库协议是不明智的。"
这也让 DuckDB-Wasm 原生支持 Quack——浏览器中的 DuckDB 可以直接连接 EC2 上的 DuckDB 实例。
Request-Response 模式
所有交互由客户端驱动:连接请求(含 token 认证)→ 查询执行请求(返回第一批结果)→ 后续 fetch 请求(分页拉取剩余结果,支持多线程并行)。
序列化:application/duckdb
请求和响应使用新的 MIME 类型 application/duckdb 编码。底层复用了 DuckDB 内部的高效序列化原语——和预写日志 (WAL) 文件使用同一套基础库,经过了多年实战检验。
加密与安全
默认行为:
- 启动时自动生成随机 token
- 默认只绑定 localhost(可覆盖)
- 不使用 SSL(本地通信没必要引入 CA 基础架构)
建议暴露到公网时用 nginx 反向代理终止 SSL(用 Let's Encrypt 自动续期)。非本地连接时,Quack 客户端默认启用 SSL。
认证与授权:可扩展回调
Quack 的认证/授权模型设计得非常灵活:
- 认证:默认用随机 token 对比,但允许用户自定义回调函数——可以查询 LDAP、读文本文件、甚至"掷骰子"
- 授权:默认放行所有操作,但你可以审查每条客户端查询,关联认证身份
- 回调函数甚至可以是纯 SQL 宏——门槛极低
默认端口:9494
Quack 服务器默认监听 9494 端口。94 这个数字是为了纪念 Netscape Navigator 的发布年份——1994 年。
基准测试:快得离谱
DuckDB 团队在 AWS 上进行了两个维度的基准测试:
测试环境:m8g.2xlarge(8 vCPU / 32 GB RAM / 最高 15 Gbps 网络),同一可用区,ping 延迟约 0.280 ms。
1. 批量传输性能
对比对象:PostgreSQL 原生协议和 Arrow Flight SQL(GizmoSQL 作为服务器,内部也用 DuckDB)。
逐步增加 TPC-H lineitem 表的传输行数,最高达 6000 万行(CSV 格式 76 GB)。5 次运行中位数时间。
结果令人印象深刻:Quack 在几乎所有数据量级上都明显优于 PostgreSQL 和 Arrow Flight。DuckDB 团队表示:"据我们所知,Quack 目前是通过 socket 传输表格的最快方式之一。"
2. 小事务性能
模拟仪表盘实时读写的场景:大量小查询 + 少量插入。Quack 在这种"混合负载"下的性能同样优秀,能够支持通常需要重型 OLTP 数据库的实时分析工作负载。
Quack 的定位与限制
Quack 的目标不是替代 PostgreSQL,也不是把 DuckDB 变成一个通用的 OLTP 数据库。它的定位是:为 DuckDB 解锁更多使用场景——在保留 in-process 架构优势的同时,提供一个轻量、高效的远程访问通道。
适合 Quack 的场景:
- 多进程/多机器同时写入同一个 DuckDB 数据库
- 仪表盘实时查询 + 后端数据采集写入
- 浏览器中的 DuckDB-Wasm 连接远程实例
- 数据流水线中的中间结果交互
不适合的场景:
- 高并发短事务 OLTP(这不是 DuckDB 的设计目标)
- 需要完整 SQL 兼容性的场景(DuckDB 的 SQL 方言在持续完善中)
- 对行级锁和 ACID 事务有严格要求的场景
总结
DuckDB Quack 协议的发布标志着这个广受欢迎的分析型嵌入式数据库迈出了重要一步。它没有丢掉 DuckDB 的简洁哲学——安装一条命令,启动一条命令,连接一条命令。基于 HTTP、request-response 模式、可扩展的认证回调,这些设计选择让 Quack 既保持了 DuckDB 的"轻盈感",又解决了真实世界中的多进程并发访问问题。
如果你已经在用 DuckDB 做数据分析,Quack 会让你在多场景下更灵活;如果你之前因为并发限制而绕过 DuckDB,现在可以重新考虑它了。