DuckDB 不再只做嵌入式:Quack 协议让多客户端通过 HTTP 共享同一个数据库

2026-05-31 28 预计阅读时间:1 分钟
来源:infoq.com AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:8 分钟

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 做本地分析,想尝试多用户共享,可以按这个清单推进:

  1. 确认版本兼容:检查你当前 DuckDB 版本是否已发布 Quack 扩展,社区扩展仓库中是否可安装。
  2. 先在单机测试:在同一台机器上分别跑服务端和客户端进程,验证连接和查询正常后再做跨机器部署。
  3. 评估并发模式:如果你的场景以读为主、偶尔写入,Quack 很合适;如果写入密集,先做压力测试再决定。
  4. 网络安全:Quack 目前走 HTTP 无加密,生产部署建议放在内网或前面加 TLS 反向代理(如 nginx)。
  5. 监控查询耗时:因为引入了网络层,原本本地毫秒级完成的查询可能变成百毫秒级,用 EXPLAIN ANALYZE 对比本地和远程的差异。

DuckDB 从嵌入式走向可共享,Quack 是第一步。它没有试图把 DuckDB 变成通用分布式数据库,而是用最轻量的 HTTP 协议解决了"多人想用同一份 DuckDB 数据"这个具体问题。对于已经在 DuckDB 上投入的数据团队,这是一个值得跟进的方向。


相关推荐