开发者生态
morning
Quack:DuckDB 客户端-服务器协议
2026-05-12
1 阅读
aduffy
Quack:DuckDB 客户端-服务器协议 DuckDB 团队 2026-05-12 · 20 分钟 TL;DR:DuckDB 实例现在可以使用 Quack 远程协议相互通信。这使您可以在具有多个并发写入器的客户端-服务器设置中运行 DuckDB。秉承 DuckDB 的精神,Quack 易于设置,并且基于 HTTP 等成熟技术构建。它的速度也很快,这使得它能够支持从批量操作到小型事务的工作负载。背景:数据库架构当数据库刚出现时,没有“客户端”和“服务器”之间的区别,整个数据库只是在一台计算机上运行。在 80 年代的某个时候,Sybase 第一个引入了运行在不同计算机上的数据库“服务器”和“客户端”的概念。从那时起,人们就假设每个数据库系统都使用客户端-服务器架构以及在这些系统之间进行通信的通信协议。这很方便,因为单个可变状态保留在服务器控制下的单个位置,并且可以有许多客户端同时读取和写入数据。当然,这种方法也有缺点,最值得注意的是,这些协议会增加大量的开销。如果您想了解更多信息,我们不久前写了一篇关于数据库协议的研究论文。当然,对客户端/服务器架构总是有异议,最引人注目的是 2000 年无处不在的 SQLite,当然还有 2019 年首次发布的 DuckDB。我们对实现进程内架构发出了很多噪音,其中没有客户端/服务器,没有协议,只有低级 API 调用。这对于数据科学等交互式用例非常有效,分析师可以在 Python 笔记本中与他们的数据进行交互,并且他们的数据在运行在同一进程中的 DuckDB 实例中进行管理。它对于 DuckDB 只是“粘合”到现有应用程序以针对该应用程序中的数据提供 SQL 功能的许多用例也非常有效。当尝试同时从多个进程修改同一数据库文件时,进程内系统对于用例来说效果“不太好”。有很多用例与此相关,例如,当从一组收集遥测数据的进程插入同一数据库时,同时查询相同的表以驱动仪表板。我们无法完成这项工作有很好的技术原因,最值得注意的是,DuckDB 在主内存中保留了一堆状态,如果多个进程同时开始进行更改,则必须同步该状态。是的,有解决方法。当然,您可以创建一个自定义远程过程调用 (RPC) 解决方案,其中有一个进程保存 DuckDB 数据库实例并向其他进程提供查询和插入数据的服务。还有多个项目可以改进 DuckDB 的客户端/服务器功能,例如使用 Arrow Flight SQL 协议。 MotherDuck 有自己的自定义客户端-服务器协议。当然,您始终可以(喘息)切换到具有客户端-服务器支持的更传统的数据库系统,例如同样无处不在的 PostgreSQL。然后,您甚至可以继续运行所谓的“EleDucken”,即 PostgreSQL 中的 DuckDB,使用支持此功能的各种扩展之一,例如 pg_duckdb 。人们为将客户端-服务器解决方案附加到 DuckDB 上而构建的大量解决方法至少让我们相信这是人们关心的事情。我们将 DuckDB 视为通用数据整理工具。如果这意味着除了进程内功能之外还拥有客户端-服务器协议 – 很好。如果这最终解锁了 DuckDB 可以发挥作用的大量新案例 – 那就太棒了!最后,我们非常关心用户体验,也许不太关心对架构的最终决定权。所以我们最终硬着头皮,今天我们非常高兴地宣布结果:为 DuckDB 引入 Quack 协议 如果两只(或更多)鸭子想要互相交谈,它们会做什么?他们嘎嘎叫!因此,很自然地,我们也需要将两个 DuckDB 实例用于相互通信的协议称为“Quack”!我们有机会在 2026 年从头开始设计一个数据库协议,而不必考虑任何遗留问题,这是相当奢侈的。我们能够从现有协议中学习,包括最新的 Arrow Flight SQL 和其他协议。在我们深入了解 Quack 的内部工作原理之前,让我们从用户的角度看看它是如何工作的。首先,您需要两个 DuckDB 实例。没错,DuckDB 既充当客户端又充当服务器!这两个实例可以位于相距遥远(或在太空中)的不同计算机上,也可以位于笔记本电脑上的两个不同终端窗口上。首先,我们需要在两个 DuckDB 实例中安装 Quack 扩展。目前,Quack 位于 core_nightly 存储库中,并可在当前版本的 DuckDB v1.5.2 中使用。