DuckDB 社区扩展仓库来了
前几天我尝试修改DuckDB代码,添加了huggingface.co的镜像支持,让国内的用户也可以方便地访问huggingface超15万的数据集, 其实就是对httpfs插件[1]的修改, 其实可以直接fork并修改duckdb_httpfs更好, 如果有兴趣开发duckdb插件的,可以参考duckdb插件模版(extension-template[2])。
DuckDB 扩展现在可以通过 DuckDB 社区扩展仓库[3] 发布。该仓库使用户可以使用 INSTALL ⟨extension name⟩ FROM community 语法更轻松地安装扩展。扩展开发者无需再为编译和分发而烦恼。
DuckDB 扩展
设计理念
DuckDB 的核心理念之一是 简洁性。这意味着系统应该轻便灵活,尽量减少依赖,并且体积小巧,以便能够在资源受限的平台(如 WebAssembly[4]) 上运行。然而,用户也提出了合理的需求,希望 DuckDB 能够支持更多高级功能,例如空间数据分析、向量索引、与其他数据库的连接、支持更多数据格式等等。当然,我们可以将所有功能都塞进一个单一的二进制文件中,这也是一些系统采取的做法。但我们希望保持 DuckDB 的简洁性。此外,提供所有可能的功能对大多数用户来说是过度的,因为没有哪个用例需要同时使用 所有 扩展(就像“Microsoft Word 悖论”:即使是高级用户也只使用系统中的一小部分功能,而具体使用的功能组合又因人而异)。
为了解决这个问题,DuckDB 引入了一个强大的扩展机制,允许用户根据需要为 DuckDB 添加新功能。该机制支持注册新函数、支持新的文件格式和压缩方法、处理新的网络协议等等。事实上,DuckDB 的许多流行功能都是以扩展的方式实现的,例如:Parquet 读取器[5]、JSON 读取器[6] 和 HTTPS/S3 连接器[7]。
使用扩展
自 0.3.2 版本[8] 起,我们已经通过将扩展托管在一个集中式的仓库中,大大简化了扩展的发现和安装过程。例如,要安装 空间扩展[9],只需使用 DuckDB 的 SQL 接口运行以下命令:
INSTALL spatial;--一次性安装
LOAD spatial;--每次使用时加载在幕后,DuckDB 会下载与当前操作系统和处理器架构相匹配的扩展二进制文件(例如,适用于 ARM64 架构的 macOS 系统),并将其存储在 ~/.duckdb 文件夹中。每次执行 LOAD 命令时,该文件都会被加载到正在运行的 DuckDB 实例中。为了支持这种机制,我们需要为各种处理器架构和操作系统组合编译、签名和托管扩展文件。目前,该机制已被广泛使用,每周的扩展下载量约为 600 万次,数据传输量约为 40 TB!
之前,发布第三方扩展一直是一件 非常麻烦 的事,因为开发者需要为各种平台构建扩展。此外,他们无法使用官方密钥对扩展进行签名,这迫使用户使用 allow_unsigned_extensions 选项禁用签名检查,但这本身就存在安全隐患。
DuckDB 社区扩展
如今,安全地分发软件已经变得非常容易,我们可以通过 pip、conda、cran、npm、brew 等软件包管理工具轻松地将软件分发给广大用户。我们希望为 DuckDB 的用户和开发者提供类似的体验:用户可以轻松地获取他们需要的扩展,而开发者则无需为分发细节而烦恼。我们还希望降低将实用程序和脚本打包成 DuckDB 扩展的门槛,让用户能够轻松地将自己领域的专业知识(或解决特定问题的方案)分享给其他人。
我们相信,构建一个社区扩展生态系统是 DuckDB 发展的必然趋势。因此,我们非常高兴地宣布推出 DuckDB 社区扩展仓库[10],该仓库已在 Data + AI Summit[11] 上正式发布。
对于用户来说,这个仓库可以帮助他们直接在 DuckDB 的 SQL 交互界面中轻松地发现、安装和维护社区扩展。对于开发者来说,它可以大大简化扩展的发布流程。接下来,我们将详细介绍新的扩展仓库如何提升用户和开发者的体验。
用户体验
以 h3 扩展[12] 为例,该扩展为地理空间数据实现了 六角分层地理空间索引[13]。
现在,您可以使用 DuckDB 社区扩展仓库轻松安装和加载 h3 扩展,只需运行以下 SQL 命令:
INSTALL h3 FROM community;
LOAD h3;安装完成后,您可以立即开始使用它。以下示例使用了 500 MB 的样本数据:
SELECT
h3_latlng_to_cell(pickup_latitude, pickup_longitude,9)AS cell_id,
h3_cell_to_boundary_wkt(cell_id)AS boundary,
count()AS cnt
FROM read_parquet('https://blobs.duckdb.org/data/yellow_tripdata_2010-01.parquet')
GROUPBY cell_id
HAVING cnt >10;在加载扩展时,DuckDB 会检查扩展的签名,以确保平台和版本兼容,并验证二进制文件的来源是社区扩展仓库。所有扩展都针对 Linux、macOS、Windows 和 WebAssembly 平台进行了构建、签名和分发。这意味着所有使用 1.0.0 及更高版本的 DuckDB 客户端都可以使用这些扩展。
开发者体验
对于开发者来说,社区扩展仓库可以帮助他们完成发布扩展所需的所有步骤,包括为所有受支持的 [平台]({% link docs/dev/building/supported_platforms.md %}) 构建扩展、对扩展二进制文件进行签名以及将扩展发布到仓库中。
以 h3 扩展的维护者[14] 为例,发布扩展的步骤如下:
1. 创建一个 Pull Request,其中包含一个名为
description.yml的元数据文件,用于描述扩展的信息:extension:
name:h3
description:Hierarchicalhexagonalindexingforgeospatialdata
version:1.0.0
language:C++
build:cmake
license:Apache-2.0
maintainers:
-isaacbrodskyrepo:
github:isaacbrodsky/h3-duckdb
ref:3c8a5358e42ab8d11e0253c70f7cc7d37781b2ef2. CI 系统会自动构建和测试扩展。CI 执行的检查与
extension-template仓库[15] 中的检查一致,因此开发者可以独立地进行迭代开发。3. 等待 DuckDB 社区扩展仓库维护者的批准,并等待构建过程完成。
已发布的扩展
为了验证社区扩展仓库的可行性,我们联系了一些关键扩展的开发者,邀请他们将扩展发布到仓库中。截至本博客文章发布之时,DuckDB 社区扩展仓库中已包含以下扩展。
| 名称 | 描述 |
| crypto[16] | 提供加密哈希函数和 HMAC[17] 支持。 |
| h3[18] | 为地理空间数据提供分层六边形索引。 |
| lindel[19] | 实现线性化/去线性化、Z 阶曲线、希尔伯特曲线和莫顿曲线。 |
| prql[20] | 允许直接在 DuckDB 中运行 PRQL[21] 查询语言。 |
| scrooge[22] | 提供一组用于处理财务数据的聚合函数和数据扫描器。 |
| shellfs[23] | 允许使用 shell 命令进行输入和输出。 |
请注意,DuckDB Labs 和 DuckDB 基金会不对社区扩展中的代码进行审查,因此无法保证社区扩展的安全性。您可以通过以下配置选项禁用社区扩展的加载功能:
SET allow_community_extensions =false;有关更多详细信息,请参阅文档的 保护 DuckDB 页面[24]。
总结和展望
我们介绍了 DuckDB 社区扩展仓库,该仓库旨在方便用户安装和使用第三方 DuckDB 扩展。
我们期待着社区扩展仓库能够不断发展壮大。如果您有创建扩展的想法,可以参考已发布的扩展源代码,从中学习如何打包社区扩展,并加入我们 Discord[25] 上的 #extensions 频道与我们交流。如果您已经开发了一个扩展,欢迎您通过 Pull Request[26] 将其贡献到社区扩展仓库中。
最后,我们要感谢所有早期使用 DuckDB 扩展机制和社区扩展仓库的用户,感谢你们与我们一起探索和改进 DuckDB 的扩展生态。
引用链接
[1] httpfs插件: https://github.com/duckdb/duckdb_httpfs[2] extension-template: https://github.com/duckdb/extension-template[3] DuckDB 社区扩展仓库: https://github.com/duckdb/community-extensions[4] WebAssembly: https://duckdb.org/docs/api/wasm/overview.html[5] Parquet 读取器: https://duckdb.org/docs/data/parquet/overview.html[6] JSON 读取器: https://duckdb.org/docs/extensions/json.html[7] HTTPS/S3 连接器: https://duckdb.org/docs/extensions/httpfs/overview.html[8] 0.3.2 版本: https://github.com/duckdb/duckdb/releases/tag/v0.3.2[9] 空间扩展: https://duckdb.org/docs/extensions/spatial.html[10] DuckDB 社区扩展仓库: https://github.com/duckdb/community-extensions/[11] Data + AI Summit: https://youtu.be/wuP6iEYH11E?t=275[12] h3 扩展: https://github.com/isaacbrodsky/h3-duckdb[13] 六角分层地理空间索引: https://github.com/uber/h3[14] h3 扩展的维护者: https://github.com/isaacbrodsky/[15] extension-template 仓库: https://github.com/duckdb/extension-template[16] crypto: https://github.com/rustyconover/duckdb-crypto-extension[17] HMAC: https://en.wikipedia.org/wiki/HMAC[18] h3: https://github.com/isaacbrodsky/h3-duckdb[19] lindel: https://github.com/rustyconover/duckdb-lindel-extension[20] prql: https://github.com/ywelsch/duckdb-prql[21] PRQL: https://prql-lang.org/[22] scrooge: https://github.com/pdet/Scrooge-McDuck[23] shellfs: https://github.com/rustyconover/duckdb-shellfs-extension[24] 保护 DuckDB 页面: https://duckdb.org/docs/operations_manual/securing_duckdb/securing_extensions.html#community-extension[25] Discord: https://discord.duckdb.org/[26] Pull Request: https://github.com/duckdb/community-extensions/pulls