将 Google Cloud Storage 与 ClickHouse 集成
如果您正在 Google Cloud 上使用 ClickHouse 云平台,则此页面不适用,因为您的服务已经在使用 Google Cloud Storage。如果您希望从 GCS 中 SELECT
或 INSERT
数据,请参阅 gcs
表函数。
ClickHouse 认识到 GCS 代表着一种有吸引力的存储解决方案,适用于寻求分离存储和计算的用户。为了帮助实现这一点,提供了对使用 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
# highlight-next-line
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 区域中复制单个分片指南。
了解更多
云存储 XML API可以与某些工具和库互操作,这些工具和库适用于诸如 Amazon Simple Storage Service (Amazon S3) 之类的服务。
有关调整线程的更多信息,请参阅性能优化。
使用 Google Cloud Storage (GCS)
对象存储在 ClickHouse 云平台中默认使用,如果您在 ClickHouse 云平台中运行,则无需遵循此程序。
规划部署
本教程旨在描述在 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 需要两个节点才能运行,因此,高可用性需要三个节点。
准备虚拟机
在三个区域中部署五个虚拟机
区域 | ClickHouse 服务器 | 存储桶 | ClickHouse Keeper |
---|---|---|---|
1 | chnode1 | bucket_regionname | keepernode1 |
2 | chnode2 | bucket_regionname | keepernode2 |
3 * | keepernode3 |
*
这可以是与 1 或 2 相同的区域中的不同可用区。
部署 ClickHouse
在两台主机上部署 ClickHouse,在示例配置中,这些主机被命名为 chnode1
、chnode2
。
将 chnode1
放置在一个 GCP 区域中,将 chnode2
放置在第二个区域中。在本指南中,us-east1
和 us-east4
用于计算引擎 VM,也用于 GCS 存储桶。
在配置完成之前,请勿启动 clickhouse server
。只需安装它。
在 ClickHouse 服务器节点上执行部署步骤时,请参阅安装说明。
部署 ClickHouse Keeper
在三台主机上部署 ClickHouse Keeper,在示例配置中,这些主机被命名为 keepernode1
、keepernode2
和 keepernode3
。keepernode1
可以与 chnode1
部署在同一区域中,keepernode2
与 chnode2
部署在同一区域中,keepernode3
可以与任一区域部署在同一区域中,但在与该区域中的 ClickHouse 节点不同的可用区中。
在 ClickHouse Keeper 节点上执行部署步骤时,请参阅安装说明。
创建两个存储桶
为了实现高可用性,两个 ClickHouse 服务器将位于不同的区域中。每个服务器将在同一区域中都有一个 GCS 存储桶。
在云存储 > 存储桶中,选择创建存储桶。在本教程中,创建了两个存储桶,每个存储桶分别位于 us-east1
和 us-east4
中。存储桶是单区域、标准存储类且不公开的。出现提示时,启用公共访问预防。不要创建文件夹,当 ClickHouse 写入存储时,将创建文件夹。
如果您需要创建存储桶和 HMAC 密钥的分步说明,请展开创建 GCS 存储桶和 HMAC 密钥并按照说明进行操作
创建 GCS 存储桶和 HMAC 密钥
ch_bucket_us_east1
ch_bucket_us_east4
生成访问密钥
创建服务帐户 HMAC 密钥和密钥
打开云存储 > 设置 > 互操作性,然后选择现有的访问密钥,或者选择为服务帐户创建密钥。本指南介绍了为新服务帐户创建新密钥的路径。
添加新服务帐户
如果这是一个没有现有服务帐户的项目,请选择创建新帐户。
创建服务帐户有三个步骤,第一步是为帐户提供有意义的名称、ID 和描述。
在互操作性设置对话框中,建议使用 IAM 角色存储对象管理员角色;在第二步中选择该角色。
第三步是可选的,在本指南中未使用。您可以根据您的策略允许用户拥有这些特权。
将显示服务帐户 HMAC 密钥。保存此信息,因为它将在 ClickHouse 配置中使用。
配置 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
<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 侦听环回接口,在复制设置中,机器之间的网络连接是必需的。监听所有接口
<clickhouse>
<listen_host>0.0.0.0</listen_host>
</clickhouse>
远程 ClickHouse Keeper 服务器
复制由 ClickHouse Keeper 协调。此配置文件通过主机名和端口号标识 ClickHouse Keeper 节点。
- 编辑主机名以匹配您的 Keeper 主机
<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 服务器节点解析
<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
。名称可以更改,根据我们的示例,一个副本存储在南卡罗来纳州,另一个副本存储在弗吉尼亚州北部,这些值可以是 carolina
和 virginia
;只需确保它们在每台计算机上都不同。
<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 存储配置包括 disks
和 policies
。下面配置的磁盘名为 gcs
,类型为 s3
。类型为 s3,因为 ClickHouse 访问 GCS 存储桶时,就好像它是 AWS S3 存储桶一样。将需要此配置的两个副本,每个 ClickHouse 服务器节点一个。
应在下面的配置中进行这些替换。
这两个 ClickHouse 服务器节点之间的替换有所不同
REPLICA 1 BUCKET
应设置为与服务器位于同一区域的存储桶的名称REPLICA 1 FOLDER
在其中一台服务器上应更改为replica_1
,在另一台服务器上应更改为replica_2
这些替换在两个节点之间是通用的
access_key_id
应设置为之前生成的 HMAC 密钥secret_access_key
应设置为之前生成的 HMAC 密钥密钥
<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 服务器
在 chnode1
和 chnode
上运行
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.
验证在集群上创建的表是否在两个节点上都已创建
# highlight-next-line
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
# highlight-next-line
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 控制台中验证
查看存储桶,您将看到在每个存储桶中都创建了一个文件夹,其名称是在 storage.xml
配置文件中使用的名称。展开文件夹,您将看到许多文件,代表数据分区。