用于存储数据的外部磁盘
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中的一个。 - 特定外部存储类型的配置。
从 24.1 clickhouse 版本开始,可以使用新的配置选项。 它需要指定
- 一个等于
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 存储部分中描述,web 元数据类型只能与 web 对象存储类型一起使用,local 元数据类型将元数据文件存储在本地(每个元数据文件包含对对象存储中文件的映射以及有关它们的其他元信息)。
例如
等于以下配置(从版本 24.1 开始)
以下配置
等于
完整的存储配置示例如下所示
从版本 24.1 开始,它也可以如下所示
要使特定类型的存储成为所有 MergeTree 表的默认选项,请将以下部分添加到配置文件
如果您想为特定表配置特定的存储策略,可以在创建表时在设置中定义它
您也可以使用 disk 代替 storage_policy。在这种情况下,不必在配置文件中包含 storage_policy 部分,只需一个 disk 部分即可。
refresh_parts_interval 和 table_disk
此设置适用于非复制的 MergeTree 表,其中部分可能被写入外部存储,并且需要从存储刷新元数据发现。
MergeTree 设置 refresh_parts_interval 启用定期刷新来自底层存储的数据部分列表(例如,以获取外部写入的部分)。 重要的区别在于跨副本共享元数据与副本本地元数据(例如,具有每个副本本地元数据的 S3):只有在共享元数据时,新部分才对所有副本可见。 单独使用对象存储并不意味着共享元数据。
-
对象存储(例如
disk = 's3')并不意味着共享元数据。 当元数据存储在每个副本的本地时(默认情况下),每个副本独立管理其指向对象存储中 blob 的指针。 在一个副本上所做的更改对其他副本不可见。 在这种情况下,refresh_parts_interval不会使新部分在副本之间可见,因为每个副本读取的元数据是副本本地的。 -
自动部分刷新需要文件系统元数据是共享的(或者表使用表拥有的、只读元数据,以便刷新适用)。 将
table_disk = true与表本地磁盘(例如SETTINGS disk = disk(type=object_storage, ...), table_disk = true)一起设置是一种获得正确语义的方法:表拥有元数据生命周期,存储被视为只读,因此refresh_parts_interval运行并且可以发现外部添加的部分。 -
使用全局定义的磁盘(例如
disk = 's3'在storage_configuration中)和默认的本地元数据,每个副本都有自己的元数据状态。 即使 blob 可能在 S3 中,存储对于refresh_parts_interval的目的也不被认为是共享的,并且在 ClickHouse 外部或在另一个副本上创建的新部分将不会被检测到。
为了自动刷新部分,请确保元数据是共享的,或者使用带有 table_disk = true 的表级磁盘,如上所述。 仅依赖于带有副本本地元数据的 refresh_parts_interval 将不会按预期刷新部分。
refresh_parts_interval 不用于 ReplicatedMergeTree 表。 复制表已经通过复制机制同步部分。 此设置仅适用于非复制的 MergeTree 表,其中部分被写入外部存储并且需要刷新元数据。
动态配置
也可以在不使用配置文件中预定义的磁盘的情况下指定存储配置,但可以在 CREATE/ATTACH 查询设置中进行配置。
以下示例查询基于上述动态磁盘配置,并演示如何使用本地磁盘缓存从 URL 存储的表中的数据。
下面的示例为外部存储添加了缓存。
在突出显示的设置中,请注意 type=web 的磁盘嵌套在 type=cache 的磁盘内。
该示例使用 type=web,但任何磁盘类型都可以配置为动态的,包括本地磁盘。 本地磁盘需要一个路径参数位于服务器配置参数 custom_local_disks_base_directory 内部,该参数没有默认值,因此在使用本地磁盘时也设置它。
基于配置的配置和 SQL 定义的配置的组合也是可能的
其中 web 来自服务器配置文件
使用 S3 存储
必需参数
| 参数 | 描述 |
|---|---|
端点 | S3 终端 URL 在 path 或 virtual hosted 样式中。 应包括用于数据存储的 bucket 和根路径。 |
access_key_id | 用于身份验证的 S3 访问密钥 ID。 |
secret_access_key | 用于身份验证的 S3 秘密访问密钥。 |
可选参数
| 参数 | 描述 | 默认值 |
|---|---|---|
region | S3 区域名称。 | - |
support_batch_delete | 控制是否检查批量删除支持。 在使用 Google Cloud Storage (GCS) 时设置为 false,因为 GCS 不支持批量删除。 | true |
use_environment_credentials | 从环境变量读取 AWS 凭据:如果存在,则读取 AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY 和 AWS_SESSION_TOKEN。 | 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 | 用于使用 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 加密访问 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 密钥(与 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。
使用普通存储
在 22.10 中,引入了一种新的磁盘类型 s3_plain,它提供了一次写入存储。其配置参数与 s3 磁盘类型相同。与 s3 磁盘类型不同,它按原样存储数据。换句话说,它不使用随机生成的文件名,而是使用普通文件名(就像 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 普通可重写存储
在 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 | 使用共享密钥进行身份验证(与 account_key 一起使用)。 |
account_key | 使用共享密钥进行身份验证(与 account_name 一起使用)。 |
限制参数
| 参数 | 描述 |
|---|---|
s3_max_single_part_upload_size | 上传到 Blob 存储的单个分块的最大大小。 |
min_bytes_for_seek | 可寻址区域的最小大小。 |
max_single_read_retries | 从 Blob 存储读取数据块的最大重试次数。 |
max_single_download_retries | 从 Blob 存储下载可读缓冲区的最大重试次数。 |
thread_pool_size | 用于 IDiskRemote 实例化的最大线程数。 |
s3_max_inflight_parts_for_one_file | 单个对象并发上传请求的最大数量。 |
其他参数
| 参数 | 描述 | 默认值 |
|---|---|---|
metadata_path | 用于存储 Blob 存储元数据文件的本地文件系统路径。 | /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 及更高版本中,默认情况下禁用 Zero-copy 复制。 此功能不建议用于生产环境。
使用 HDFS 存储(不受支持)
在此示例配置中
- 磁盘类型为
hdfs(不受支持) - 数据托管在
hdfs://hdfs1:9000/clickhouse/
顺便说一下,HDFS 不受支持,因此在使用它时可能会出现问题。如果出现任何问题,请随时提出带有修复的拉取请求。
请记住,HDFS 在某些情况下可能无法正常工作。
使用数据加密
您可以加密存储在 S3 或 HDFS(不受支持)外部磁盘或本地磁盘上的数据。要启用加密模式,您必须在配置文件中定义一个类型为 encrypted 的磁盘,并选择保存数据的磁盘。encrypted 磁盘会在写入所有文件时对其进行加密,并且在从 encrypted 磁盘读取文件时会自动对其进行解密。因此,您可以像使用普通磁盘一样使用 encrypted 磁盘。
磁盘配置示例
例如,当 ClickHouse 将某个表的数据写入到 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 的物理磁盘。
必需参数
| 参数 | 类型 | 描述 |
|---|---|---|
类型 | String | 必须设置为 encrypted 以创建加密磁盘。 |
disk | String | 用于底层存储的磁盘类型。 |
key | Uint64 | 用于加密和解密的密钥。可以使用十六进制格式指定,方法是使用 key_hex。可以使用 id 属性指定多个密钥。 |
可选参数
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
path | String | 根目录 | 数据将保存到的磁盘上的位置。 |
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、Local、Encrypted 等。对于版本 >= 23.5,缓存仅支持远程磁盘类型:S3、Azure、HDFS(不受支持)。缓存使用 LRU 缓存策略。
版本晚于或等于 22.8 的配置示例
版本早于 22.8 的配置示例
文件缓存 磁盘配置设置
这些设置应在磁盘配置部分中定义。
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
path | String | - | 必需。将存储缓存的目录路径。 |
max_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 | 整数 | 0 | 在缓存数据之前所需的读取次数(需要 enable_cache_hits_threshold)。 |
enable_bypass_cache_with_threshold | Boolean | false | 跳过大型读取范围的缓存。 |
bypass_cache_threshold | 大小 | 256Mi | 触发缓存绕过(需要 enable_bypass_cache_with_threshold)的读取范围大小。 |
max_file_segment_size | 大小 | 8Mi | 缓存文件中允许的最大大小(以字节为单位或可读格式)。 |
max_elements | 整数 | 10000000 | 允许的最大文件数。 |
load_metadata_threads | 整数 | 16 | 启动时加载缓存元数据的线程数。 |
use_split_cache | Boolean | false | 使用文件分离来系统/数据。 |
split_cache_ratio | Double | 0.1 | split_cache 分割缓存时,系统分段占总缓存大小的比例。 |
注意:大小值支持诸如
ki、Mi、Gi等单位(例如,10Gi)。
文件缓存查询/配置设置
| 设置 | 类型 | 默认值 | 描述 |
|---|---|---|---|
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 (云: 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 | 大小 | 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 版本,对于早期版本,某些内容可能不受支持。
缓存系统表
| 表名 | 描述 | 要求 |
|---|---|---|
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)
DESCRIBE FILESYSTEM CACHE '<cache_name>'
显示特定缓存的缓存配置和一些常规统计信息。可以从 SHOW FILESYSTEM CACHES 命令获取缓存名称。(对于版本小于或等于 22.8,该命令命名为 DESCRIBE CACHE)
| 缓存当前指标 | 缓存异步指标 | 缓存配置事件 |
|---|---|---|
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 服务器。完成此准备后,您可以将此表加载到任何 ClickHouse 服务器通过 DiskWeb。
在此示例配置中
- 磁盘类型为
web - 数据托管在
http://nginx:80/test1/ - 使用本地缓存
如果预计不需要常规使用 Web 数据集,则可以在查询中临时配置存储,请参阅 动态配置 并跳过编辑配置文件。
在 GitHub 上托管了一个 演示数据集。要为 Web 存储准备自己的表,请参阅工具 clickhouse-static-files-uploader
在此 ATTACH TABLE 查询中,提供的 UUID 与数据目录名称匹配,并且端点是原始 GitHub 内容的 URL。
一个准备好的测试用例。您需要将此配置添加到 config
然后执行此查询
必需参数
| 参数 | 描述 |
|---|---|
类型 | web。否则不会创建磁盘。 |
端点 | path 格式的端点 URL。端点 URL 必须包含一个根路径来存储数据,数据上传到该路径。 |
可选参数
| 参数 | 描述 | 默认值 |
|---|---|---|
min_bytes_for_seek | 用于代替顺序读取的最小字节数以使用 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>(--metadata-path 可以在查询 SELECT data_paths FROM system.tables WHERE name = 'table_name' 中找到)。
通过 endpoint 加载文件时,必须将它们加载到 <endpoint>/store/ 路径,但 config 仅包含 endpoint。
如果服务器启动时无法访问磁盘上的 URL,则会捕获所有错误。在这种情况下,如果出现错误,可以通过 DETACH TABLE table_name -> ATTACH TABLE table_name 重新加载表(使其可见)。如果元数据在服务器启动时成功加载,则表将立即可用。
使用 http_max_single_read_retries 设置来限制单个 HTTP 读取期间的最大重试次数。
零拷贝复制(不准备用于生产)
零拷贝复制是可能的,但不推荐,使用 S3 和 HDFS(不受支持)磁盘。零拷贝复制意味着如果数据远程存储在多台机器上并且需要同步,则仅复制元数据(数据片段的路径),而不复制数据本身。
在 ClickHouse 22.8 及更高版本中,默认情况下禁用 Zero-copy 复制。 此功能不建议用于生产环境。