S3 表引擎
该引擎提供与 Amazon S3 生态系统的集成能力。此引擎类似于 HDFS 引擎,但提供了 S3 专用功能。
示例
创建表
引擎参数
path— 带有文件路径的存储桶 URL。在只读模式下支持以下通配符:*、**、?、{abc,def}和{N..M},其中N、M为数字,'abc'、'def'为字符串。更多信息参见下文。NOSIGN- 如果在凭证位置提供此关键字,所有请求都不会被签名。format— 文件的格式。aws_access_key_id,aws_secret_access_key- AWS 账号用户的长期凭证。可以使用它们对请求进行认证。该参数为可选。如果未指定凭证,则会从配置文件中读取。更多信息参见 Using S3 for Data Storage。compression— 压缩类型。支持的值:none、gzip/gz、brotli/br、xz/LZMA、zstd/zst。该参数为可选。默认情况下,将根据文件扩展名自动检测压缩类型。partition_strategy– 选项:WILDCARD或HIVE。WILDCARD要求路径中包含{_partition_id},该占位符会被分区键替换。HIVE不允许使用通配符,假定路径为表的根路径,并生成 Hive 风格的分区目录,使用 Snowflake ID 作为文件名,并以文件格式作为扩展名。默认值为WILDCARD。partition_columns_in_data_file- 仅在使用HIVE分区策略时使用。用于指示 ClickHouse 数据文件中是否包含分区列。默认值为false。storage_class_name- 选项:STANDARD或INTELLIGENT_TIERING,用于指定 AWS S3 Intelligent Tiering 存储类别。
数据缓存
S3 表引擎支持在本地磁盘上进行数据缓存。
有关文件系统缓存配置选项和使用方法,请参见本节。
缓存键基于存储对象的路径和 ETag,因此 ClickHouse 不会读取已过期的缓存版本。
要启用缓存,请使用设置 filesystem_cache_name = '<name>' 和 enable_filesystem_cache = 1。
在配置文件中定义缓存有两种方式。
- 在 ClickHouse 配置文件中添加如下配置段:
- 复用 ClickHouse 中
storage_configuration部分的缓存配置(以及相应的缓存存储),如本节所述
PARTITION BY
PARTITION BY — 可选。大多数情况下您不需要分区键,即便需要,一般也不需要比“按月”更细粒度的分区键。分区并不会加快查询速度(与 ORDER BY 表达式相反)。绝不要使用粒度过细的分区。不要按客户端标识符或名称对数据进行分区(而应将客户端标识符或名称设置为 ORDER BY 表达式中的第一列)。
对于按月分区,使用 toYYYYMM(date_column) 表达式,其中 date_column 是类型为 Date 的日期列。此时的分区名称采用 "YYYYMM" 格式。
分区策略
WILDCARD(默认):将文件路径中的 {_partition_id} 通配符替换为实际的分区键。不支持读取操作。
HIVE 实现了用于读写的 Hive 风格分区。读取通过递归的 glob 模式完成,等价于 SELECT * FROM s3('table_root/**.parquet')。
写入会按如下格式生成文件:<prefix>/<key1=val1/key2=val2...>/<snowflakeid>.<toLower(file_format)>。
注意:当使用 HIVE 分区策略时,use_hive_partitioning 设置不会生效。
HIVE 分区策略示例:
查询分区数据
本示例使用了集成 ClickHouse 和 MinIO 的 docker compose 配置示例。你只需替换 endpoint 和认证参数即可在 S3 上复现相同的查询。
请注意,在 ENGINE 配置中,S3 endpoint 将参数占位符 {_partition_id} 用作 S3 对象(文件名)的一部分,而 SELECT 查询则是针对这些生成的对象名称进行查询(例如 test_3.csv)。
如示例所示,目前尚不支持直接从分区的 S3 表中进行查询, 但可以通过使用 S3 表函数分别查询各个分区来实现。
在 S3 中写入分区数据的主要用途,是为了将这些数据迁移到另一套 ClickHouse 系统(例如,从本地部署系统迁移到 ClickHouse Cloud)。由于 ClickHouse 数据集通常非常庞大,且网络可靠性有时并不理想, 因此将数据集拆分为多个子集进行传输是合理的做法,这也正是进行分区写入的原因。
创建表
插入数据
查询分区 3
此查询使用 S3 表函数。
从分区 1 查询数据
从分区 45 中查询数据
限制
你可能很自然地会尝试执行 Select * from p,但如上所述,此查询会失败;请改用前面的查询。
插入数据
请注意,数据行只能插入到新文件中,不会执行合并周期或文件拆分操作。一旦文件写入完成,后续插入将会失败。为避免这种情况,可以使用 s3_truncate_on_insert 和 s3_create_new_file_on_insert 设置。更多详情请参见此处。
虚拟列
_path— 文件的路径。类型:LowCardinality(String)。_file— 文件名。类型:LowCardinality(String)。_size— 文件大小(字节)。类型:Nullable(UInt64)。如果大小未知,则值为NULL。_time— 文件的最后修改时间。类型:Nullable(DateTime)。如果时间未知,则值为NULL。_etag— 文件的 ETag。类型:LowCardinality(String)。如果 ETag 未知,则值为NULL。_tags— 文件的标签。类型:Map(String, String)。如果没有标签,则值为空映射{}。
有关虚拟列的更多信息,请参阅此处`.
实现细节
-
读写操作可以并行进行
-
不支持:
ALTER和SELECT...SAMPLE操作。- 索引。
- 零拷贝 复制在技术上可行,但目前不受支持。
零拷贝复制尚未准备好用于生产环境在 ClickHouse 22.8 及更高版本中,零拷贝复制默认被禁用。该特性不建议在生产环境中使用。
路径中的通配符
path 参数可以使用类似 bash 的通配符来指定多个文件。要参与处理,文件必须实际存在,并且与整个路径模式完全匹配。文件列表在执行 SELECT 时确定(而不是在 CREATE 时)。
*— 匹配任意数量的任意字符(不包括/),可以为空字符串。**— 匹配任意数量的任意字符(包括/),可以为空字符串。?— 匹配任意单个字符。{some_string,another_string,yet_another_one}— 匹配字符串'some_string'、'another_string'、'yet_another_one'中的任意一个。{N..M}— 匹配从 N 到 M 范围内(含两端)的任意数字。N 和 M 可以有前导零,例如000..078。
带有 {} 的写法类似于 remote 表函数。
如果文件列表中包含带前导零的数字范围,请对每一位数字分别使用带花括号的写法,或者使用 ?。
通配符示例 1
创建一个表,使用名为 file-000.csv、file-001.csv、...、file-999.csv 的文件:
带有通配符的示例 2
假设我们有几个 CSV 格式的文件,其在 S3 上的 URI 如下:
- 'https://clickhouse-public-datasets.s3.amazonaws.com/my-bucket/some_folder/some_file_1.csv'
- 'https://clickhouse-public-datasets.s3.amazonaws.com/my-bucket/some_folder/some_file_2.csv'
- 'https://clickhouse-public-datasets.s3.amazonaws.com/my-bucket/some_folder/some_file_3.csv'
- 'https://clickhouse-public-datasets.s3.amazonaws.com/my-bucket/another_folder/some_file_1.csv'
- 'https://clickhouse-public-datasets.s3.amazonaws.com/my-bucket/another_folder/some_file_2.csv'
- 'https://clickhouse-public-datasets.s3.amazonaws.com/my-bucket/another_folder/some_file_3.csv'
有几种方法可以创建一个由这六个文件构成的表:
- 指定文件后缀的范围:
- 将所有带有
some_file_前缀的文件取出(两个文件夹中都不应存在除此之外、带有该前缀的额外文件):
- 将这两个文件夹中的所有文件拿出来(所有文件都应符合查询中描述的格式和架构):
存储设置
- s3_truncate_on_insert - 允许在插入前截断文件。默认禁用。
- s3_create_new_file_on_insert - 当格式带有后缀时,允许在每次插入操作时创建一个新文件。默认禁用。
- s3_skip_empty_files - 允许在读取时跳过空文件。默认启用。
与 S3 相关的设置
以下设置可以在查询执行前进行配置,或写入配置文件。
s3_max_single_part_upload_size— 使用单部分上传到 S3 时,单个对象允许的最大大小。默认值为32Mb。s3_min_upload_part_size— 使用 S3 多部分上传 时,每个分片的最小大小。默认值为16Mb。s3_max_redirects— 允许的 S3 重定向跳转的最大次数。默认值为10。s3_single_read_retries— 单次读操作的最大重试次数。默认值为4。s3_max_put_rps— 在开始限流前,每秒允许的最大 PUT 请求数。默认值为0(无限制)。s3_max_put_burst— 在触及每秒请求数限制前,可以同时发起的最大请求数。默认值为0时,等同于s3_max_put_rps。s3_max_get_rps— 在开始限流前,每秒允许的最大 GET 请求数。默认值为0(无限制)。s3_max_get_burst— 在触及每秒请求数限制前,可以同时发起的最大请求数。默认值为0时,等同于s3_max_get_rps。s3_upload_part_size_multiply_factor- 每当在一次对 S3 的写入中上传了s3_multiply_parts_count_threshold个分片时,将s3_min_upload_part_size按该因子放大。默认值为2。s3_upload_part_size_multiply_parts_count_threshold- 每当向 S3 上传了该数量的分片时,会将s3_min_upload_part_size乘以s3_upload_part_size_multiply_factor。默认值为500。s3_max_inflight_parts_for_one_file- 限制对同一对象可以并发执行的 PUT 请求数。该数量应被限制。值为0表示不限制。默认值为20。每个进行中的分片(in-flight part)都会占用一个缓冲区,对于前s3_upload_part_size_multiply_factor个分片,缓冲区大小为s3_min_upload_part_size;当文件足够大时,缓冲区会更大,详见upload_part_size_multiply_factor。在默认设置下,对于小于8G的文件,单个上传文件占用的内存不超过320Mb。对于更大的文件,占用会更高。
安全注意事项:如果恶意用户可以指定任意 S3 URL,应将 s3_max_redirects 设为 0 以避免 SSRF 攻击;或者在服务器配置中指定 remote_host_filter。
基于 endpoint 的设置
可以在配置文件中为指定的 endpoint 设置以下配置(通过 URL 的精确前缀进行匹配):
endpoint— 指定 endpoint 的前缀。必需项。access_key_id和secret_access_key— 指定用于该 endpoint 的凭证。可选。use_environment_credentials— 如果设置为true,S3 客户端将尝试从环境变量和给定 endpoint 的 Amazon EC2 元数据中获取凭证。可选,默认值为false。region— 指定 S3 区域名。可选。use_insecure_imds_request— 如果设置为true,S3 客户端在从 Amazon EC2 元数据获取凭证时将使用不安全的 IMDS 请求。可选,默认值为false。expiration_window_seconds— 用于检查基于过期时间的凭证是否已失效的宽限时间(秒)。可选,默认值为120。no_sign_request- 忽略所有凭证,使请求不进行签名。用于访问公共存储桶时非常有用。header— 将指定的 HTTP 头添加到对给定 endpoint 的请求中。可选,可以指定多次。access_header- 当不存在来自其他来源的凭证时,将指定的 HTTP 头添加到对给定 endpoint 的请求中。server_side_encryption_customer_key_base64— 如果指定,将为访问使用 SSE-C 加密的 S3 对象设置所需的 HTTP 头。可选。server_side_encryption_kms_key_id- 如果指定,将为访问使用 SSE-KMS 加密 的 S3 对象设置所需的 HTTP 头。如果指定为空字符串,则使用 AWS 托管的 S3 密钥。可选。server_side_encryption_kms_encryption_context- 如果与server_side_encryption_kms_key_id一起指定,将设置给定的 SSE-KMS 加密上下文 HTTP 头。可选。server_side_encryption_kms_bucket_key_enabled- 如果与server_side_encryption_kms_key_id一起指定,将设置启用 SSE-KMS S3 bucket key 的 HTTP 头。可选,可以为true或false,默认不设置(遵循 bucket 级别设置)。max_single_read_retries— 单次读取时的最大重试次数。默认值为4。可选。max_put_rps、max_put_burst、max_get_rps和max_get_burst- 限流设置(参见上文说明),用于特定 endpoint,而不是按查询进行设置。可选。
示例:
使用归档文件
假设我们在 S3 上有若干归档文件,其 URI 如下:
- 'https://s3-us-west-1.amazonaws.com/umbrella-static/top-1m-2018-01-10.csv.zip'
- 'https://s3-us-west-1.amazonaws.com/umbrella-static/top-1m-2018-01-11.csv.zip'
- 'https://s3-us-west-1.amazonaws.com/umbrella-static/top-1m-2018-01-12.csv.zip'
可以使用 :: 从这些归档文件中提取数据。通配模式(glob)既可以用于 URL 的部分,也可以用于 :: 之后的部分(用于指定归档内部文件的名称)。
ClickHouse 支持三种归档格式: ZIP TAR 7Z 虽然可以从任意受支持的存储位置访问 ZIP 和 TAR 归档,但 7Z 归档只能从安装了 ClickHouse 的本地文件系统读取。
访问公共 bucket
ClickHouse 会尝试从多种不同类型的来源自动获取凭证。
有时,在访问某些公共 bucket 时,这可能会导致问题,从而导致客户端返回 403 错误码。
可以通过使用 NOSIGN 关键字来避免这一问题,该关键字会强制客户端忽略所有凭证,不对请求进行签名。
性能优化
如需了解如何优化 s3 函数的性能,请参阅我们的详细指南。