跳至主要内容

容错复制

描述

在此架构中,配置了五个服务器。两个用于托管数据的副本。另外三个服务器用于协调数据的复制。通过此示例,我们将创建一个数据库和表,这些数据库和表将使用 ReplicatedMergeTree 表引擎跨两个数据节点进行复制。

级别:基础

术语

副本

数据的副本。ClickHouse 始终至少拥有一个数据副本,因此副本的最小数量为一个。这是一个重要的细节,您可能不习惯将原始数据副本计为副本,但这是 ClickHouse 代码和文档中使用的术语。添加第二个数据副本可提供容错能力。

分片

数据的一个子集。ClickHouse 始终至少为您的数据提供一个分片,因此如果您不将数据拆分到多个服务器上,则您的数据将存储在一个分片中。如果单个服务器的容量不足,可以将数据跨多个服务器进行分片以分担负载。目标服务器由分片键确定,并在创建分布式表时定义。分片键可以是随机的,也可以是哈希函数的输出。涉及分片的部署示例将使用rand()作为分片键,并将提供有关何时以及如何选择其他分片键的更多信息。

分布式协调

ClickHouse Keeper 为数据复制和分布式 DDL 查询执行提供协调系统。ClickHouse Keeper 与 Apache ZooKeeper 兼容。

环境

架构图

Architecture diagram for 1 shard and 2 replicas with ReplicatedMergeTree

节点描述
clickhouse-01数据
clickhouse-02数据
clickhouse-keeper-01分布式协调
clickhouse-keeper-02分布式协调
clickhouse-keeper-03分布式协调
注意

在生产环境中,我们强烈建议为 ClickHouse Keeper 使用专用主机。在测试环境中,可以在同一服务器上组合运行 ClickHouse 服务器和 ClickHouse Keeper。另一个基本示例,“横向扩展”使用了这种方法。在此示例中,我们介绍了将 Keeper 与 ClickHouse 服务器分离的推荐方法。Keeper 服务器可以更小,每个 Keeper 服务器通常只需要 4GB RAM,直到您的 ClickHouse 服务器变得非常大。

安装

在两台服务器clickhouse-01clickhouse-02上安装 ClickHouse 服务器和客户端,请按照您的归档类型说明(.deb、.rpm、.tar.gz 等)进行操作。

在三台服务器clickhouse-keeper-01clickhouse-keeper-02clickhouse-keeper-03上安装 ClickHouse Keeper,请按照您的归档类型说明(.deb、.rpm、.tar.gz 等)进行操作。

编辑配置文件

最佳实践

通过添加或编辑配置文件来配置 ClickHouse 服务器时,您应该

  • 将文件添加到/etc/clickhouse-server/config.d/目录
  • 将文件添加到/etc/clickhouse-server/users.d/目录
  • 保持/etc/clickhouse-server/config.xml文件不变
  • 保持/etc/clickhouse-server/users.xml文件不变

clickhouse-01 配置

对于 clickhouse-01,有五个配置文件。您可以选择将这些文件合并到一个文件中,但为了文档的清晰起见,单独查看它们可能更简单。在阅读配置文件时,您会发现 clickhouse-01 和 clickhouse-02 之间的大部分配置都是相同的;差异将突出显示。

网络和日志记录配置

您可以根据需要自定义这些值。此示例配置为您提供

  • 一个调试日志,该日志将在 1000M 处翻转三次
  • 使用clickhouse-client连接时显示的名称为cluster_1S_2R node 1
  • ClickHouse 将在 IPV4 网络的 8123 和 9000 端口上侦听。
/etc/clickhouse-server/config.d/network-and-logging.xml 在 clickhouse-01 上
<clickhouse>
<logger>
<level>debug</level>
<log>/var/log/clickhouse-server/clickhouse-server.log</log>
<errorlog>/var/log/clickhouse-server/clickhouse-server.err.log</errorlog>
<size>1000M</size>
<count>3</count>
</logger>
<display_name>cluster_1S_2R node 1</display_name>
<listen_host>0.0.0.0</listen_host>
<http_port>8123</http_port>
<tcp_port>9000</tcp_port>
</clickhouse>

宏配置

shardreplica降低了分布式 DDL 的复杂性。配置的值会自动替换到您的 DDL 查询中,从而简化您的 DDL。此配置的宏指定每个节点的分片和副本编号。
在此 1 分片 2 副本示例中,clickhouse-01 上的副本宏为replica_1,clickhouse-02 上的副本宏为replica_2。由于只有一个分片,因此 clickhouse-01 和 clickhouse-02 上的分片宏均为1

/etc/clickhouse-server/config.d/macros.xml 在 clickhouse-01 上
<clickhouse>
<macros>
<shard>01</shard>
<replica>01</replica>
<cluster>cluster_1S_2R</cluster>
</macros>
</clickhouse>

复制和分片配置

从顶部开始

  • XML 的remote_servers部分指定了环境中的每个集群。属性replace=true将默认 ClickHouse 配置中的示例remote_servers替换为此文件中指定的remote_server配置。如果没有此属性,则此文件中的远程服务器将附加到默认服务器列表中。
  • 在此示例中,有一个名为cluster_1S_2R的集群。
  • 为名为cluster_1S_2R的集群创建了一个值为mysecretphrase的密钥。该密钥在环境中的所有远程服务器之间共享,以确保将正确的服务器连接在一起。
  • 集群cluster_1S_2R有一个分片和两个副本。查看本文档开头的架构图,并将其与下面的 XML 中的shard定义进行比较。分片定义包含两个副本。指定了每个副本的主机和端口。一个副本存储在clickhouse-01上,另一个副本存储在clickhouse-02上。
  • 分片的内部复制设置为 true。每个分片都可以在配置文件中定义internal_replication参数。如果此参数设置为 true,则写入操作将选择第一个正常的副本并将数据写入该副本。
/etc/clickhouse-server/config.d/remote-servers.xml 在 clickhouse-01 上
<clickhouse>
<remote_servers replace="true">
<cluster_1S_2R>
<secret>mysecretphrase</secret>
<shard>
<internal_replication>true</internal_replication>
<replica>
<host>clickhouse-01</host>
<port>9000</port>
</replica>
<replica>
<host>clickhouse-02</host>
<port>9000</port>
</replica>
</shard>
</cluster_1S_2R>
</remote_servers>
</clickhouse>

配置 Keeper 的使用

此配置文件use-keeper.xml正在配置 ClickHouse 服务器以使用 ClickHouse Keeper 来协调复制和分布式 DDL。此文件指定 ClickHouse 服务器应在 9181 端口上的 clickhouse-keeper-01 - 03 节点上使用 Keeper,并且该文件在clickhouse-01clickhouse-02上相同。

/etc/clickhouse-server/config.d/use-keeper.xml 在 clickhouse-01 上
<clickhouse>
<zookeeper>
<!-- where are the ZK nodes -->
<node>
<host>clickhouse-keeper-01</host>
<port>9181</port>
</node>
<node>
<host>clickhouse-keeper-02</host>
<port>9181</port>
</node>
<node>
<host>clickhouse-keeper-03</host>
<port>9181</port>
</node>
</zookeeper>
</clickhouse>

clickhouse-02 配置

由于 clickhouse-01 和 clickhouse-02 上的配置非常相似,因此此处仅指出差异。

网络和日志配置

此文件在 clickhouse-01 和 clickhouse-02 上相同,除了 display_name

/etc/clickhouse-server/config.d/network-and-logging.xml 在 clickhouse-02 上
<clickhouse>
<logger>
<level>debug</level>
<log>/var/log/clickhouse-server/clickhouse-server.log</log>
<errorlog>/var/log/clickhouse-server/clickhouse-server.err.log</errorlog>
<size>1000M</size>
<count>3</count>
</logger>
<display_name>cluster_1S_2R node 2</display_name>
<listen_host>0.0.0.0</listen_host>
<http_port>8123</http_port>
<tcp_port>9000</tcp_port>
</clickhouse>

宏配置

宏配置在 clickhouse-01 和 clickhouse-02 之间有所不同。此节点上的 replica 设置为 02

/etc/clickhouse-server/config.d/macros.xml 在 clickhouse-02 上
<clickhouse>
<macros>
<shard>01</shard>
<replica>02</replica>
<cluster>cluster_1S_2R</cluster>
</macros>
</clickhouse>

复制和分片配置

此文件在 clickhouse-01 和 clickhouse-02 上相同。

/etc/clickhouse-server/config.d/remote-servers.xml 在 clickhouse-02 上
<clickhouse>
<remote_servers replace="true">
<cluster_1S_2R>
<secret>mysecretphrase</secret>
<shard>
<internal_replication>true</internal_replication>
<replica>
<host>clickhouse-01</host>
<port>9000</port>
</replica>
<replica>
<host>clickhouse-02</host>
<port>9000</port>
</replica>
</shard>
</cluster_1S_2R>
</remote_servers>
</clickhouse>

配置 Keeper 的使用

此文件在 clickhouse-01 和 clickhouse-02 上相同。

/etc/clickhouse-server/config.d/use-keeper.xml 在 clickhouse-02 上
<clickhouse>
<zookeeper>
<!-- where are the ZK nodes -->
<node>
<host>clickhouse-keeper-01</host>
<port>9181</port>
</node>
<node>
<host>clickhouse-keeper-02</host>
<port>9181</port>
</node>
<node>
<host>clickhouse-keeper-03</host>
<port>9181</port>
</node>
</zookeeper>
</clickhouse>

clickhouse-keeper-01 配置

最佳实践

通过编辑配置文件配置 ClickHouse Keeper 时,您应该

  • 备份 /etc/clickhouse-keeper/keeper_config.xml
  • 编辑 /etc/clickhouse-keeper/keeper_config.xml 文件

ClickHouse Keeper 为数据复制和分布式 DDL 查询执行提供协调系统。ClickHouse Keeper 与 Apache ZooKeeper 兼容。此配置在端口 9181 上启用 ClickHouse Keeper。突出显示的行指定此 Keeper 实例的 server_id 为 1。这是三个服务器上 enable-keeper.xml 文件中唯一的区别。clickhouse-keeper-02server_id 设置为 2,而 clickhouse-keeper-03server_id 设置为 3。Raft 配置部分在所有三个服务器上都相同,下面突出显示它以向您显示 server_id 与 raft 配置中的 server 实例之间的关系。

注意

如果由于任何原因替换或重建了 Keeper 节点,请不要重用现有的 server_id。例如,如果重建了 server_id2 的 Keeper 节点,请将其 server_id 设置为 4 或更高。

/etc/clickhouse-keeper/keeper_config.xml 在 clickhouse-keeper-01 上
<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>1</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>trace</raft_logs_level>
</coordination_settings>
<raft_configuration>
<server>
<id>1</id>
<hostname>clickhouse-keeper-01</hostname>
<port>9234</port>
</server>
<server>
<id>2</id>
<hostname>clickhouse-keeper-02</hostname>
<port>9234</port>
</server>
<server>
<id>3</id>
<hostname>clickhouse-keeper-03</hostname>
<port>9234</port>
</server>
</raft_configuration>
</keeper_server>
</clickhouse>

clickhouse-keeper-02 配置

clickhouse-keeper-01clickhouse-keeper-02 之间只有一行差异。此节点上的 server_id 设置为 2

/etc/clickhouse-keeper/keeper_config.xml 在 clickhouse-keeper-02 上
<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>2</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>trace</raft_logs_level>
</coordination_settings>
<raft_configuration>
<server>
<id>1</id>
<hostname>clickhouse-keeper-01</hostname>
<port>9234</port>
</server>
<server>
<id>2</id>
<hostname>clickhouse-keeper-02</hostname>
<port>9234</port>
</server>
<server>
<id>3</id>
<hostname>clickhouse-keeper-03</hostname>
<port>9234</port>
</server>
</raft_configuration>
</keeper_server>
</clickhouse>

clickhouse-keeper-03 配置

clickhouse-keeper-01clickhouse-keeper-03 之间只有一行差异。此节点上的 server_id 设置为 3

/etc/clickhouse-keeper/keeper_config.xml 在 clickhouse-keeper-03 上
<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>trace</raft_logs_level>
</coordination_settings>
<raft_configuration>
<server>
<id>1</id>
<hostname>clickhouse-keeper-01</hostname>
<port>9234</port>
</server>
<server>
<id>2</id>
<hostname>clickhouse-keeper-02</hostname>
<port>9234</port>
</server>
<server>
<id>3</id>
<hostname>clickhouse-keeper-03</hostname>
<port>9234</port>
</server>
</raft_configuration>
</keeper_server>
</clickhouse>

测试

要获得使用 ReplicatedMergeTree 和 ClickHouse Keeper 的经验,您可以运行以下命令,这些命令将使您

  • 在上面配置的集群上创建数据库
  • 使用 ReplicatedMergeTree 表引擎在数据库上创建表
  • 在一个节点上插入数据并在另一个节点上查询它
  • 停止一个 ClickHouse 服务器节点
  • 在正在运行的节点上插入更多数据
  • 重新启动已停止的节点
  • 验证在查询重新启动的节点时数据是否可用

验证 ClickHouse Keeper 是否正在运行

mntr 命令用于验证 ClickHouse Keeper 是否正在运行,并获取有关三个 Keeper 节点之间关系的状态信息。在此示例中使用的配置中有三个节点协同工作。这些节点将选举一个领导者,其余节点将成为跟随者。mntr 命令提供与性能相关的信息,以及特定节点是跟随者还是领导者。

提示

您可能需要安装 netcat 才能将 mntr 命令发送到 Keeper。有关下载信息,请参阅 nmap.org 页面。

从 clickhouse-keeper-01、clickhouse-keeper-02 和 clickhouse-keeper-03 上的 shell 运行
echo mntr | nc localhost 9181
来自跟随者的响应
zk_version  v23.3.1.2823-testing-46e85357ce2da2a99f56ee83a079e892d7ec3726
zk_avg_latency 0
zk_max_latency 0
zk_min_latency 0
zk_packets_received 0
zk_packets_sent 0
zk_num_alive_connections 0
zk_outstanding_requests 0
zk_server_state follower
zk_znode_count 6
zk_watch_count 0
zk_ephemerals_count 0
zk_approximate_data_size 1271
zk_key_arena_size 4096
zk_latest_snapshot_size 0
zk_open_file_descriptor_count 46
zk_max_file_descriptor_count 18446744073709551615
来自领导者的响应
zk_version  v23.3.1.2823-testing-46e85357ce2da2a99f56ee83a079e892d7ec3726
zk_avg_latency 0
zk_max_latency 0
zk_min_latency 0
zk_packets_received 0
zk_packets_sent 0
zk_num_alive_connections 0
zk_outstanding_requests 0
zk_server_state leader
zk_znode_count 6
zk_watch_count 0
zk_ephemerals_count 0
zk_approximate_data_size 1271
zk_key_arena_size 4096
zk_latest_snapshot_size 0
zk_open_file_descriptor_count 48
zk_max_file_descriptor_count 18446744073709551615
zk_followers 2
zk_synced_followers 2

验证 ClickHouse 集群功能

在一个 shell 中使用 clickhouse client 连接到节点 clickhouse-01,并在另一个 shell 中使用 clickhouse client 连接到节点 clickhouse-02

  1. 在上面配置的集群上创建数据库
在 clickhouse-01 或 clickhouse-02 节点上运行
CREATE DATABASE db1 ON CLUSTER cluster_1S_2R
┌─host──────────┬─port─┬─status─┬─error─┬─num_hosts_remaining─┬─num_hosts_active─┐
│ clickhouse-02 │ 9000 │ 0 │ │ 1 │ 0 │
│ clickhouse-01 │ 9000 │ 0 │ │ 0 │ 0 │
└───────────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘
  1. 使用 ReplicatedMergeTree 表引擎在数据库上创建表
在 clickhouse-01 或 clickhouse-02 节点上运行
CREATE TABLE db1.table1 ON CLUSTER cluster_1S_2R
(
`id` UInt64,
`column1` String
)
ENGINE = ReplicatedMergeTree
ORDER BY id
┌─host──────────┬─port─┬─status─┬─error─┬─num_hosts_remaining─┬─num_hosts_active─┐
│ clickhouse-02 │ 9000 │ 0 │ │ 1 │ 0 │
│ clickhouse-01 │ 9000 │ 0 │ │ 0 │ 0 │
└───────────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘
  1. 在一个节点上插入数据并在另一个节点上查询它
在 clickhouse-01 节点上运行
INSERT INTO db1.table1 (id, column1) VALUES (1, 'abc');
  1. 在节点 clickhouse-02 上查询表
在 clickhouse-02 节点上运行
SELECT *
FROM db1.table1
┌─id─┬─column1─┐
│ 1 │ abc │
└────┴─────────┘
  1. 在另一个节点上插入数据并在节点 clickhouse-01 上查询它
在 clickhouse-02 节点上运行
INSERT INTO db1.table1 (id, column1) VALUES (2, 'def');
在 clickhouse-01 节点上运行
SELECT *
FROM db1.table1
┌─id─┬─column1─┐
│ 1 │ abc │
└────┴─────────┘
┌─id─┬─column1─┐
│ 2 │ def │
└────┴─────────┘
  1. 停止一个 ClickHouse 服务器节点 通过运行类似于启动节点的命令的操作系统命令来停止一个 ClickHouse 服务器节点。如果您使用 systemctl start 启动节点,则使用 systemctl stop 停止它。

  2. 在正在运行的节点上插入更多数据

在正在运行的节点上运行
INSERT INTO db1.table1 (id, column1) VALUES (3, 'ghi');

选择数据

在正在运行的节点上运行
SELECT *
FROM db1.table1
┌─id─┬─column1─┐
│ 1 │ abc │
└────┴─────────┘
┌─id─┬─column1─┐
│ 2 │ def │
└────┴─────────┘
┌─id─┬─column1─┐
│ 3 │ ghi │
└────┴─────────┘
  1. 重新启动已停止的节点并从中选择
在重新启动的节点上运行
SELECT *
FROM db1.table1
┌─id─┬─column1─┐
│ 1 │ abc │
└────┴─────────┘
┌─id─┬─column1─┐
│ 2 │ def │
└────┴─────────┘
┌─id─┬─column1─┐
│ 3 │ ghi │
└────┴─────────┘