DuckDB Quack:让嵌入式数据库走向多用户网络协作

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

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

预计阅读时间:7 分钟

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 引入工作流,可以按这个清单推进:

  1. 先确认场景:团队是否真的需要多人同时查询同一份 DuckDB 数据?如果只是偶尔共享,拷贝文件可能更简单。
  2. 网络安全先行:Quack 默认走 HTTP 而非 HTTPS,生产环境务必叠加反向代理(如 Nginx)做 TLS 终结和基本认证。
  3. 读写分离设计:写操作集中在少数管道任务,读操作通过 Quack 服务分发。避免多个客户端同时大批量 INSERT。
  4. 监控服务进程:DuckDB 作为服务器进程需要守护(systemd 或容器),并监控内存与查询耗时。
  5. 保留嵌入式回退路径:本地开发和单用户场景继续用嵌入式模式,只在需要共享时才切换到 Quack。

Quack 的意义不在于让 DuckDB 变成"又一个 PostgreSQL",而是让一个原本只能在进程内使用的分析引擎,获得了低门槛的网络共享能力。对于已经在用 DuckDB 做本地分析的团队来说,这是一条最小代价的协作升级路径。


相关推荐