DuckDB 一直以"嵌入式分析数据库"著称——进程内运行、零外部依赖、单文件搞定一切。但嵌入式也意味着一个天然限制:多个进程或多个用户很难同时操作同一个数据库文件。最近 DuckDB 官方宣布了 Quack 协议,通过 HTTP 实现客户端/服务器模式,让多个 DuckDB 实例可以远程连接同一个数据库。这标志着 DuckDB 从"单机利器"开始向"多用户协作"迈出关键一步。
从嵌入式到可共享:为什么需要 Quack
DuckDB 的传统用法是这样的:
import duckdb
con = duckdb.connect("analytics.db")
con.execute("SELECT COUNT(*) FROM events")
数据库文件 analytics.db 被当前进程独占。如果另一个 Python 进程或 Jupyter 用户也想查询同一份数据,要么等前者释放连接,要么各自拷贝一份文件——对实时分析场景来说都不理想。
Quack 解决的核心问题:让一个 DuckDB 实例作为服务器持有数据库,其他实例通过 HTTP 协议远程读写,不再需要文件级独占。
Quack 协议的工作方式
Quack 基于 HTTP 传输,这意味着:
- 客户端不需要专门的二进制网络库,任何能发 HTTP 请求的环境都能接入
- 防火墙、代理、负载均衡器等基础设施天然兼容
- 未来可以叠加 TLS、认证等标准 Web 安全层
协议层面,Quack 定义了一组 HTTP endpoint,客户端将 SQL 查询和参数以请求体发送,服务器端 DuckDB 执行后返回结果。这和 PostgreSQL 的 libpq 或 MySQL 的原生协议不同——Quack 走的是"HTTP 即协议"路线,更轻量、更易部署。
实战:启动 Quack 服务并远程查询
以下示例展示如何启动一个 DuckDB Quack 服务器,并用 Python 客户端远程执行查询。注意:Quack 是新发布的协议,具体 API 路径和参数以官方文档为准,此处基于协议设计思路给出可改造的骨架代码。
第一步:启动服务器端
# 安装 DuckDB CLI(如果尚未安装)
# macOS
brew install duckdb
# 启动 DuckDB 并加载 Quack 扩展,开放 HTTP 服务
duckdb -c "INSTALL httpserver FROM community; LOAD httpserver;"
duckdb -c "INSTALL quack FROM community; LOAD quack; START_QUACK_SERVER('0.0.0.0', 9000);"
上述扩展名与端口为示意,实际扩展加载方式请参照 DuckDB 最新官方文档。核心思路是:在持有数据库的 DuckDB 进程中加载 Quack 扩展并绑定端口。
第二步:客户端远程查询
import requests
import json
QUACK_URL = "http://your-server:9000/query"
# 发送 SQL 查询到远程 DuckDB
response = requests.post(
QUACK_URL,
json={"sql": "SELECT event_type, COUNT(*) AS cnt FROM events GROUP BY event_type ORDER BY cnt DESC LIMIT 10"}
)
if response.status_code == 200:
result = response.json()
for row in result["data"]:
print(f"{row['event_type']}: {row['cnt']}")
else:
print(f"Query failed: {response.status_code}, {response.text}")
也可以直接用 DuckDB Python 客户端连接远程实例(如果客户端驱动已支持 Quack 协议):
import duckdb
# 通过 Quack 协议连接远程数据库
con = duckdb.connect("quack://your-server:9000/analytics")
df = con.execute("""
SELECT date, SUM(revenue) AS daily_revenue
FROM sales
WHERE date >= '2025-01-01'
GROUP BY date
ORDER BY date
""").df()
print(df.head())
quack://连接串格式为示意写法,实际格式以官方发布为准。如果客户端驱动尚未内置 Quack 支持,可退回到 HTTP 请求方式。
多用户场景下的考量
Quack 打开了多用户大门,但也带来需要正视的问题:
| 维度 | 嵌入式模式 | Quack 服务模式 |
|---|---|---|
| 并发读 | 单进程内安全 | 多客户端可并行读 |
| 并发写 | 串行化,无冲突 | 需要事务隔离与锁机制 |
| 部署复杂度 | 零 | 需要守护进程、端口管理 |
| 网络延迟 | 无 | HTTP 往返开销 |
| 安全边界 | 进程内 | 需认证、TLS、访问控制 |
关键提醒:DuckDB 的写入并发能力仍然有限。Quack 让多个客户端能"到达"同一个数据库,但不意味着它可以像 PostgreSQL 那样处理高并发写入。适合的场景是:多用户读查询 + 低频写入,比如团队共享一个分析数据集,少数人定期刷新数据,多数人只做查询和报表。
落地建议
如果你正在考虑把 Quack 引入工作流,可以按这个清单推进:
- 先确认场景:团队是否真的需要多人同时查询同一份 DuckDB 数据?如果只是偶尔共享,拷贝文件可能更简单。
- 网络安全先行:Quack 默认走 HTTP 而非 HTTPS,生产环境务必叠加反向代理(如 Nginx)做 TLS 终结和基本认证。
- 读写分离设计:写操作集中在少数管道任务,读操作通过 Quack 服务分发。避免多个客户端同时大批量 INSERT。
- 监控服务进程:DuckDB 作为服务器进程需要守护(systemd 或容器),并监控内存与查询耗时。
- 保留嵌入式回退路径:本地开发和单用户场景继续用嵌入式模式,只在需要共享时才切换到 Quack。
Quack 的意义不在于让 DuckDB 变成"又一个 PostgreSQL",而是让一个原本只能在进程内使用的分析引擎,获得了低门槛的网络共享能力。对于已经在用 DuckDB 做本地分析的团队来说,这是一条最小代价的协作升级路径。