用于存储数据的外部磁盘
在 ClickHouse 中处理的数据通常存储在运行 ClickHouse 服务器的 机器的本地文件系统中。这需要大容量磁盘,而这可能比较昂贵。为了避免在本地存储数据,ClickHouse 支持多种存储选项:
- Amazon S3 对象存储。
- Azure Blob Storage。
- 不受支持:Hadoop 分布式文件系统(HDFS)
ClickHouse 还支持外部表引擎,它们与本页所描述的外部存储选项不同,因为这些引擎允许读取以通用文件格式(例如 Parquet)存储的数据。本页描述的是 ClickHouse MergeTree 系列表或 Log 系列表的存储配置。
- 要处理存储在
Amazon S3磁盘上的数据,请使用 S3 表引擎。 - 要处理存储在 Azure Blob Storage 中的数据,请使用 AzureBlobStorage 表引擎。
- 要处理 Hadoop 分布式文件系统(不受支持)中的数据,请使用 HDFS 表引擎。
配置外部存储
MergeTree 和 Log
系列表引擎可以通过使用类型分别为 s3、azure_blob_storage、hdfs(不支持)的磁盘,将数据存储到 S3、AzureBlobStorage、HDFS(不支持)中。
磁盘配置需要:
- 一个
type段,其值为s3、azure_blob_storage、hdfs(不支持)、local_blob_storage、web之一。 - 指定相应外部存储类型的配置。
从 ClickHouse 24.1 版本起,可以使用一个新的配置选项。 它需要指定:
- 一个
type,其值为object_storage - 一个
object_storage_type,其值为s3、azure_blob_storage(或从24.3起简写为azure)、hdfs(不支持)、local_blob_storage(或从24.3起简写为local)、web之一。
可以选配 metadata_type(默认值为 local),也可以将其设置为 plain、web,并且从 24.4 起可以设置为 plain_rewritable。
plain 元数据类型的用法在 plain 存储部分中进行了说明;web 元数据类型只能与 web 对象存储类型一起使用;local 元数据类型会在本地存储元数据文件(每个元数据文件都包含对象存储中文件的映射关系,以及关于这些文件的一些附加元信息)。
例如:
相当于以下配置(自 24.1 版本起):
如下配置:
等于:
一个完整的存储配置示例如下:
从 24.1 版本开始,它还可以写成:
要将特定类型的存储设为所有 MergeTree 表的默认选项,
请在配置文件中添加以下配置段:
要为某个特定表配置专用的存储策略,可以在创建该表时通过 SETTINGS 子句进行定义:
你也可以使用 disk 替代 storage_policy。在这种情况下,无需在配置文件中包含 storage_policy 部分,只保留一个 disk 部分即可。
动态配置
还可以在无需在配置文件中预先定义磁盘的情况下指定存储配置,而是通过
CREATE/ATTACH 查询的设置来进行配置。
下面的示例查询基于上述动态磁盘配置,并展示如何使用本地磁盘 来缓存存储在某个 URL 上的表的数据。
以下示例演示如何为外部存储添加缓存。
在下方高亮显示的配置中可以看到,type=web 的磁盘被嵌套在
type=cache 的磁盘之内。
本示例使用了 type=web,但任何磁盘类型都可以配置为动态的,
包括本地磁盘。本地磁盘要求其路径参数位于服务器配置参数
custom_local_disks_base_directory 指定的目录下。该参数没有默认值,因此在使用本地磁盘时也需要进行设置。
还可以组合使用基于配置文件的配置和基于 SQL 定义的配置:
其中的 web 来自服务器配置文件:
使用 S3 存储
必需参数
| Parameter | Description |
|---|---|
endpoint | 使用 path 或 virtual hosted 风格 的 S3 endpoint URL。应包含用于数据存储的 bucket 和根路径。 |
access_key_id | 用于身份验证的 S3 access key ID。 |
secret_access_key | 用于身份验证的 S3 secret access key。 |
可选参数
| Parameter | Description | Default Value |
|---|---|---|
region | S3 区域名称。 | - |
support_batch_delete | 控制是否检查是否支持批量删除。在使用 Google Cloud Storage (GCS) 时将其设置为 false,因为 GCS 不支持批量删除。 | true |
use_environment_credentials | 如果存在,则从环境变量 AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY 和 AWS_SESSION_TOKEN 中读取 AWS 凭证。 | false |
use_insecure_imds_request | 如果为 true,在从 Amazon EC2 元数据获取凭证时使用不安全的 IMDS 请求。 | false |
expiration_window_seconds | 检查基于过期时间的凭证是否已过期的宽限期(秒)。 | 120 |
proxy | S3 endpoint 的代理配置。proxy 块中的每个 uri 元素都应包含一个代理 URL。 | - |
connect_timeout_ms | 套接字连接超时时间(毫秒)。 | 10000(10 秒) |
request_timeout_ms | 请求超时时间(毫秒)。 | 5000(5 秒) |
retry_attempts | 失败请求的重试次数。 | 10 |
single_read_retries | 读操作期间连接中断时的重试次数。 | 4 |
min_bytes_for_seek | 使用 seek 操作而不是顺序读取所需的最小字节数。 | 1 MB |
metadata_path | 用于存储 S3 元数据文件的本地文件系统路径。 | /var/lib/clickhouse/disks/<disk_name>/ |
skip_access_check | 如果为 true,在启动过程中跳过磁盘访问检查。 | false |
header | 向请求添加指定的 HTTP 头。可以指定多次。 | - |
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 | SSE-KMS 的加密上下文 HTTP 头(与 server_side_encryption_kms_key_id 一起使用)。 | - |
server_side_encryption_kms_bucket_key_enabled | 为 SSE-KMS 启用 S3 bucket key(与 server_side_encryption_kms_key_id 一起使用)。 | 与 bucket 级别设置保持一致 |
s3_max_put_rps | 在触发限流前允许的最大 PUT 请求数(每秒)。 | 0(不限) |
s3_max_put_burst | 触及 RPS 限制前允许的最大并发 PUT 请求数。 | 与 s3_max_put_rps 相同 |
s3_max_get_rps | 在触发限流前允许的最大 GET 请求数(每秒)。 | 0(不限) |
s3_max_get_burst | 触及 RPS 限制前允许的最大并发 GET 请求数。 | 与 s3_max_get_rps 相同 |
read_resource | 用于调度读请求的资源名称。 | 空字符串(禁用) |
write_resource | 用于调度写请求的资源名称。 | 空字符串(禁用) |
key_template | 使用 re2 语法定义对象 key 生成格式。需要 storage_metadata_write_full_object_key 标志。与 endpoint 中的 root path 不兼容。需要 key_compatibility_prefix。 | - |
key_compatibility_prefix | 与 key_template 一起使用。指定 endpoint 中之前的 root path,用于读取旧版本元数据。 | - |
read_only | 只允许从该磁盘读取数据。 | - |
也支持使用类型 s3 的 Google Cloud Storage (GCS)。参见基于 GCS 的 MergeTree。
使用 Plain Storage
在 22.10 中引入了一种新的磁盘类型 s3_plain,它提供只写一次的存储。
其配置参数与 s3 磁盘类型相同。
与 s3 磁盘类型不同,它按原样存储数据。换句话说,
它不会使用随机生成的 blob 名称,而是使用普通文件名
(与 ClickHouse 在本地磁盘上存储文件的方式相同),并且不会在本地存储任何
元数据。例如,这些元数据是从 s3 上的数据中推导而来。
这种磁盘类型允许保留表的静态版本,因为它不允许对现有数据执行合并,
也不允许插入新数据。该磁盘类型的一个用例是在其上创建备份,
可以通过 BACKUP TABLE data TO Disk('plain_disk_name', 'backup_name') 完成。
之后,可以执行
RESTORE TABLE data AS data_restored FROM Disk('plain_disk_name', 'backup_name')
或者使用
ATTACH TABLE data (...) ENGINE = MergeTree() SETTINGS disk = 'plain_disk_name'。
配置:
从 24.1 版本开始,可以使用 plain 元数据类型来配置任意对象存储磁盘(s3、azure、hdfs(不支持)、local)。
配置:
使用 S3 Plain Rewritable 存储
在 24.4 中引入了一种新的磁盘类型 s3_plain_rewritable。
与 s3_plain 磁盘类型类似,它不需要额外的存储空间来保存
元数据文件,而是将元数据存储在 S3 中。
不同于 s3_plain 磁盘类型,s3_plain_rewritable 允许执行合并操作,
并支持 INSERT 操作。
不支持变更和表的复制。
此磁盘类型的一个使用场景是非复制的 MergeTree 表。尽管
s3 磁盘类型适用于非复制的 MergeTree 表,如果不需要表的本地元数据,
并且可以接受受限的操作集,则可以选择使用 s3_plain_rewritable 磁盘类型。
例如,这对于系统表可能会很有用。
配置:
等于
从 24.5 版本起,可以使用 plain_rewritable 元数据类型来配置任意对象存储磁盘(s3、azure、local)。
使用 Azure Blob Storage
MergeTree 系列的表引擎可以使用类型为 azure_blob_storage 的磁盘将数据存储到 Azure Blob Storage。
配置示例:
连接参数
| 参数 | 描述 | 默认值 |
|---|---|---|
storage_account_url (Required) | Azure Blob Storage 帐户 URL。例如:http://account.blob.core.windows.net 或 http://azurite1:10000/devstoreaccount1。 | - |
container_name | 目标容器名称。 | default-container |
container_already_exists | 控制容器创建行为: - false:创建一个新容器 - true:直接连接到已存在的容器 - 未设置:检查容器是否存在,如不存在则创建 | - |
身份验证参数(磁盘会尝试所有可用方法 以及 Managed Identity Credential(托管身份凭据)):
| 参数 | 描述 |
|---|---|
connection_string | 使用连接字符串进行身份验证。 |
account_name | 使用共享密钥进行身份验证(与 account_key 配合使用)。 |
account_key | 使用共享密钥进行身份验证(与 account_name 配合使用)。 |
限制参数
| 参数 | 描述 |
|---|---|
s3_max_single_part_upload_size | 向 Blob Storage 上传单个分块的最大大小。 |
min_bytes_for_seek | 可随机访问(seekable)区域的最小大小。 |
max_single_read_retries | 从 Blob Storage 读取一段数据的最大重试次数。 |
max_single_download_retries | 从 Blob Storage 下载可读缓冲区的最大重试次数。 |
thread_pool_size | 用于实例化 IDiskRemote 的最大线程数。 |
s3_max_inflight_parts_for_one_file | 针对单个对象的最大并发 PUT 请求数。 |
其他参数
| 参数 | 描述 | 默认值 |
|---|---|---|
metadata_path | 用于存储 Blob Storage 元数据文件的本地文件系统路径。 | /var/lib/clickhouse/disks/<disk_name>/ |
skip_access_check | 如果为 true,则在启动期间跳过磁盘访问检查。 | false |
read_resource | 用于调度读取请求的资源名称。 | 空字符串(禁用) |
write_resource | 用于调度写入请求的资源名称。 | 空字符串(禁用) |
metadata_keep_free_space_bytes | 需要预留的元数据磁盘空闲空间大小。 | - |
在集成测试目录中可以找到工作配置示例(例如 test_merge_tree_azure_blob_storage 或 test_azure_blob_storage_zero_copy_replication)。
在 ClickHouse 22.8 及更高版本中,零拷贝复制默认禁用。该功能不建议在生产环境中使用。
使用 HDFS 存储(不受支持)
在此示例配置中:
- 磁盘类型为
hdfs(不受支持) - 数据托管在
hdfs://hdfs1:9000/clickhouse/
需要注意的是,HDFS 当前不受支持,因此在使用时可能会遇到问题。如果遇到问题并找到解决方案,欢迎提交 pull request 贡献修复。
请注意,HDFS 在某些极端情况下可能无法正常工作。
使用数据加密
可以对存储在 S3、HDFS(不受支持)等外部磁盘,或本地磁盘上的数据进行加密。要启用加密模式,必须在配置文件中定义一个类型为 encrypted 的磁盘,并选择一个用于保存数据的底层磁盘。encrypted 磁盘会实时加密所有写入的文件,从 encrypted 磁盘读取文件时则会自动解密。因此,可以像使用普通磁盘一样使用 encrypted 磁盘。
磁盘配置示例:
例如,当 ClickHouse 将某个表中的数据写入文件 store/all_1_1_0/data.bin 到 disk1 时,该文件实际会写入物理磁盘路径 /path1/store/all_1_1_0/data.bin。
当将同一个文件写入 disk2 时,实际上会以加密方式写入物理磁盘路径 /path1/path2/store/all_1_1_0/data.bin。
必需参数
| Parameter | Type | Description |
|---|---|---|
type | String | 必须设置为 encrypted 才能创建加密磁盘。 |
disk | String | 用于底层存储的磁盘类型。 |
key | Uint64 | 用于加密和解密的密钥。可以使用 key_hex 以十六进制形式指定。可以通过 id 属性指定多个密钥。 |
可选参数
| Parameter | Type | Default | Description |
|---|---|---|---|
path | String | Root directory | 磁盘上保存数据的位置。 |
current_key_id | String | - | 用于加密的密钥 ID。所有已指定的密钥都可用于解密。 |
algorithm | Enum | AES_128_CTR | 加密算法。选项: - AES_128_CTR(16 字节密钥)- AES_192_CTR(24 字节密钥)- AES_256_CTR(32 字节密钥) |
磁盘配置示例:
使用本地缓存
从 22.3 版本开始,可以在存储配置中为磁盘配置本地缓存。
在 22.3 - 22.7 版本中,缓存仅支持 s3 磁盘类型。对于 >= 22.8 版本,缓存支持任意磁盘类型:S3、Azure、本地、加密等。
对于 >= 23.5 版本,缓存仅支持远程磁盘类型:S3、Azure、HDFS(暂不支持)。
缓存使用 LRU 缓存策略。
适用于 22.8 及以上版本的配置示例:
22.8 之前的版本配置示例:
文件缓存 磁盘配置参数:
这些参数应在磁盘配置部分中定义。
| Parameter | Type | Default | Description |
|---|---|---|---|
path | String | - | 必需。用于存储缓存的目录路径。 |
max_size | Size | - | 必需。缓存的最大大小,可以是字节数或可读格式(例如 10Gi)。达到限制时,会使用 LRU 策略淘汰文件。支持 ki、Mi、Gi 格式(自 v22.10 起)。 |
cache_on_write_operations | Boolean | false | 为 INSERT 查询和后台合并启用写穿缓存。可以通过 enable_filesystem_cache_on_write_operations 在每个查询级别进行覆盖。 |
enable_filesystem_query_cache_limit | Boolean | false | 基于 max_query_cache_size 启用按查询的缓存大小限制。 |
enable_cache_hits_threshold | Boolean | false | 启用后,仅在数据被多次读取后才会将其缓存。 |
cache_hits_threshold | Integer | 0 | 将数据写入缓存前所需的读取次数(需要启用 enable_cache_hits_threshold)。 |
enable_bypass_cache_with_threshold | Boolean | false | 对大范围读取跳过缓存。 |
bypass_cache_threshold | Size | 256Mi | 触发跳过缓存的读取范围大小(需要启用 enable_bypass_cache_with_threshold)。 |
max_file_segment_size | Size | 8Mi | 单个缓存文件的最大大小,可以是字节数或可读格式。 |
max_elements | Integer | 10000000 | 最大缓存文件数量。 |
load_metadata_threads | Integer | 16 | 启动时用于加载缓存元数据的线程数。 |
注意:Size 值支持
ki、Mi、Gi等单位(例如10Gi)。
文件缓存查询/配置文件设置
| Setting | Type | Default | Description |
|---|---|---|---|
enable_filesystem_cache | Boolean | true | 针对单个查询启用或禁用缓存使用,即使使用的是 cache 磁盘类型。 |
read_from_filesystem_cache_if_exists_otherwise_bypass_cache | Boolean | false | 启用后,仅在数据已存在于缓存中时才使用缓存;新的数据不会写入缓存。 |
enable_filesystem_cache_on_write_operations | Boolean | false (Cloud: true) | 启用写穿缓存。需要在缓存配置中设置 cache_on_write_operations。 |
enable_filesystem_cache_log | Boolean | false | 启用后会将详细的缓存使用情况记录到 system.filesystem_cache_log。 |
filesystem_cache_allow_background_download | Boolean | true | 允许在后台完成部分已下载的分段。若禁用,则在当前查询/会话中始终在前台进行下载。 |
max_query_cache_size | Size | false | 每个查询可使用的最大缓存大小。需要在缓存配置中启用 enable_filesystem_query_cache_limit。 |
filesystem_cache_skip_download_if_exceeds_per_query_cache_write_limit | Boolean | true | 控制达到 max_query_cache_size 时的行为: - true:停止下载新数据 - false:淘汰旧数据以为新数据腾出空间 |
缓存配置设置和缓存查询设置对应最新的 ClickHouse 版本, 在较早版本中,某些功能可能不受支持。
缓存系统表
| Table Name | Description | Requirements |
|---|---|---|
system.filesystem_cache | 显示文件系统缓存的当前状态。 | 无 |
system.filesystem_cache_log | 提供每个查询的详细缓存使用统计信息。 | 需要 enable_filesystem_cache_log = true |
缓存命令
SYSTEM DROP FILESYSTEM CACHE (<cache_name>) (ON CLUSTER) -- ON CLUSTER
仅当未提供 <cache_name> 时才支持此命令。
SHOW FILESYSTEM CACHES
显示服务器上已配置的文件系统缓存列表。
(对于版本小于或等于 22.8,该命令名称为 SHOW CACHES)
DESCRIBE FILESYSTEM CACHE '<cache_name>'
显示指定缓存的配置以及一些整体统计信息。
缓存名称可以通过 SHOW FILESYSTEM CACHES 命令获取。(对于版本小于或等于 22.8 的 ClickHouse,该命令名为 DESCRIBE CACHE)
| 缓存当前指标 | 缓存异步指标 | 缓存 Profile 事件 |
|---|---|---|
FilesystemCacheSize | FilesystemCacheBytes | CachedReadBufferReadFromSourceBytes, CachedReadBufferReadFromCacheBytes |
FilesystemCacheElements | FilesystemCacheFiles | CachedReadBufferReadFromSourceMicroseconds, CachedReadBufferReadFromCacheMicroseconds |
CachedReadBufferCacheWriteBytes, CachedReadBufferCacheWriteMicroseconds | ||
CachedWriteBufferCacheWriteBytes, CachedWriteBufferCacheWriteMicroseconds |
使用静态 Web 存储(只读)
这是一个只读磁盘,其数据只会被读取,从不会被修改。通过 ATTACH TABLE 查询(见下方示例)将新表加载到该磁盘上。实际上不会使用本地磁盘,每个 SELECT 查询都会触发一次 http 请求以获取所需数据。所有对表数据的修改操作都会抛出异常,即不允许以下类型的查询:CREATE TABLE、ALTER TABLE、RENAME TABLE、DETACH TABLE 和 TRUNCATE TABLE。
Web 存储适用于只读场景。典型用例包括托管示例数据或执行数据迁移。有一个名为 clickhouse-static-files-uploader 的工具,用于为给定表准备数据目录(SELECT data_paths FROM system.tables WHERE name = 'table_name')。对于每个所需的表,都会得到一个包含文件的目录。这些文件可以上传到例如提供静态文件的 Web 服务器上。完成上述准备后,就可以通过 DiskWeb 将该表加载到任意 ClickHouse 服务器中。
在此示例配置中:
- 磁盘类型为
web - 数据托管在
http://nginx:80/test1/ - 使用了本地存储上的缓存
如果某个 web 数据集预期不会被常规使用,也可以在查询中临时配置存储。 参见 dynamic configuration,即可跳过编辑配置文件的步骤。
一个 示例数据集 托管在 GitHub 上。要将您自己的表准备好用于 web 存储,请参阅工具 clickhouse-static-files-uploader
在这个 ATTACH TABLE 查询中,提供的 UUID 与数据所在目录的名称相匹配,endpoint 为指向 GitHub 原始内容的 URL。
一个现成的测试用例。你需要将如下配置添加到 config 中:
然后执行此查询:
必填参数
| Parameter | Description |
|---|---|
type | web。否则不会创建磁盘。 |
endpoint | 使用 path 格式的端点 URL。端点 URL 必须包含一个用于存储数据的根路径,即数据上传到的路径。 |
可选参数
| 参数 | 描述 | 默认值 |
|---|---|---|
min_bytes_for_seek | 使用 seek 操作而不是顺序读取所需的最小字节数 | 1 MB |
remote_fs_read_backoff_threashold | 尝试从远程磁盘读取数据时的最大等待时间 | 10000 seconds |
remote_fs_read_backoff_max_tries | 使用退避策略进行读取时的最大尝试次数 | 5 |
如果查询失败并抛出异常 DB:Exception Unreachable URL,则可以尝试调整以下设置:http_connection_timeout、http_receive_timeout、keep_alive_timeout。
要获取用于上传的文件,请运行:
clickhouse static-files-disk-uploader --metadata-path <path> --output-dir <dir>(--metadata-path 可通过查询 SELECT data_paths FROM system.tables WHERE name = 'table_name' 获取)。
当通过 endpoint 加载文件时,文件必须被加载到 <endpoint>/store/ 路径下,但配置中只能包含 endpoint。
如果在服务器启动并加载表时无法访问磁盘上的 URL,则所有错误都会被捕获。如果在这种情况下发生了错误,可以通过 DETACH TABLE table_name -> ATTACH TABLE table_name 重新加载表(使其可见)。如果在服务器启动时元数据已成功加载,则表会立即可用。
使用 http_max_single_read_retries 设置来限制单次 HTTP 读取期间的最大重试次数。
零拷贝复制(尚未准备好用于生产环境)
在 S3 磁盘以及(尚不支持的)HDFS 磁盘上可以进行零拷贝复制,但不推荐使用。零拷贝复制意味着:如果数据在多台机器上以远程方式存储且需要同步,则仅复制元数据(数据分片的路径),而不复制数据本身。
在 ClickHouse 22.8 及更高版本中,零拷贝复制默认是禁用的。该功能不推荐用于生产环境。