试一试Ducklake

试一试Ducklake

八月 21, 2025

在上一篇文章中,我们一起体验了 DuckDB 的跨数据源查询。今天我将为各位介绍一个 DuckDB 生态中,另一个有意思的成员:DuckLake

以下是来自官方的简要说明:

  • DuckLake is an integrated data lake and catalog format
  • DuckLake delivers advanced data lake features without traditional lakehouse complexity by using Parquet files and your SQL database. It’s an open, standalone format from the DuckDB team.

  • DuckLake 整合了数据湖和数据目录的格式
  • DuckLake 利用 Parquet 数据问题件,提供了数据湖才有的一些高级功能,且不会带来额外的技术复杂性

DuckLake 提供的主要功能有:

  • 数据湖相关的操作:支持数据快照,时间旅行查询(time travel queries),库表演进(schema evolution)
  • 支持大量轻量级快照
  • ACID事务
  • filter pushdown

对于有 Iceberg 使用经验的人来说,这是很好理解的,因为两者可以类比,都是定义了一种统一的用于组织数据的格式。对于没有这方面经验的,建议通过自己的实践去理解它到底是什么。毕竟,单纯通过文字来解释概念是很苍白的。

值得注意的是,DuckLake format 现在才发布了 0.2 版本,因此它仍然是处于快速进化之中。

接下来,我将演示如何通过在 DuckDB 中,借助 DuckLake 扩展,来对 S3 (比如,阿里云OSS) 上的数据进行查询、修改、快照查询。

DuckLake extension

进入 duckdb 的命令行后,直接安装即可:

1
INSTALL ducklake;

详细文档,可自行前往:DuckLake extension

S3 extension

S3 的访问能力,其实是由 httpfs extension 提供的,因此不需要单独安装。

这里主要演示如何连接到 阿里云OSS bucket:

1
2
3
4
5
6
7
8
CREATE OR REPLACE SECRET s3_secret (
TYPE s3,
PROVIDER config,

ENDPOINT 's3.oss-cn-beijing.aliyuncs.com',
KEY_ID 'access-key',
SECRET 'secret-key'
);

请将上述代码中的 access-keysecret-key 替换为具有 OSS bucket 读写权限的 RAM 账号 的 Access Key。

此时,建议往 bucket 上面丢一个文件去验证访问是正常的,比如,我上传了一个 parquet 文件到根路径下:

对该文件进行查询:

需要特别注意的是, 我们在创建 S3 secret 时,使用的是 PROVIDER config,它的作用是,当遇到 s3: 协议的 http 文件,默认就使用这个 secret。

配置 DuckLake 数据源

在 S3 访问没问题后,我们就可以接着配 DuckLake 数据源了:

1
2
3
4
5
CREATE OR REPLACE SECRET ducklake_secret (
TYPE DUCKLAKE,
METADATA_PATH 'vldl_metadata.db',
DATA_PATH 's3://viclau-ducklake/'
);

DuckLake 的数据源信息分为两部分:

  • 第一部分是 metadata, 即 DuckLake format 数据存的位置
  • 第二部分是 数据表内的数据 要存在哪里

由于这里仅仅是做演示,所以方便起见,直接将 metadata 以 duckdb 单文件的方式进行存储。而数据部分,是存在 S3 bucket 上的。

正式项目使用的话,metadata 一定要存在可靠的数据库系统中,比如 pg 当中:

1
2
3
4
5
6
7
INSTALL ducklake;
INSTALL postgres;

-- Make sure that the database `ducklake_catalog` exists in PostgreSQL.
ATTACH 'ducklake:postgres:dbname=ducklake_catalog host=localhost' AS my_ducklake
(DATA_PATH 'data_files/');
USE my_ducklake;

创建好 secret 后,通过这个 secret 连接数据源:

1
2
ATTACH 'ducklake:ducklake_secret' AS vldl;
USE vldl;

DuckLake 的功能演示

按顺序执行以下命令。

  1. 利用 CTAS 往 S3 建一张表
1
CREATE TABLE nl_train_stations AS FROM 'https://blobs.duckdb.org/nl_stations.csv';
  1. 修改一条数据
1
UPDATE nl_train_stations SET name_long='Johan Cruijff ArenA' WHERE code = 'ASB';
  1. 查询不同版本的数据

解读如下:

  • from nl_train_stations select name_long where code = 'ASB' 常规 SQL 查询,因此返回最新的数据
  • from nl_train_stations at (version => 2) select name_long where code = 'ASB' 查询快照版本 2, 由于这个库最新的版本就是2, 所以跟上面的查询结果相同
  • from nl_train_stations at (version => 1) select name_long where code = 'ASB' 查询快照版本 1, 所以返回修改之前的数据
  1. snapshots 解密

通过 snapshots,会告诉我们整个库有多少个快照版本,每个版本对应的 schema 是什么,做了什么改动。

  1. ducklake 使用的是 Parquet

刚刚通过 CTAS 创建的表,落到 S3 后,文件格式确实是 Parquet 。

总结

通过简单的示例,我们体验了如何从 S3 上查询 parquet 文件,以及很方便的通过 at (version => ...) 来查询快照数据。更多用法,各位可以自行导航到 DuckLake 去了解更多。

更有价值的是,DuckLake + S3 为我们解决了分布式存储的问题。但由于 DuckDB 本身是一个 embedding db,计算能力还是仅限于在单机内的,不知道将来是否会出现分布式的duckdb查询呢? 如果有,那么,它就真的成了存算分离的、且非常轻量的,可运用于正式项目的利器了。