DuckDB 一直以"嵌入式分析数据库"著称——它像 SQLite 一样跑在进程内,没有独立服务端,没有网络监听端口。这种设计对单机场景很友好,但一旦你想让多个应用或多个用户同时访问同一份 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 用户、或者一个 BI 工具想同时读同一份数据,要么忍受只读模式下的并发限制,要么自己写一层代理服务来串行化请求。
Quack 解决的就是这个问题:它在 DuckDB 之上提供 HTTP 协议层,让一个 DuckDB 实例作为服务端监听请求,其他 DuckDB 实例作为客户端远程连接,共享同一个底层存储和计算资源。
Quack 协议的核心设计
Quack 的关键特性可以概括为三点:
- HTTP 作为传输层:不依赖自定义 TCP 协议或 gRPC,直接走 HTTP,这意味着任何能发 HTTP 请求的运行时都能当客户端,部署和调试也更简单。
- 多客户端并发访问:多个 DuckDB 客户端实例可以同时连接同一个 Quack 服务端,服务端负责协调查询执行和资源管理。
- 保留 DuckDB 的分析能力:客户端拿到的是完整的 SQL 执行能力,不是简单的数据转发。查询计划在服务端生成和执行,结果通过网络返回。
这种架构让 DuckDB 从"每个进程各跑一份"变成了"一份数据、多个入口",对数据团队共享分析场景尤其有用。
实际搭建与使用
下面用一个最小示例演示如何启动 Quack 服务端并用客户端远程查询。注意:Quack 是新发布的协议,具体 API 和参数可能随版本迭代调整,以下示例基于当前公开信息,运行前请确认你使用的 DuckDB 版本已包含 Quack 支持。
启动服务端
先安装带 Quack 扩展的 DuckDB,然后在服务端机器上启动 HTTP 监听:
import duckdb
con = duckdb.connect("analytics.db")
# 加载 Quack 扩展并启动 HTTP 服务端
con.execute("INSTALL quack FROM community")
con.execute("LOAD quack")
con.execute("SELECT quack_start_server('0.0.0.0', 5433)")
服务端会在 0.0.0.0:5433 上监听 HTTP 请求,底层操作的数据库就是 analytics.db。
客户端远程连接
在另一台机器(或同一机器的不同进程)中,客户端通过 HTTP 连接到服务端:
import duckdb
# 客户端连接远程 Quack 服务端
con = duckdb.connect("quack://192.168.1.10:5433")
# 直接执行 SQL,查询在服务端运行,结果返回客户端
result = con.execute("SELECT user_id, COUNT(*) AS cnt FROM events GROUP BY user_id ORDER BY cnt DESC LIMIT 10")
print(result.df())
客户端代码看起来和本地连接几乎一样,只是连接字符串从文件路径变成了 quack://host:port。这是 Quack 的设计目标——让远程访问的代码改动量最小。
用 curl 直接发请求
因为 Quack 走 HTTP,你甚至可以用 curl 快速验证服务端是否正常:
# 发送一条 SQL 查询到 Quack 服务端
curl -X POST http://192.168.1.10:5433/query \
-H "Content-Type: application/json" \
-d '{"sql": "SELECT COUNT(*) FROM events"}'
这种裸 HTTP 调用方式对调试、监控和脚本集成都很方便。
适用场景与边界
Quack 打开了多用户共享 DuckDB 的门,但它并不是要替代 PostgreSQL 或 ClickHouse 的定位。理解它的边界,才能用对地方:
适合的场景: - 数据团队内部共享一份分析数据集,多人用 Python / Jupyter 并发查询。 - BI 工具(如 Metabase、Superset)需要读 DuckDB 数据,但不想把文件拷来拷去。 - 微服务架构中,多个服务需要读同一份冷数据做轻量分析,不想引入重型数据库。
需要注意的限制: - DuckDB 本身的并发写入能力有限,Quack 服务端仍然受此约束。高并发写入场景不是它的强项。 - HTTP 传输意味着每次查询都有网络延迟,对毫秒级低延迟场景不如本地嵌入式合适。 - Quack 是新协议,生态和工具链(连接池、ORM 适配、监控)还在早期阶段。
上手建议
如果你已经在用 DuckDB 做本地分析,想尝试多用户共享,可以按这个清单推进:
- 确认版本兼容:检查你当前 DuckDB 版本是否已发布 Quack 扩展,社区扩展仓库中是否可安装。
- 先在单机测试:在同一台机器上分别跑服务端和客户端进程,验证连接和查询正常后再做跨机器部署。
- 评估并发模式:如果你的场景以读为主、偶尔写入,Quack 很合适;如果写入密集,先做压力测试再决定。
- 网络安全:Quack 目前走 HTTP 无加密,生产部署建议放在内网或前面加 TLS 反向代理(如 nginx)。
- 监控查询耗时:因为引入了网络层,原本本地毫秒级完成的查询可能变成百毫秒级,用
EXPLAIN ANALYZE对比本地和远程的差异。
DuckDB 从嵌入式走向可共享,Quack 是第一步。它没有试图把 DuckDB 变成通用分布式数据库,而是用最轻量的 HTTP 协议解决了"多人想用同一份 DuckDB 数据"这个具体问题。对于已经在 DuckDB 上投入的数据团队,这是一个值得跟进的方向。