跳转到主要内容
如果您在 Google Cloud 上使用 ClickHouse Cloud,则本页不适用,因为您的服务已在使用 Google Cloud Storage。如果您想从 GCS SELECT 或向 GCS INSERT 数据,请参阅 gcs 表函数
ClickHouse 认识到,对于希望将存储与计算分离的用户来说,GCS 是一种很有吸引力的存储解决方案。为此,现已支持将 GCS 用作 MergeTree 引擎的存储后端。这样,您既可以利用 GCS 在可扩展性和成本方面的优势,也能获得 MergeTree 引擎的插入和查询性能。

基于 GCS 的 MergeTree

创建磁盘

要将 GCS 存储桶用作磁盘,首先必须在 conf.d 下的某个文件中,在 ClickHouse 配置里声明它。下面展示了一个 GCS 磁盘声明示例。此配置包含多个部分,分别用于配置 GCS“磁盘”、缓存,以及在需要在 GCS 磁盘上创建表时在 DDL queries 中指定的策略。下面将分别介绍这些部分。

存储配置 > disks > gcs

配置中的这一部分显示在高亮区域,用于指定以下内容:
  • 磁盘类型为 s3,因为这里使用的是 S3 API。
  • GCS 提供的端点
  • 服务账号的 HMAC 密钥和 secret
  • 本地磁盘上的元数据路径
<clickhouse>
    <storage_configuration>
        <disks>
            <gcs>
                <support_batch_delete>true</support_batch_delete>
                <type>s3</type>
                <endpoint>https://storage.googleapis.com/BUCKET NAME/FOLDER NAME/</endpoint>
                <access_key_id>SERVICE ACCOUNT HMAC KEY</access_key_id>
                <secret_access_key>SERVICE ACCOUNT HMAC SECRET</secret_access_key>
                <metadata_path>/var/lib/clickhouse/disks/gcs/</metadata_path>
            </gcs>
        </disks>
        <policies>
            <gcs_main>
                <volumes>
                    <main>
                        <disk>gcs</disk>
                    </main>
                </volumes>
            </gcs_main>
        </policies>
    </storage_configuration>
</clickhouse>

存储配置 > disks > cache

下面高亮显示的示例配置会为 gcs 磁盘启用 10Gi 的内存缓存。
<clickhouse>
    <storage_configuration>
        <disks>
            <gcs>
                <support_batch_delete>true</support_batch_delete>
                <type>s3</type>
                <endpoint>https://storage.googleapis.com/BUCKET NAME/FOLDER NAME/</endpoint>
                <access_key_id>SERVICE ACCOUNT HMAC KEY</access_key_id>
                <secret_access_key>SERVICE ACCOUNT HMAC SECRET</secret_access_key>
                <metadata_path>/var/lib/clickhouse/disks/gcs/</metadata_path>
            </gcs>
            <gcs_cache>
                <type>cache</type>
                <disk>gcs</disk>
                <path>/var/lib/clickhouse/disks/gcs_cache/</path>
                <max_size>10Gi</max_size>
            </gcs_cache>
        </disks>
        <policies>
            <gcs_main>
                <volumes>
                    <main>
                        <disk>gcs_cache</disk>
                    </main>
                </volumes>
            </gcs_main>
        </policies>
    </storage_configuration>
</clickhouse>

存储配置 > 策略 > gcs_main

存储配置策略可用于指定数据的存储位置。下面重点说明的策略通过指定 gcs_main,允许将数据存储在磁盘 gcs 上。例如:CREATE TABLE ... SETTINGS storage_policy='gcs_main'
<clickhouse>
    <storage_configuration>
        <disks>
            <gcs>
                <support_batch_delete>true</support_batch_delete>
                <type>s3</type>
                <endpoint>https://storage.googleapis.com/BUCKET NAME/FOLDER NAME/</endpoint>
                <access_key_id>SERVICE ACCOUNT HMAC KEY</access_key_id>
                <secret_access_key>SERVICE ACCOUNT HMAC SECRET</secret_access_key>
                <metadata_path>/var/lib/clickhouse/disks/gcs/</metadata_path>
            </gcs>
        </disks>
        <policies>
            <gcs_main>
                <volumes>
                    <main>
                        <disk>gcs</disk>
                    </main>
                </volumes>
            </gcs_main>
        </policies>
    </storage_configuration>
</clickhouse>
此磁盘声明的相关设置完整列表可参见此处

创建表

假设你已将磁盘配置为使用具有写入权限的 存储桶,那么你应该能够像下面的示例一样创建一个表。为简洁起见,我们只使用 NYC taxi 部分列,并将数据直接流式写入以 GCS 作为后端的表中:
CREATE TABLE trips_gcs
(
   `trip_id` UInt32,
   `pickup_date` Date,
   `pickup_datetime` DateTime,
   `dropoff_datetime` DateTime,
   `pickup_longitude` Float64,
   `pickup_latitude` Float64,
   `dropoff_longitude` Float64,
   `dropoff_latitude` Float64,
   `passenger_count` UInt8,
   `trip_distance` Float64,
   `tip_amount` Float32,
   `total_amount` Float32,
   `payment_type` Enum8('UNK' = 0, 'CSH' = 1, 'CRE' = 2, 'NOC' = 3, 'DIS' = 4)
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(pickup_date)
ORDER BY pickup_datetime
SETTINGS storage_policy='gcs_main'
INSERT INTO trips_gcs SELECT trip_id, pickup_date, pickup_datetime, dropoff_datetime, pickup_longitude, pickup_latitude, dropoff_longitude, dropoff_latitude, passenger_count, trip_distance, tip_amount, total_amount, payment_type FROM s3('https://ch-nyc-taxi.s3.eu-west-3.amazonaws.com/tsv/trips_{0..9}.tsv.gz', 'TabSeparatedWithNames') LIMIT 1000000;
根据硬件配置不同,最后这次插入 100 万行数据可能需要几分钟才能完成。你可以通过 system.processes 表查看进度。你也可以将行数提高到 1000 万的上限,并尝试运行一些示例查询。
SELECT passenger_count, avg(tip_amount) AS avg_tip, avg(total_amount) AS avg_amount FROM trips_gcs GROUP BY passenger_count;

实现复制

使用 GCS 磁盘时,可以通过 ReplicatedMergeTree 表引擎实现复制。详情请参阅使用 GCS 在两个 GCP 区域间复制单个分片指南。

了解更多

Cloud Storage XML API 可与部分适用于 Amazon Simple Storage Service (Amazon S3) 等服务的工具和库互操作。 有关线程调优的更多信息,请参阅性能优化

使用 Google Cloud Storage (GCS)

ClickHouse Cloud 默认使用对象存储;如果您运行在 ClickHouse Cloud 上,则无需遵循此流程。

规划部署

本教程介绍如何在 Google Cloud 上部署一个复制的 ClickHouse 集群,并使用 Google Cloud Storage (GCS) 作为 ClickHouse 存储磁盘的“类型”。 在本教程中,您将在 Google Cloud Engine VM 中部署 ClickHouse 服务器 节点,并为每个节点关联一个 GCS 存储桶用于存储。复制由一组同样部署为 VM 的 ClickHouse Keeper 节点负责协调。 高可用性的示例要求:
  • 两个 ClickHouse 服务器 节点,位于两个 GCP 区域
  • 两个 GCS 存储桶,部署在与这两个 ClickHouse 服务器 节点相同的区域
  • 三个 ClickHouse Keeper 节点,其中两个部署在与 ClickHouse 服务器 节点相同的区域。第三个可以与前两个 Keeper 节点中的一个位于同一区域,但需处于不同的可用区。
ClickHouse Keeper 至少需要两个节点才能正常工作,因此要实现高可用性,需要三个节点。

准备虚拟机

在三个区域部署五台虚拟机:
区域ClickHouse Server存储桶ClickHouse Keeper
1chnode1bucket_regionnamekeepernode1
2chnode2bucket_regionnamekeepernode2
3 *keepernode3
* 这也可以是在与 1 或 2 相同区域内的另一个可用区。

部署 ClickHouse

在两台主机上部署 ClickHouse;在示例配置中,这两台主机分别命名为 chnode1chnode2 chnode1 放在一个 GCP 区域中,将 chnode2 放在另一个区域中。本指南中,Compute Engine 虚拟机和 GCS 存储桶分别使用 us-east1us-east4
在完成配置之前,不要启动 clickhouse server,只需先安装即可。
在 ClickHouse 服务器 节点上执行部署步骤时,请参阅安装说明

部署 ClickHouse Keeper

在三台主机上部署 ClickHouse Keeper。在示例配置中,这三台主机分别命名为 keepernode1keepernode2keepernode3keepernode1 可部署在与 chnode1 相同的区域,keepernode2 可与 chnode2 部署在同一区域,keepernode3 则可部署在任一区域,但需与该区域中的 ClickHouse 节点位于不同的可用区。 在 ClickHouse Keeper 节点上执行部署步骤时,请参阅安装说明

创建两个存储桶

两个 ClickHouse 服务器将部署在不同区域中,以实现高可用性。每个服务器都会在相同区域中配备一个 GCS 存储桶。 Cloud Storage > Buckets 中选择 CREATE BUCKET。在本教程中,需要创建两个存储桶,分别位于 us-east1us-east4。这些存储桶均为单区域、标准存储类别,且不公开。出现提示时,请启用公共访问防护。不要创建文件夹;ClickHouse 在写入存储时会自动创建它们。 如果你需要创建存储桶和 HMAC 密钥的分步说明,请展开 创建 GCS 存储桶和 HMAC 密钥 并按步骤操作:

ch_bucket_us_east1

ch_bucket_us_east4

生成访问密钥

创建服务账号 HMAC 密钥和密钥内容

打开 Cloud Storage > Settings > Interoperability,选择现有的 Access key,或选择 CREATE A KEY FOR A SERVICE ACCOUNT。本指南介绍的是为新的服务账号创建新密钥的流程。

添加新的服务账号

如果该项目还没有现有服务账号,请选择 CREATE NEW ACCOUNT创建服务账号共分三步。第一步,为该账号填写有意义的名称、ID 和描述。在 Interoperability 设置对话框中,推荐使用 IAM role Storage Object Admin;请在第二步选择该角色。第三步为可选项,本指南中不会用到。你可以根据自身策略决定是否向用户授予这些特权。系统会显示服务账号的 HMAC 密钥。请保存这些信息,因为稍后会在 ClickHouse 配置中使用。

配置 ClickHouse Keeper

server_id 这一行 (下方第一处高亮的行) 外,所有 ClickHouse Keeper 节点的配置文件都相同。请将文件中的主机名替换为你的 ClickHouse Keeper 服务器主机名,并在每台服务器上将 server_id 设置为与 raft_configuration 中对应 server 条目一致的值。由于此示例中的 server_id 设为 3,我们在 raft_configuration 中高亮了对应的行。
  • 用你的主机名编辑此文件,并确保这些主机名能够被 ClickHouse 服务器 节点和 Keeper 节点解析
  • 将文件复制到相应位置 (每台 Keeper 服务器上的 /etc/clickhouse-keeper/keeper_config.xml)
  • 根据每台机器在 raft_configuration 中的条目编号,修改其 server_id
/etc/clickhouse-keeper/keeper_config.xml
<clickhouse>
    <logger>
        <level>trace</level>
        <log>/var/log/clickhouse-keeper/clickhouse-keeper.log</log>
        <errorlog>/var/log/clickhouse-keeper/clickhouse-keeper.err.log</errorlog>
        <size>1000M</size>
        <count>3</count>
    </logger>
    <listen_host>0.0.0.0</listen_host>
    <keeper_server>
        <tcp_port>9181</tcp_port>
        <server_id>3</server_id>
        <log_storage_path>/var/lib/clickhouse/coordination/log</log_storage_path>
        <snapshot_storage_path>/var/lib/clickhouse/coordination/snapshots</snapshot_storage_path>

        <coordination_settings>
            <operation_timeout_ms>10000</operation_timeout_ms>
            <session_timeout_ms>30000</session_timeout_ms>
            <raft_logs_level>warning</raft_logs_level>
        </coordination_settings>

        <raft_configuration>
            <server>
                <id>1</id>
                <hostname>keepernode1.us-east1-b.c.clickhousegcs-374921.internal</hostname>
                <port>9234</port>
            </server>
            <server>
                <id>2</id>
                <hostname>keepernode2.us-east4-c.c.clickhousegcs-374921.internal</hostname>
                <port>9234</port>
            </server>
            <server>
                <id>3</id>
                <hostname>keepernode3.us-east5-a.c.clickhousegcs-374921.internal</hostname>
                <port>9234</port>
            </server>
        </raft_configuration>
    </keeper_server>
</clickhouse>

配置 ClickHouse 服务器

最佳实践本指南中的某些步骤会要求你将配置文件放到 /etc/clickhouse-server/config.d/ 中。这是 Linux 系统中配置覆盖文件的默认位置。将这些文件放入该目录后,ClickHouse 会把其中的内容与默认配置合并。把这些文件放在 config.d 目录中,可以避免在升级时丢失配置。

网络

默认情况下,ClickHouse 仅监听回环接口;在启用复制的部署中,机器之间必须能够进行网络通信。请监听所有接口:
/etc/clickhouse-server/config.d/network.xml
<clickhouse>
    <listen_host>0.0.0.0</listen_host>
</clickhouse>

远程 ClickHouse Keeper 服务器

复制由 ClickHouse Keeper 负责协调。此配置文件通过主机名和端口号指定 ClickHouse Keeper 节点。
  • 将主机名修改为与您的 Keeper 主机一致
/etc/clickhouse-server/config.d/use-keeper.xml
<clickhouse>
    <zookeeper>
        <node index="1">
            <host>keepernode1.us-east1-b.c.clickhousegcs-374921.internal</host>
            <port>9181</port>
        </node>
        <node index="2">
            <host>keepernode2.us-east4-c.c.clickhousegcs-374921.internal</host>
            <port>9181</port>
        </node>
        <node index="3">
            <host>keepernode3.us-east5-a.c.clickhousegcs-374921.internal</host>
            <port>9181</port>
        </node>
    </zookeeper>
</clickhouse>

远程 ClickHouse 服务器

此文件用于配置集群中每个 ClickHouse 服务器的主机名和端口。默认配置文件包含示例集群定义;为了只显示已完整配置的集群,需要在 remote_servers 条目中添加 replace="true" 标签。这样,当此配置与默认配置合并时,它会替换 remote_servers 部分,而不是在其中追加内容。
  • 用你的主机名编辑此文件,并确保这些主机名可从 ClickHouse 服务器节点解析
/etc/clickhouse-server/config.d/remote-servers.xml
<clickhouse>
    <remote_servers replace="true">
        <cluster_1S_2R>
            <shard>
                <replica>
                    <host>chnode1.us-east1-b.c.clickhousegcs-374921.internal</host>
                    <port>9000</port>
                </replica>
                <replica>
                    <host>chnode2.us-east4-c.c.clickhousegcs-374921.internal</host>
                    <port>9000</port>
                </replica>
            </shard>
        </cluster_1S_2R>
    </remote_servers>
</clickhouse>

副本标识

此文件用于配置与 ClickHouse Keeper 路径相关的设置。具体来说,是配置用于标识数据所属副本的宏。在一台服务器上,副本应指定为 replica_1,而在另一台服务器上则应指定为 replica_2。这些名称可以更改;根据我们的示例,如果一个副本存储在南卡罗来纳,另一个存储在北弗吉尼亚,那么相应的值也可以设为 carolinavirginia;只需确保它们在每台机器上各不相同即可。
/etc/clickhouse-server/config.d/macros.xml
<clickhouse>
    <distributed_ddl>
            <path>/clickhouse/task_queue/ddl</path>
    </distributed_ddl>
    <macros>
        <cluster>cluster_1S_2R</cluster>
        <shard>1</shard>
        <replica>replica_1</replica>
    </macros>
</clickhouse>

GCS 中的存储

ClickHouse 存储配置包含 diskspolicies。下面配置的磁盘名为 gcs,其 types3。之所以使用 s3 类型,是因为 ClickHouse 访问 GCS 存储桶时,会将其视为 AWS S3 存储桶。此配置需要准备两份,每个 ClickHouse 服务器 节点各一份。 需要在下面的配置中进行以下替换。 以下替换项在两个 ClickHouse 服务器 节点之间有所不同:
  • REPLICA 1 BUCKET 应设置为与 server 位于同一区域的存储桶名称
  • REPLICA 1 FOLDER 应在其中一个 server 上改为 replica_1,在另一个 server 上改为 replica_2
以下替换项在两个节点上相同:
  • access_key_id 应设置为之前生成的 HMAC Key
  • secret_access_key 应设置为之前生成的 HMAC Secret
/etc/clickhouse-server/config.d/storage.xml
<clickhouse>
    <storage_configuration>
        <disks>
            <gcs>
                <support_batch_delete>true</support_batch_delete>
                <type>s3</type>
                <endpoint>https://storage.googleapis.com/REPLICA 1 BUCKET/REPLICA 1 FOLDER/</endpoint>
                <access_key_id>SERVICE ACCOUNT HMAC KEY</access_key_id>
                <secret_access_key>SERVICE ACCOUNT HMAC SECRET</secret_access_key>
                <metadata_path>/var/lib/clickhouse/disks/gcs/</metadata_path>
            </gcs>
            <cache>
                <type>cache</type>
                <disk>gcs</disk>
                <path>/var/lib/clickhouse/disks/gcs_cache/</path>
                <max_size>10Gi</max_size>
            </cache>
        </disks>
        <policies>
            <gcs_main>
                <volumes>
                    <main>
                        <disk>gcs</disk>
                    </main>
                </volumes>
            </gcs_main>
        </policies>
    </storage_configuration>
</clickhouse>

启动 ClickHouse Keeper

使用适合您所用操作系统的命令,例如:
sudo systemctl enable clickhouse-keeper
sudo systemctl start clickhouse-keeper
sudo systemctl status clickhouse-keeper

检查 ClickHouse Keeper 状态

使用 netcat 向 ClickHouse Keeper 发送命令。例如,mntr 会返回 ClickHouse Keeper 集群的状态信息。如果在每个 Keeper 节点上运行该命令,你会看到其中一个是 leader,另外两个是跟随者:
echo mntr | nc localhost 9181
zk_version      v22.7.2.15-stable-f843089624e8dd3ff7927b8a125cf3a7a769c069
zk_avg_latency  0
zk_max_latency  11
zk_min_latency  0
zk_packets_received     1783
zk_packets_sent 1783
zk_num_alive_connections        2
zk_outstanding_requests 0
zk_server_state leader
zk_znode_count  135
zk_watch_count  8
zk_ephemerals_count     3
zk_approximate_data_size        42533
zk_key_arena_size       28672
zk_latest_snapshot_size 0
zk_open_file_descriptor_count   182
zk_max_file_descriptor_count    18446744073709551615
zk_followers    2
zk_synced_followers     2

启动 ClickHouse 服务器

chnode1chnode 上运行:
sudo service clickhouse-server start
sudo service clickhouse-server status

验证

验证磁盘配置

system.disks 中应包含每个磁盘对应的记录:
  • default
  • gcs
  • cache
SELECT *
FROM system.disks
FORMAT Vertical
Row 1:
──────
name:             cache
path:             /var/lib/clickhouse/disks/gcs/
free_space:       18446744073709551615
total_space:      18446744073709551615
unreserved_space: 18446744073709551615
keep_free_space:  0
type:             s3
is_encrypted:     0
is_read_only:     0
is_write_once:    0
is_remote:        1
is_broken:        0
cache_path:       /var/lib/clickhouse/disks/gcs_cache/

Row 2:
──────
name:             default
path:             /var/lib/clickhouse/
free_space:       6555529216
total_space:      10331889664
unreserved_space: 6555529216
keep_free_space:  0
type:             local
is_encrypted:     0
is_read_only:     0
is_write_once:    0
is_remote:        0
is_broken:        0
cache_path:

Row 3:
──────
name:             gcs
path:             /var/lib/clickhouse/disks/gcs/
free_space:       18446744073709551615
total_space:      18446744073709551615
unreserved_space: 18446744073709551615
keep_free_space:  0
type:             s3
is_encrypted:     0
is_read_only:     0
is_write_once:    0
is_remote:        1
is_broken:        0
cache_path:

3 rows in set. Elapsed: 0.002 sec.

验证在集群上创建的表是否已在两个节点上创建成功

create table trips on cluster 'cluster_1S_2R' (
 `trip_id` UInt32,
 `pickup_date` Date,
 `pickup_datetime` DateTime,
 `dropoff_datetime` DateTime,
 `pickup_longitude` Float64,
 `pickup_latitude` Float64,
 `dropoff_longitude` Float64,
 `dropoff_latitude` Float64,
 `passenger_count` UInt8,
 `trip_distance` Float64,
 `tip_amount` Float32,
 `total_amount` Float32,
 `payment_type` Enum8('UNK' = 0, 'CSH' = 1, 'CRE' = 2, 'NOC' = 3, 'DIS' = 4))
ENGINE = ReplicatedMergeTree
PARTITION BY toYYYYMM(pickup_date)
ORDER BY pickup_datetime
SETTINGS storage_policy='gcs_main'
┌─host───────────────────────────────────────┬─port─┬─status─┬─error─┬─num_hosts_remaining─┬─num_hosts_active─┐
│ chnode2.us-east4-c.c.gcsqa-375100.internal │ 9000 │      0 │       │                   1 │                1 │
└────────────────────────────────────────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘
┌─host───────────────────────────────────────┬─port─┬─status─┬─error─┬─num_hosts_remaining─┬─num_hosts_active─┐
│ chnode1.us-east1-b.c.gcsqa-375100.internal │ 9000 │      0 │       │                   0 │                0 │
└────────────────────────────────────────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘

2 rows in set. Elapsed: 0.641 sec.

验证数据可成功插入

INSERT INTO trips SELECT
    trip_id,
    pickup_date,
    pickup_datetime,
    dropoff_datetime,
    pickup_longitude,
    pickup_latitude,
    dropoff_longitude,
    dropoff_latitude,
    passenger_count,
    trip_distance,
    tip_amount,
    total_amount,
    payment_type
FROM s3('https://ch-nyc-taxi.s3.eu-west-3.amazonaws.com/tsv/trips_{0..9}.tsv.gz', 'TabSeparatedWithNames')
LIMIT 1000000

验证该表是否使用存储策略 gcs_main

SELECT
    engine,
    data_paths,
    metadata_path,
    storage_policy,
    formatReadableSize(total_bytes)
FROM system.tables
WHERE name = 'trips'
FORMAT Vertical
Row 1:
──────
engine:                          ReplicatedMergeTree
data_paths:                      ['/var/lib/clickhouse/disks/gcs/store/631/6315b109-d639-4214-a1e7-afbd98f39727/']
metadata_path:                   /var/lib/clickhouse/store/e0f/e0f3e248-7996-44d4-853e-0384e153b740/trips.sql
storage_policy:                  gcs_main
formatReadableSize(total_bytes): 36.42 MiB

1 row in set. Elapsed: 0.002 sec.

在 Google Cloud Console 中验证

查看这些存储桶时,你会看到系统已在每个存储桶中创建了一个文件夹,名称与 storage.xml 配置文件中使用的名称相同。展开这些文件夹后,你会看到许多文件,对应各个数据分区。

副本一的存储桶

副本二的存储桶

最后修改于 2026年6月10日