- Amazon S3 对象存储。
- Azure Blob 存储。
- 不支持:Hadoop Distributed File System (HDFS)
ClickHouse 还支持外部表引擎,它们与本页介绍的外部存储选项不同,因为前者允许读取以通用文件格式 (如 Parquet) 存储的数据。本页介绍的是 ClickHouse
MergeTree 家族或 Log 家族表的存储配置。- 如需处理存储在
Amazon S3磁盘上的数据,请使用 S3 表引擎。 - 如需处理存储在 Azure Blob 存储中的数据,请使用 AzureBlobStorage 表引擎。
- 如需处理 Hadoop Distributed File System (不支持) 中的数据,请使用 HDFS 表引擎。
配置外部存储
MergeTree 和 Log
家族的表引擎可分别通过类型为 s3、azure_blob_storage、hdfs (不支持) 的磁盘,将数据存储到 S3、AzureBlobStorage、HDFS (不支持) 中。
磁盘配置需要:
- 一个
type配置项,其值必须是s3、azure_blob_storage、hdfs(不支持) 、local_blob_storage、web之一。 - 针对具体外部存储类型的配置。
- 值为
object_storage的type 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 storage 部分;web 元数据类型只能与 web 对象存储类型一起使用;local 元数据类型会将元数据文件存储在本地 (每个元数据文件都包含对象存储中文件的映射,以及与这些文件相关的一些附加元信息) 。
例如:
24.1 开始) :
MergeTree 表的默认选项,
请在配置文件中添加以下部分:
disk 替代 storage_policy。在这种情况下,
配置文件中无需包含 storage_policy 部分,只需有一个 disk
部分即可。
refresh_parts_interval 和 table_disk
refresh_parts_interval 可定期从底层存储刷新数据分区片段列表 (例如发现外部写入的 parts) 。这里的关键区别在于跨副本共享元数据与副本本地元数据 (例如每个副本各自维护本地元数据的 S3) :只有在元数据共享时,新的 parts 才会对所有副本可见。仅使用对象存储本身并不意味着元数据是共享的。
-
对象存储 (例如
disk = 's3') 并不意味着元数据是共享的。 当元数据默认按副本存储在本地时,每个副本都会独立管理自己指向对象存储中 blob 的指针。在一个副本上所做的更改,对其他副本不可见。在这种情况下,refresh_parts_interval不会让新的 parts 在副本之间变得可见,因为每个副本读取的都是各自的本地元数据。 -
自动刷新 parts 要求 filesystem 元数据是共享的 (或者表使用表自有的只读元数据,从而能够进行刷新) 。将
table_disk = true与表本地磁盘一起使用 (例如SETTINGS disk = disk(type=object_storage, ...), table_disk = true) 是获得正确语义的一种方式:表负责元数据的生命周期管理,存储会被视为只读,因此会执行refresh_parts_interval,并且能够发现外部新增的 parts。 -
使用全局定义的磁盘时 (例如在
storage_configuration中设置disk = 's3') ,如果采用默认的本地元数据,则每个副本都有自己的元数据状态。即使 blob 可能位于 S3 中,就refresh_parts_interval而言,该存储也不被视为共享存储,因此在 ClickHouse 外部或在另一个副本上创建的新的 parts 都不会被检测到。
table_disk = true 的表级磁盘。如果在元数据为副本本地的情况下仅依赖 refresh_parts_interval,则 parts 不会按预期刷新。
refresh_parts_interval 不用于 ReplicatedMergeTree 表。
复制表已经通过复制机制同步 parts。
此设置仅适用于 parts 由外部写入且需要刷新元数据的非复制表 MergeTree 表。动态配置
CREATE/ATTACH 查询设置中进行配置。
以下示例查询基于上述动态磁盘配置,展示了如何使用本地磁盘缓存存储在 URL 上的表数据。
type=web 的磁盘嵌套在
type=cache 的磁盘内。
此示例使用了
type=web,但任何磁盘类型都可以配置为动态磁盘,
包括本地磁盘。本地磁盘要求其 path 参数位于
server 配置参数 custom_local_disks_base_directory 中。该参数没有
默认值,因此使用本地磁盘时也需要设置它。web 来自服务端配置文件:
使用 S3 存储
必需参数
| 参数 | 说明 |
|---|---|
endpoint | 采用 path 或 virtual hosted 样式 的 S3 端点 URL。应包含存储数据所用的存储桶和根路径。 |
access_key_id | 用于身份验证的 S3 访问密钥 ID。 |
secret_access_key | 用于身份验证的 S3 私密访问密钥。 |
可选参数
| 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 凭证。注意:环境凭证会在所有 S3 磁盘之间共享。若要为不同磁盘使用不同的凭证,请改为为每个磁盘显式指定 access_key_id 和 secret_access_key。 | false |
use_insecure_imds_request | 如果为 true,则在从 Amazon EC2 元数据获取凭证时使用不安全的 IMDS 请求。 | false |
expiration_window_seconds | 检查基于过期时间的凭证是否已过期时使用的宽限期 (秒) 。 | 120 |
proxy | S3 端点的代理配置。proxy 块中的每个 uri 元素都应包含一个代理 URL。 | - |
connect_timeout_ms | 套接字连接超时时间 (毫秒) 。 | 10000 (10 秒) |
request_timeout_ms | 请求超时时间 (毫秒) 。 | 5000 (5 秒) |
retry_attempts | 失败请求的重试次数。 | 10 |
single_read_retries | 读取过程中连接中断时的重试次数。 | 4 |
min_bytes_for_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 对象所需的请求头。 | - |
server_side_encryption_kms_key_id | 访问使用 SSE-KMS encryption 的 S3 对象所需的请求头。空字符串表示使用 AWS 托管的 S3 密钥。 | - |
server_side_encryption_kms_encryption_context | SSE-KMS 的加密上下文请求头 (与 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 语法定义对象键的生成格式。要求启用 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 上的数据推导出来。
这种磁盘类型可用于保留表的静态版本,因为它不允许
对现有数据执行 merge,也不允许插入新
数据。该磁盘类型的一个典型用法是基于它创建 backups,这可以通过
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 存储
MergeTree 家族表引擎可使用类型为 azure_blob_storage 的磁盘将数据存储到 Azure Blob 存储 中。
配置示例:
连接参数
| 参数 | 描述 | 默认值 |
|---|---|---|
storage_account_url (必填) | Azure Blob 存储账户 URL。示例:http://account.blob.core.windows.net 或 http://azurite1:10000/devstoreaccount1。 | - |
container_name | 目标容器名称。 | default-container |
container_already_exists | 控制容器创建行为: - false:创建新容器 - true:直接连接到现有容器 - 未设置:检查容器是否存在,并在需要时创建 | - |
| 参数 | 描述 |
|---|---|
connection_string | 用于通过连接字符串进行身份验证。 |
account_name | 用于通过 Shared Key 进行身份验证 (与 account_key 配合使用) 。 |
account_key | 用于通过 Shared Key 进行身份验证 (与 account_name 配合使用) 。 |
限制参数
| 参数 | 描述 |
|---|---|
s3_max_single_part_upload_size | 上传到 Blob Storage 的单个块的最大大小。 |
min_bytes_for_seek | 可寻道区域的最小大小。 |
max_single_read_retries | 从 Blob Storage 读取一个数据块的最大重试次数。 |
max_single_download_retries | 从 Blob Storage 下载可读缓冲区的最大重试次数。 |
thread_pool_size | 用于实例化 IDiskRemote 的最大线程数。 |
s3_max_inflight_parts_for_one_file | 单个对象的并发 PUT 请求最大数量。 |
其他参数
可在集成测试目录中找到可用的配置示例 (例如,test_merge_tree_azure_blob_storage 或 test_azure_blob_storage_zero_copy_replication) 。
零拷贝复制尚不能用于生产环境在 ClickHouse 22.8 及更高版本中,零拷贝复制默认处于禁用状态。不建议在生产环境中使用此功能。
使用 HDFS 存储 (不支持)
- 磁盘类型为
hdfs(不支持) - 数据存储在
hdfs://hdfs1:9000/clickhouse/
使用数据加密
encrypted 的磁盘,并选择一个用于保存数据的底层磁盘。encrypted 磁盘会在写入时即时加密所有文件,而从 encrypted 磁盘读取文件时则会自动解密。因此,你可以像使用普通磁盘一样使用 encrypted 磁盘。
磁盘配置示例:
disk1 上的文件 store/all_1_1_0/data.bin 时,实际上该文件会写入物理磁盘上的 /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 属性指定多个密钥。 |
可选参数
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
path | String | 根目录 | 数据在磁盘上的保存位置。 |
current_key_id | String | - | 用于加密的密钥 ID。所有指定的密钥均可用于解密。 |
algorithm | 枚举 | AES_128_CTR | 加密算法。可选值: - AES_128_CTR (16 字节密钥) - AES_192_CTR (24 字节密钥) - AES_256_CTR (32 字节密钥) |
使用本地缓存
s3 磁盘类型支持缓存。对于 >= 22.8 版本,所有磁盘类型都支持缓存:S3、Azure、Local、Encrypted 等。
对于 >= 23.5 版本,仅远程磁盘类型支持缓存:S3、Azure、HDFS (不支持) 。
缓存使用 LRU 缓存策略。
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 | 启动时用于加载缓存元数据的线程数。 |
use_split_cache | Boolean | false | 将文件拆分为 system/data 两类。 |
split_cache_ratio | Double | 0.1 | split_cache 中 system 部分占缓存总大小的比例。 |
注意:Size 值支持ki、Mi、Gi等单位 (例如10Gi) 。
File Cache 查询/profile 设置
| 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 | 允许在后台完成部分已下载分段的剩余下载。禁用后,当前查询/session 的下载会保持在前台执行。 |
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:淘汰旧数据,为新数据腾出空间 |
缓存相关系统表
| Table Name | Description | Requirements |
|---|---|---|
system.filesystem_cache | 显示文件系统缓存的当前状态。 | 无 |
system.filesystem_cache_log | 提供每个查询的详细缓存使用统计信息。 | 需要 enable_filesystem_cache_log = true |
缓存命令
SYSTEM CLEAR|DROP FILESYSTEM CACHE (<cache_name>) (ON CLUSTER) — ON CLUSTER
<cache_name> 时,才支持此命令
SHOW FILESYSTEM CACHES
22.8 的版本,该命令名为 SHOW CACHES)
Query
Response
DESCRIBE FILESYSTEM CACHE '<cache_name>'
SHOW FILESYSTEM CACHES 命令获取。 (在小于或等于 22.8 的版本中,
该命令名为 DESCRIBE CACHE)
Query
Response
| 缓存当前状态指标 | 缓存异步指标 | 缓存 profile events |
|---|---|---|
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 server 中。
在此示例配置中:
- 磁盘类型为
web - 数据托管在
http://nginx:80/test1/ - 使用了本地存储上的缓存
ATTACH TABLE 查询中,提供的 UUID 与数据目录名称一致,而端点是 GitHub 原始内容的 URL。
必需参数
| 参数 | 描述 |
|---|---|
type | web。否则不会创建该磁盘。 |
endpoint | path 格式的端点 URL。端点 URL 必须包含一个用于存储数据的根路径,也就是数据上传后的存储位置。 |
可选参数
| 参数 | 描述 | 默认值 |
|---|---|---|
min_bytes_for_seek | 使用寻道操作而不是顺序读取的最小字节数 | 1 MB |
remote_fs_read_backoff_threashold | 读取远程磁盘数据时的最大等待时间 | 10000 秒 |
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> (可通过查询 SELECT data_paths FROM system.tables WHERE name = 'table_name' 找到 --metadata-path) 。
通过 endpoint 加载文件时,文件必须加载到 <endpoint>/store/ 路径下,但配置中只能填写 endpoint。
如果服务器在启动表时,磁盘加载过程中 URL 无法访问,系统会捕获所有错误。在这种情况下如果出现错误,可以通过 DETACH TABLE table_name -> ATTACH TABLE table_name 重新加载表 (使其重新可见) 。如果元数据在服务器启动时已成功加载,则表会立即可用。
使用 http_max_single_read_retries 设置来限制单次 HTTP 读取期间的最大重试次数。
零拷贝复制 (尚不适用于生产环境)
S3 和 HDFS (不受支持) 磁盘上使用零拷贝复制,但不建议这样做。零拷贝复制是指:如果数据远程存储在多台机器上并且需要同步,则只复制元数据 (数据分区片段的路径) ,而不复制数据本身。
零拷贝复制尚不适用于生产环境在 ClickHouse 22.8 及更高版本中,零拷贝复制默认被禁用。不建议在生产环境中使用此功能。