S3 表引擎

这个引擎提供与Amazon S3生态系统的集成。这个引擎类似于HDFS引擎,但提供了 S3 特有的功能。

创建表

  1. CREATE TABLE s3_engine_table (name String, value UInt32)
  2. ENGINE = S3(path, [aws_access_key_id, aws_secret_access_key,] format, [compression])

引擎参数

  • path — 带有文件路径的 Bucket url。在只读模式下支持以下通配符: *, ?, {abc,def}{N..M} 其中 N, M 是数字, 'abc', 'def' 是字符串. 更多信息见下文.
  • format — 文件的格式.
  • aws_access_key_id, aws_secret_access_key - AWS 账号的长期凭证. 你可以使用凭证来对你的请求进行认证.参数是可选的. 如果没有指定凭据, 将从配置文件中读取凭据. 更多信息参见 使用 S3 来存储数据.
  • compression — 压缩类型. 支持的值: none, gzip/gz, brotli/br, xz/LZMA, zstd/zst. 参数是可选的. 默认情况下,通过文件扩展名自动检测压缩类型.

示例

  1. 创建 s3_engine_table 表:
  1. CREATE TABLE s3_engine_table (name String, value UInt32) ENGINE=S3('https://storage.yandexcloud.net/my-test-bucket-768/test-data.csv.gz', 'CSV', 'gzip');
  1. 填充文件:
  1. INSERT INTO s3_engine_table VALUES ('one', 1), ('two', 2), ('three', 3);
  1. 查询数据:
  1. SELECT * FROM s3_engine_table LIMIT 2;
  1. ┌─name─┬─value─┐
  2. one 1
  3. two 2
  4. └──────┴───────┘

虚拟列

  • _path — 文件路径.
  • _file — 文件名.

有关虚拟列的更多信息,见 这里.

实施细节

  • 读取和写入可以是并行的
  • 以下是不支持的:
    • ALTERSELECT...SAMPLE 操作.
    • 索引.
    • 复制.

路径中的通配符

path 参数可以使用类 bash 的通配符来指定多个文件。对于正在处理的文件应该存在并匹配到整个路径模式。 文件列表的确定是在 SELECT 的时候进行(而不是在 CREATE 的时候)。

  • * — 替代任何数量的任何字符,除了 / 以及空字符串。
  • ? — 代替任何单个字符.
  • {some_string,another_string,yet_another_one} — 替代 'some_string', 'another_string', 'yet_another_one'字符串.
  • {N..M} — 替换 N 到 M 范围内的任何数字,包括两个边界的值. N 和 M 可以以 0 开头,比如 000..078

{} 的结构类似于 远程 表函数。

示例

  1. 假设我们在 S3 上有几个 CSV 格式的文件,URI如下:

有几种方法来创建由所有六个文件组成的数据表:

第一种方式:

  1. CREATE TABLE table_with_range (name String, value UInt32) ENGINE = S3('https://storage.yandexcloud.net/my-test-bucket-768/{some,another}_prefix/some_file_{1..3}', 'CSV');

另一种方式:

  1. CREATE TABLE table_with_question_mark (name String, value UInt32) ENGINE = S3('https://storage.yandexcloud.net/my-test-bucket-768/{some,another}_prefix/some_file_?', 'CSV');

表由两个目录中的所有文件组成(所有文件应满足查询中描述的格式和模式)。

  1. CREATE TABLE table_with_asterisk (name String, value UInt32) ENGINE = S3('https://storage.yandexcloud.net/my-test-bucket-768/{some,another}_prefix/*', 'CSV');

如果文件列表中包含有从零开头的数字范围,请对每个数字分别使用带括号的结构,或者使用?

示例

使用文件file-000.csv, file-001.csv, … , file-999.csv来创建表:

  1. CREATE TABLE big_table (name String, value UInt32) ENGINE = S3('https://storage.yandexcloud.net/my-test-bucket-768/big_prefix/file-{000..999}.csv', 'CSV');

虚拟列

  • _path — 文件路径.
  • _file — 文件名.

另请参阅

S3 相关的设置

以下设置可以在查询执行前设置,也可以放在配置文件中。

  • s3_max_single_part_upload_size - 使用单文件上传至 S3 的对象的最大文件大小。默认值是64Mb
  • s3_min_upload_part_size - 使用S3多文件块上传时,文件块的最小文件大小。默认值是512Mb
  • s3_max_redirects - 允许的最大S3重定向跳数。默认值是10
  • s3_single_read_retries - 单次读取时的最大尝试次数。默认值是4

安全考虑:如果恶意用户可以指定任意的 S3 网址,s3_max_redirects参数必须设置为零,以避免SSRF攻击;或者,必须在服务器配置中指定remote_host_filter

基于 Endpoint 的设置

在配置文件中可以为给定的端点指定以下设置(将通过URL的准确前缀来匹配)。

  • endpoint - 指定一个端点的前缀。必要参数。
  • access_key_idsecret_access_key - 用于指定端点的登陆凭据。可选参数。
  • use_environment_credentials - 如果设置为true,S3客户端将尝试从环境变量和Amazon EC2元数据中为指定的端点获取证书。可选参数,默认值是false
  • region - 指定S3的区域名称。可选参数。
  • use_insecure_imds_request - 如果设置为true,S3客户端将使用不安全的 IMDS 请求,同时从Amazon EC2 元数据获取证书。可选参数,默认值是false
  • header - 添加指定的HTTP头到给定端点的请求中。可选参数,可以使用多次此参数来添加多个值。
  • server_side_encryption_customer_key_base64 - 如果指定,需要指定访问 SSE-C 加密的 S3 对象所需的头信息。可选参数。
  • max_single_read_retries - 单次读取时的最大尝试次数。默认值是4。可选参数。

示例:

  1. <s3>
  2. <endpoint-name>
  3. <endpoint>https://storage.yandexcloud.net/my-test-bucket-768/</endpoint>
  4. <!-- <access_key_id>ACCESS_KEY_ID</access_key_id> -->
  5. <!-- <secret_access_key>SECRET_ACCESS_KEY</secret_access_key> -->
  6. <!-- <region>us-west-1</region> -->
  7. <!-- <use_environment_credentials>false</use_environment_credentials> -->
  8. <!-- <use_insecure_imds_request>false</use_insecure_imds_request> -->
  9. <!-- <header>Authorization: Bearer SOME-TOKEN</header> -->
  10. <!-- <server_side_encryption_customer_key_base64>BASE64-ENCODED-KEY</server_side_encryption_customer_key_base64> -->
  11. <!-- <max_single_read_retries>4</max_single_read_retries> -->
  12. </endpoint-name>
  13. </s3>

用法

假设我们在 S3 上有几个 CSV 格式的文件,URI 如下:

  1. 有几种方式来制作由所有六个文件组成的表格,其中一种方式如下:
  1. CREATE TABLE table_with_range (name String, value UInt32)
  2. ENGINE = S3('https://storage.yandexcloud.net/my-test-bucket-768/{some,another}_prefix/some_file_{1..3}', 'CSV');
  1. 另一种方式:
  1. CREATE TABLE table_with_question_mark (name String, value UInt32)
  2. ENGINE = S3('https://storage.yandexcloud.net/my-test-bucket-768/{some,another}_prefix/some_file_?', 'CSV');
  1. 表由两个目录中的所有文件组成(所有文件应满足查询中描述的格式和模式):
  1. CREATE TABLE table_with_asterisk (name String, value UInt32)
  2. ENGINE = S3('https://storage.yandexcloud.net/my-test-bucket-768/{some,another}_prefix/*', 'CSV');

Warning

如果文件列表中包含有从0开头的数字范围,请对每个数字分别使用带括号的结构,或者使用?.

  1. 从文件file-000.csv, file-001.csv, … , file-999.csv创建表:
  1. CREATE TABLE big_table (name String, value UInt32)
  2. ENGINE = S3('https://storage.yandexcloud.net/my-test-bucket-768/big_prefix/file-{000..999}.csv', 'CSV');

另请参阅