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 帐户用户的长期凭据。您可以将其用于身份验证请求。该参数是可选的。如果未指定凭据,则将使用配置文件中的凭据。有关更多信息,请参见 使用 S3 存储数据。compression
— 压缩类型。支持的值:none
、gzip/gz
、brotli/br
、xz/LZMA
、zstd/zst
。该参数为可选项。默认情况下,它将根据文件扩展名自动检测压缩。partition_strategy
– 选项:WILDCARD
或HIVE
。WILDCARD
需要在路径中包含{_partition_id}
,并替换为分区键。HIVE
不允许使用通配符,假定路径为表的根,并生成带有 Snowflake ID 作为文件名并以文件格式作为扩展名的 Hive 风格分区目录。默认为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
— 可选。在大多数情况下,您不需要分区键,如果需要,通常不需要比按月更细粒度的分区。分区不会加快查询速度(与 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
分区策略的示例:
查询分区数据
该示例使用 docker compose 配方,集成了 ClickHouse 和 MinIO。您应该能够通过替换端点和身份验证值来重现相同的查询。
请注意,ENGINE
配置中的 S3 端点使用了参数令牌 {_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
。
有关虚拟列的更多信息,请参见 这里。
实现细节
-
读取和写入可以并行进行。
-
不支持:
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
假设我们在 S3 上有几个 CSV 格式的文件,其 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
部分每次乘以此因子。默认值为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
。每个在途部分的缓冲区大小为s3_min_upload_part_size
,前s3_upload_part_size_multiply_factor
个部分适用,文件较大时则更多,见upload_part_size_multiply_factor
。使用默认设置时,一个上传的文件在小于8G
的情况下最多消耗320Mb
。较大文件的消耗则更大。
安全考虑:如果恶意用户可以指定任意 S3 URL,则 s3_max_redirects
必须设置为零,以避免 SSRF 攻击;或者在服务器配置中另行指定 remote_host_filter
。
基于端点的设置
以下设置可以在配置文件中为给定的端点指定(将通过 URL 的精确前缀进行匹配):
endpoint
— 指定端点的前缀。必填。access_key_id
和secret_access_key
— 指定给定端点可用的凭据。可选。use_environment_credentials
— 如果设置为true
,S3 客户端将尝试从环境变量和 Amazon EC2 元数据中获取凭据。可选,默认值为false
。region
— 指定 S3 区域名称。可选。use_insecure_imds_request
— 如果设置为true
,S3 客户端在从 Amazon EC2 元数据中获取凭据时将使用不安全的 IMDS 请求。可选,默认值为false
。expiration_window_seconds
— 检查以过期为基础的凭据是否已过期的宽限期。可选,默认值为120
。no_sign_request
- 忽略所有凭据,因此请求不被签名。适用于访问公共存储桶。header
— 在请求添加指定的 HTTP 头到给定的端点。可选,可以多次指定。access_header
- 在请求添加指定的 HTTP 头到给定的端点,当没有其他来源的凭据时。server_side_encryption_customer_key_base64
— 如果指定,则将设置访问 S3 对象所需的 SSE-C 加密所需的头。可选。server_side_encryption_kms_key_id
- 如果指定,则将设置访问 S3 对象所需的 SSE-KMS 加密 所需的头。如果指定空字符串,则将使用 AWS 管理的 S3 密钥。可选。server_side_encryption_kms_encryption_context
- 如果与server_side_encryption_kms_key_id
一起指定,则将设置 SSE-KMS 的给定加密上下文头。可选。server_side_encryption_kms_bucket_key_enabled
- 如果与server_side_encryption_kms_key_id
一起指定,则将设置启用 SSE-KMS 的 S3 存储桶密钥的头。可选,可以为true
或false
,默认为无(匹配存储桶级别的设置)。max_single_read_retries
— 单次读取的最大尝试次数。默认值为4
。可选。max_put_rps
、max_put_burst
、max_get_rps
和max_get_burst
- 用于特定端点而不是每个查询的节流设置(见上文描述)。可选。
示例:
处理档案
假设我们在 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'
使用 :: 提取这些档案中的数据是可能的。Globs 可以在 URL 部分以及 :: 后的部分(负责档案内文件的名称)使用。
ClickHouse 支持三种档案格式: ZIP TAR 7Z 虽然 ZIP 和 TAR 档案可以从任何支持的存储位置访问,但 7Z 档案只能从安装 ClickHouse 的本地文件系统读取。
访问公共存储桶
ClickHouse 尝试从许多不同类型的来源获取凭据。
有时,访问某些公共存储桶时可能会出现问题,导致客户端返回 403
错误代码。
通过使用 NOSIGN
关键字,可以避免此问题,从而强制客户端忽略所有凭据,并且不签署请求。
优化性能
有关优化 S3 功能性能的详细信息,请参见 我们的详细指南。