跳至主要内容

将 Google Cloud Storage 与 ClickHouse 集成

注意

如果您在 Google Cloud 上使用 ClickHouse Cloud,此页面不适用,因为您的服务将已经使用 Google Cloud Storage。如果您想从 GCS SELECTINSERT 数据,请参阅 gcs 表函数

ClickHouse 认识到 GCS 是用户寻求分离存储和计算的理想存储解决方案。为了实现这一点,ClickHouse 提供了将 GCS 用作 MergeTree 引擎存储的支持。这将使用户能够利用 GCS 的可扩展性和成本效益,以及 MergeTree 引擎的插入和查询性能。

GCS 支持的 MergeTree

创建磁盘

要将 GCS 存储桶用作磁盘,我们首先必须在 conf.d 下的文件中,在 ClickHouse 配置中声明它。下面显示了 GCS 磁盘声明的示例。此配置包含多个部分来配置 GCS "磁盘"、缓存和在 DDL 查询中指定用于在 GCS 磁盘上创建表的策略。下面将分别描述这些内容。

storage_configuration > disks > gcs

配置的这部分显示在突出显示的部分中,并指定了以下内容:

  • 不执行批量删除。GCS 目前不支持批量删除,因此禁用自动检测以抑制错误消息。
  • 磁盘的类型是 s3,因为正在使用 S3 API。
  • GCS 提供的端点
  • 服务帐户 HMAC 密钥和秘密
  • 本地磁盘上的元数据路径
<clickhouse>
<storage_configuration>
<disks>
<gcs>
<support_batch_delete>false</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>

storage_configuration > disks > cache

下面突出显示的示例配置为磁盘 gcs 启用了 10Gi 内存缓存。

<clickhouse>
<storage_configuration>
<disks>
<gcs>
<support_batch_delete>false</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>

storage_configuration > policies > gcs_main

存储配置策略允许选择数据存储的位置。下面突出显示的策略通过指定策略 gcs_main 允许将数据存储在磁盘 gcs 上。例如,CREATE TABLE ... SETTINGS storage_policy='gcs_main'

<clickhouse>
<storage_configuration>
<disks>
<gcs>
<support_batch_delete>false</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 出租车列的子集并将数据直接流式传输到 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;

处理复制

可以使用 ReplicatedMergeTree 表引擎实现使用 GCS 磁盘的复制。有关详细信息,请参见 跨两个 GCP 区域复制单个分片使用 GCS 指南。

了解更多

Cloud Storage XML API 与某些工具和库可以互操作,这些工具和库与 Amazon Simple Storage Service (Amazon S3) 等服务一起使用。

有关调整线程的更多信息,请参见 性能优化

使用 Google Cloud Storage (GCS)

提示

对象存储在 ClickHouse Cloud 中默认使用,如果您在 ClickHouse Cloud 中运行,则无需执行此操作。

规划部署

本教程旨在描述在 Google Cloud 中运行并使用 Google Cloud Storage (GCS) 作为 ClickHouse 存储磁盘 "类型" 的复制 ClickHouse 部署。

在本教程中,您将在 Google Cloud Engine VM 中部署 ClickHouse 服务器节点,每个节点都与一个用于存储的关联 GCS 存储桶相关联。复制由一组 ClickHouse Keeper 节点协调,这些节点也作为 VM 部署。

高可用性的示例要求

  • 两个 ClickHouse 服务器节点,位于两个 GCP 区域
  • 两个 GCS 存储桶,部署在与两个 ClickHouse 服务器节点相同的区域
  • 三个 ClickHouse Keeper 节点,其中两个节点部署在与 ClickHouse 服务器节点相同的区域。第三个节点可以与前两个 Keeper 节点中的一个位于同一个区域,但位于不同的可用区。

ClickHouse Keeper 需要两个节点才能正常工作,因此需要三个节点才能实现高可用性。

准备 VM

在三个区域部署五个 VM

区域ClickHouse 服务器存储桶ClickHouse Keeper
1chnode1bucket_regionnamekeepernode1
2chnode2bucket_regionnamekeepernode2
3 *keepernode3

* 这可以是与 1 或 2 相同的区域中的不同可用区。

部署 ClickHouse

在两个主机上部署 ClickHouse,在示例配置中,这些主机名为 chnode1chnode2

chnode1 放置在一个 GCP 区域,将 chnode2 放置在另一个区域。在本指南中,us-east1us-east4 用于计算引擎 VM,也用于 GCS 存储桶。

注意

在配置 ClickHouse 服务器之前不要启动它。只需安装它即可。

在 ClickHouse 服务器节点上执行部署步骤时,请参考 安装说明

部署 ClickHouse Keeper

在三个主机上部署 ClickHouse Keeper,在示例配置中,这些主机名为 keepernode1keepernode2keepernode3keepernode1 可以部署在与 chnode1 相同的区域,keepernode2 可以部署在与 chnode2 相同的区域,keepernode3 可以部署在任何区域,但位于该区域中 ClickHouse 节点的不同可用区。

在 ClickHouse Keeper 节点上执行部署步骤时,请参考 安装说明

创建两个存储桶

两个 ClickHouse 服务器将位于不同的区域以实现高可用性。每个服务器将在同一个区域中拥有一个 GCS 存储桶。

Cloud Storage > 存储桶 中选择 创建存储桶。对于本教程,将创建两个存储桶,一个位于 us-east1,另一个位于 us-east4。存储桶是单区域的、标准存储类别,并且不公开。出现提示时,请启用公共访问预防。不要创建文件夹,它们将在 ClickHouse 写入存储时创建。

如果您需要创建存储桶和 HMAC 密钥的逐步说明,请展开 **创建 GCS 存储桶和 HMAC 密钥** 并按照说明进行操作。

创建 GCS 存储桶和 HMAC 密钥

ch_bucket_us_east1

Add a bucket

ch_bucket_us_east4

Add a bucket

生成访问密钥

创建服务帐户 HMAC 密钥和密钥

打开 **云存储 > 设置 > 互操作性** 并选择现有 **访问密钥** 或 **为服务帐户创建密钥**。本指南涵盖为新服务帐户创建新密钥的路径。

Add a bucket

添加新服务帐户

如果这是一个没有现有服务帐户的项目,请 **创建新帐户**。

Add a bucket

创建服务帐户需要三个步骤,在第一步中,请为帐户提供有意义的名称、ID 和描述。

Add a bucket

在互操作性设置对话框中,建议使用 IAM 角色 **存储对象管理员** 角色;在第二步中选择该角色。

Add a bucket

第三步是可选的,在本指南中不使用。您可以根据自己的策略允许用户拥有这些权限。

Add a bucket

服务帐户 HMAC 密钥将显示出来。保存此信息,因为它将在 ClickHouse 配置中使用。

Add a bucket

配置 ClickHouse Keeper

所有 ClickHouse Keeper 节点都具有相同的配置文件,除了 server_id 行(下面第一行突出显示)。使用您的 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 Server

最佳实践

本指南中的一些步骤要求您将配置文件放在 /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 服务器的主机名和端口。默认配置文件包含示例集群定义,为了仅显示完全配置的集群,将 replace="true" 标签添加到 remote_servers 条目中,以便在将此配置与默认配置合并时,它替换 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 像访问 AWS S3 存储桶一样访问 GCS 存储桶。将需要此配置的两个副本,每个 ClickHouse 服务器节点一个副本。

应在下面的配置中进行这些替换。

这些替换在两个 ClickHouse 服务器节点之间有所不同

  • REPLICA 1 BUCKET 应设置为与服务器在同一区域的存储桶的名称
  • REPLICA 1 FOLDER 应在一个服务器上更改为 replica_1,而在另一个服务器上更改为 replica_2

这些替换在两个节点之间是通用的

  • access_key_id 应设置为之前生成的 HMAC 密钥
  • secret_access_key 应设置为之前生成的 HMAC 密钥
/etc/clickhouse-server/config.d/storage.xml
<clickhouse>
<storage_configuration>
<disks>
<gcs>
<support_batch_delete>false</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 节点上运行该命令,您将看到其中一个是领导者,另外两个是跟随者。

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 配置文件中使用的名称的文件夹。展开文件夹,您将看到许多文件,它们代表数据分区。

副本一的存储桶

replica one bucket

副本二的存储桶

replica two bucket