httpfs
扩展支持使用 S3 API 在对象存储服务器上读取/写入/文件模式匹配文件。S3 提供了一个标准的 API 来读写远程文件(而早于 S3 的普通 HTTP 服务器不提供通用的写入 API)。DuckDB 符合 S3 API,该 API 现在在行业存储提供商中很常见。
平台
httpfs
文件系统已通过 AWS S3、Minio、Google Cloud 和 lakeFS 的测试。其他实现 S3 API 的服务(例如 Cloudflare R2)也应该可用,但并非所有功能都可能受支持。
下表显示了每个 httpfs
功能所需的 S3 API 部分。
功能 | 所需的 S3 API 功能 |
---|---|
公共文件读取 | HTTP Range 请求 |
私有文件读取 | 密钥或会话令牌身份验证 |
文件模式匹配 | ListObjectsV2 |
文件写入 | 分段上传 |
配置和身份验证
配置和验证 S3 端点的首选方法是使用密钥。有多个密钥提供程序可用。
要从已废弃的 S3 API 迁移,请使用具有配置文件的已定义密钥。请参阅“根据配置文件加载密钥”部分。
config
提供程序
默认提供程序 config
(即用户配置),允许通过手动提供密钥来访问 S3 存储桶。例如
CREATE OR REPLACE SECRET secret (
TYPE s3,
PROVIDER config,
KEY_ID 'AKIAIOSFODNN7EXAMPLE',
SECRET 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
REGION 'us-east-1'
);
提示 如果您遇到 IO 错误(
Connection error for HTTP HEAD
),请通过ENDPOINT 's3.your_region.amazonaws.com'
显式配置端点。
现在,要使用上述密钥进行查询,只需查询任何以 s3://
为前缀的文件即可
SELECT *
FROM 's3://your-bucket/your_file.parquet';
credential_chain
提供者
credential_chain
提供程序允许使用 AWS SDK 提供的机制自动获取凭证。例如,要使用 AWS SDK 默认提供程序
CREATE OR REPLACE SECRET secret (
TYPE s3,
PROVIDER credential_chain
);
同样,要使用上述密钥查询文件,只需查询任何以 s3://
为前缀的文件即可。
DuckDB 还允许使用 CHAIN
关键字指定特定的链。这需要一个以分号分隔的提供程序列表(a;b;c
),这些提供程序将按顺序尝试。例如
CREATE OR REPLACE SECRET secret (
TYPE s3,
PROVIDER credential_chain,
CHAIN 'env;config'
);
CHAIN
的可能值如下
credential_chain
提供程序还允许覆盖自动获取的配置。例如,要自动加载凭证,然后覆盖区域,请运行
CREATE OR REPLACE SECRET secret (
TYPE s3,
PROVIDER credential_chain,
CHAIN config,
REGION 'eu-west-1'
);
根据配置文件加载密钥
要根据未从 AWS_PROFILE
环境变量定义为默认值或未根据 AWS SDK 优先级定义为默认配置文件的配置文件加载凭证,请运行
CREATE OR REPLACE SECRET secret (
TYPE s3,
PROVIDER credential_chain,
CHAIN config,
PROFILE 'my_profile'
);
此方法等同于已废弃的 S3 API 的 load_aws_credentials('⟨my_profile⟩')
方法。
S3 密钥参数概述
下面是 config
和 credential_chain
提供程序都支持的参数的完整列表
名称 | 描述 | 密钥 | 类型 | 默认值 |
---|---|---|---|---|
ENDPOINT |
指定自定义 S3 端点 | S3 、GCS 、R2 |
字符串 |
S3 的 s3.amazonaws.com , |
KEY_ID |
要使用的密钥 ID | S3 、GCS 、R2 |
字符串 |
- |
REGION |
要进行身份验证的区域(应与要查询的存储桶的区域匹配) | S3 、GCS 、R2 |
字符串 |
us-east-1 |
SECRET |
要使用的密钥 | S3 、GCS 、R2 |
字符串 |
- |
SESSION_TOKEN |
可选地,可以传递会话令牌以使用临时凭证 | S3 、GCS 、R2 |
字符串 |
- |
URL_COMPATIBILITY_MODE |
当 URL 包含有问题字符时有帮助 | S3 、GCS 、R2 |
布尔值 |
true |
URL_STYLE |
vhost 或 path |
S3 、GCS 、R2 |
字符串 |
S3 为 vhost ,R2 和 GCS 为 path |
USE_SSL |
是否使用 HTTPS 或 HTTP | S3 、GCS 、R2 |
布尔值 |
true |
ACCOUNT_ID |
用于生成端点 URL 的 R2 账户 ID | R2 |
字符串 |
- |
KMS_KEY_ID |
用于 S3 服务器端加密的 AWS KMS(密钥管理服务)密钥 | S3 |
字符串 |
- |
平台特定的密钥类型
S3 密钥
httpfs 扩展支持使用 KMS_KEY_ID
选项在 S3 上通过 AWS 密钥管理服务 (KMS) 进行服务器端加密。
CREATE OR REPLACE SECRET secret (
TYPE s3,
PROVIDER credential_chain,
CHAIN config,
REGION 'eu-west-1',
KMS_KEY_ID 'arn:aws:kms:region:account_id:key/key_id',
SCOPE 's3://bucket-sub-path'
);
R2 密钥
尽管 Cloudflare R2 使用常规的 S3 API,但 DuckDB 有一个特殊的密钥类型 R2
,以使其配置更简单一些。
CREATE OR REPLACE SECRET secret (
TYPE r2,
KEY_ID 'AKIAIOSFODNN7EXAMPLE',
SECRET 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
ACCOUNT_ID 'my_account_id'
);
请注意新增的 ACCOUNT_ID
,它用于为您生成正确的端点 URL。另请注意,R2
密钥也可以使用 CONFIG
和 credential_chain
提供程序。然而,由于 DuckDB 内部使用 AWS 客户端,当使用 credential_chain
时,客户端将在标准 AWS 凭证位置(环境变量、凭证文件等)中搜索 AWS 凭证。因此,您的 R2 凭证必须以 AWS 环境变量(AWS_ACCESS_KEY_ID
和 AWS_SECRET_ACCESS_KEY
)的形式提供,以使凭证链正常工作。最后,R2
密钥仅在 URL 以 r2://
开头时可用,例如
SELECT *
FROM read_parquet('r2://some-file-that-uses-an-r2-secret.parquet');
GCS 密钥
尽管 DuckDB 使用 S3 API 访问 Google Cloud Storage,但 DuckDB 有一个特殊的密钥类型 GCS
,以使其配置更简单一些。
CREATE OR REPLACE SECRET secret (
TYPE gcs,
KEY_ID 'my_hmac_access_id',
SECRET 'my_hmac_secret_key'
);
重要提示:KEY_ID
和 SECRET
值必须是专为 Google Cloud Storage 互操作性生成的 HMAC 密钥。这些密钥与常规 GCP 服务账户密钥或访问令牌不同。您可以按照Google Cloud 关于管理 HMAC 密钥的文档创建 HMAC 密钥。
请注意,上述密钥将自动配置正确的 Google Cloud Storage 端点。另请注意,GCS
密钥也可以使用 CONFIG
和 credential_chain
提供程序。然而,由于 DuckDB 内部使用 AWS 客户端,当使用 credential_chain
时,客户端将在标准 AWS 凭证位置(环境变量、凭证文件等)中搜索 AWS 凭证。因此,您的 GCS HMAC 密钥必须以 AWS 环境变量(AWS_ACCESS_KEY_ID
和 AWS_SECRET_ACCESS_KEY
)的形式提供,以使凭证链正常工作。最后,GCS
密钥仅在 URL 以 gcs://
或 gs://
开头时可用,例如
SELECT *
FROM read_parquet('gcs://some/file/that/uses/a/gcs/secret.parquet');
读取
现在,从 S3 读取文件就像这样简单
SELECT *
FROM 's3://your-bucket/filename.extension';
部分读取
httpfs
扩展支持从 S3 存储桶进行部分读取。
读取多个文件
也可以处理多个文件,例如
SELECT *
FROM read_parquet([
's3://your-bucket/filename-1.parquet',
's3://your-bucket/filename-2.parquet'
]);
文件模式匹配
文件模式匹配是使用 ListObjectsV2 API 调用实现的,允许使用类似文件系统的 glob 模式来匹配多个文件,例如
SELECT *
FROM read_parquet('s3://your-bucket/*.parquet');
此查询匹配存储桶根目录中所有带有Parquet 扩展名的文件。
支持多种匹配功能,例如 *
匹配任意数量的任意字符,?
匹配任意单个字符,或 [0-9]
匹配指定范围内的单个字符。
SELECT count(*) FROM read_parquet('s3://your-bucket/folder*/100?/t[0-9].parquet');
使用 glob 时一个有用的功能是 filename
选项,它会添加一个名为 filename
的列,该列编码了特定行来自的文件。
SELECT *
FROM read_parquet('s3://your-bucket/*.parquet', filename = true);
例如,这可能会导致
column_a | column_b | 文件名 |
---|---|---|
1 | examplevalue1 | s3://bucket-name/file1.parquet |
2 | examplevalue1 | s3://bucket-name/file2.parquet |
Hive 分区
DuckDB 还支持 Hive 分区方案,在使用 HTTP(S) 和 S3 端点时可用。
写入
写入 S3 使用分段上传 API。这使得 DuckDB 能够以高速稳定地上传文件。写入 S3 适用于 CSV 和 Parquet 格式。
COPY table_name TO 's3://your-bucket/filename.extension';
分区复制到 S3 也适用。
COPY table TO 's3://your-bucket/partitioned' (
FORMAT parquet,
PARTITION_BY (part_col_a, part_col_b)
);
系统会对现有文件/目录进行自动检查,目前这相当保守(并且在 S3 上会增加一些延迟)。要禁用此检查并强制写入,请添加 OVERWRITE_OR_IGNORE
标志。
COPY table TO 's3://your-bucket/partitioned' (
FORMAT parquet,
PARTITION_BY (part_col_a, part_col_b),
OVERWRITE_OR_IGNORE true
);
写入文件的命名方案如下所示
s3://your-bucket/partitioned/part_col_a=val/part_col_b=val/data_thread_number.parquet
配置
S3 上传还有一些额外的配置选项,尽管默认值应足以满足大多数用例。
名称 | 描述 |
---|---|
s3_uploader_max_parts_per_file |
用于部分大小计算,请参阅AWS 文档 |
s3_uploader_max_filesize |
用于部分大小计算,请参阅AWS 文档 |
s3_uploader_thread_limit |
最大上传线程数 |