ClickHouse Keeper(clickhouse-keeper)
本页不适用于 ClickHouse Cloud。此处所述流程已在 ClickHouse Cloud 服务中自动化完成。
ClickHouse Keeper 为数据复制和分布式 DDL 查询执行提供协调系统。ClickHouse Keeper 与 ZooKeeper 兼容。
实现细节
ZooKeeper 是最早广为人知的开源协调系统之一。它用 Java 实现,具有相当简单而强大的数据模型。ZooKeeper 的协调算法 ZooKeeper Atomic Broadcast (ZAB) 不为读操作提供线性一致性保证,因为每个 ZooKeeper 节点本地提供读服务。与 ZooKeeper 不同,ClickHouse Keeper 使用 C++ 编写,并采用 RAFT 算法的实现。该算法允许对读写操作提供线性一致性,并且在不同语言中有多种开源实现。
默认情况下,ClickHouse Keeper 提供与 ZooKeeper 相同的保证:线性一致的写入以及非线性一致的读取。它具有兼容的客户端-服务器协议,因此可以使用任何标准 ZooKeeper 客户端与 ClickHouse Keeper 交互。快照和日志的格式与 ZooKeeper 不兼容,但 clickhouse-keeper-converter 工具可以将 ZooKeeper 数据转换为 ClickHouse Keeper 快照。ClickHouse Keeper 的服务器间协议同样与 ZooKeeper 不兼容,因此无法构建混合的 ZooKeeper / ClickHouse Keeper 集群。
ClickHouse Keeper 以与 ZooKeeper 相同的方式支持访问控制列表 (ACL)。ClickHouse Keeper 支持相同的权限集合,并具有相同的内置方案:world、auth 和 digest。digest 认证方案使用 username:password 这一对值,其中密码以 Base64 编码。
不支持外部集成。
配置
ClickHouse Keeper 可以作为 ZooKeeper 的独立替代品,或作为 ClickHouse 服务器的内部组件使用。在这两种情况下,配置文件几乎相同,都是 .xml 文件。
Keeper 配置设置
ClickHouse Keeper 主要的配置标签是 <keeper_server>,并包含以下参数:
| Parameter | Description | Default |
|---|---|---|
tcp_port | 客户端连接使用的端口。 | 2181 |
tcp_port_secure | 客户端与 keeper-server 之间通过 SSL 连接使用的安全端口。 | - |
server_id | 唯一的服务器 ID,ClickHouse Keeper 集群中的每个节点都必须有唯一编号(1、2、3 等)。 | - |
log_storage_path | 协调日志的存储路径,与 ZooKeeper 一样,最好将日志存储在负载较低的节点上。 | - |
snapshot_storage_path | 协调快照的存储路径。 | - |
enable_reconfiguration | 通过 reconfig 启用动态集群重配置。 | False |
max_memory_usage_soft_limit | Keeper 最大内存使用量的软限制(字节)。 | max_memory_usage_soft_limit_ratio * physical_memory_amount |
max_memory_usage_soft_limit_ratio | 如果未设置 max_memory_usage_soft_limit 或将其设置为 0,则使用此值来定义默认软限制。 | 0.9 |
cgroups_memory_observer_wait_time | 如果未设置 max_memory_usage_soft_limit 或将其设置为 0,则使用该时间间隔监控物理内存大小。一旦内存大小发生变化,将通过 max_memory_usage_soft_limit_ratio 重新计算 Keeper 的内存软限制。 | 15 |
http_control | HTTP control 接口的配置。 | - |
digest_enabled | 启用实时数据一致性检查。 | True |
create_snapshot_on_exit | 在关闭期间创建快照。 | - |
hostname_checks_enabled | 为集群配置启用主机名合理性检查(例如,当 localhost 与远程端点一起使用时)。 | True |
four_letter_word_white_list | 4lw 命令的白名单。 | conf, cons, crst, envi, ruok, srst, srvr, stat, wchs, dirs, mntr, isro, rcvr, apiv, csnp, lgif, rqld, ydld |
enable_ipv6 | 启用 IPv6 | True |
其他常用参数继承自 ClickHouse 服务器配置(listen_host、logger 等)。
内部协调设置
内部协调设置位于 <keeper_server>.<coordination_settings> 部分,并包含以下参数:
| Parameter | Description | Default |
|---|---|---|
operation_timeout_ms | 单个客户端操作的超时时间(毫秒) | 10000 |
min_session_timeout_ms | 客户端会话的最小超时时间(毫秒) | 10000 |
session_timeout_ms | 客户端会话的最大超时时间(毫秒) | 100000 |
dead_session_check_period_ms | ClickHouse Keeper 检查并清理失效会话的周期(毫秒) | 500 |
heart_beat_interval_ms | ClickHouse Keeper 领导节点向跟随者发送心跳的时间间隔(毫秒) | 500 |
election_timeout_lower_bound_ms | 如果跟随者在该时间间隔内没有收到来自领导者的心跳,则可以发起领导者选举。必须小于或等于 election_timeout_upper_bound_ms。理想情况下,这两个值不应相等。 | 1000 |
election_timeout_upper_bound_ms | 如果跟随者在该时间间隔内没有收到来自领导者的心跳,则必须发起领导者选举。 | 2000 |
rotate_log_storage_interval | 单个文件中要存储的日志记录数量。 | 100000 |
reserved_log_items | 在压缩之前要保留的协调日志记录数量。 | 100000 |
snapshot_distance | ClickHouse Keeper 创建新快照的频率(按日志记录条数计)。 | 100000 |
snapshots_to_keep | 要保留的快照数量。 | 3 |
stale_log_gap | 领导者将跟随者视为“过期”,并向其发送快照而非日志时所使用的阈值。 | 10000 |
fresh_log_gap | 节点被认为重新变为“最新”的阈值。 | 200 |
max_requests_batch_size | 在发送到 RAFT 之前,请求批次中包含的最大请求数量。 | 100 |
force_sync | 每次写入协调日志时调用 fsync。 | true |
quorum_reads | 通过完整的 RAFT 共识机制,以类似写请求的速度执行读请求。 | false |
raft_logs_level | 协调相关文本日志的日志级别(trace、debug 等)。 | system default |
auto_forwarding | 允许将写请求从跟随者转发到领导者。 | true |
shutdown_timeout | 等待内部连接完成并关闭的时间(毫秒)。 | 5000 |
startup_timeout | 如果服务器在指定的超时时间内未能连接到其他仲裁参与者,则会终止(毫秒)。 | 30000 |
async_replication | 启用异步复制。在保留所有写入和读取保证的同时获得更好的性能。为避免破坏向后兼容性,该设置默认禁用。 | false |
latest_logs_cache_size_threshold | 最新日志条目的内存缓存的最大总大小。 | 1GiB |
commit_logs_cache_size_threshold | 为下一次提交所需日志条目的内存缓存的最大总大小。 | 500MiB |
disk_move_retries_wait_ms | 在一次磁盘间文件移动失败后,两次重试之间等待的时间(毫秒)。 | 1000 |
disk_move_retries_during_init | 在初始化期间,磁盘间文件移动失败后重试的次数。 | 100 |
experimental_use_rocksdb | 使用 RocksDB 作为后端存储 | 0 |
仲裁(quorum)配置位于 <keeper_server>.<raft_configuration> 部分中,并包含各服务器的配置说明。
整个仲裁范围内唯一的参数是 secure,用于为仲裁参与者之间的通信启用加密连接。如果内部节点间通信需要 SSL 连接,可以将该参数设置为 true,否则可以保持未指定。
每个 <server> 的主要参数为:
id— 仲裁中服务器的标识符。hostname— 部署该服务器的主机名。port— 该服务器监听连接的端口。can_become_leader— 设为false可将该服务器配置为learner。如果省略,则默认为true。
当 ClickHouse Keeper 集群的拓扑发生变化时(例如替换某个服务器),请务必保持 server_id 与 hostname 的映射关系一致,避免打乱顺序或在不同服务器之间复用已有的 server_id(例如,如果依赖自动化脚本部署 ClickHouse Keeper,就有可能发生这种情况)。
如果 Keeper 实例所在的主机可能发生变化,建议定义并使用主机名而不是原始 IP 地址。更改主机名等同于先移除该服务器再将其重新加入,在某些情况下这可能无法完成(例如 Keeper 实例数量不足以形成仲裁)。
async_replication 默认是禁用的,以避免破坏向后兼容性。如果集群中的所有 Keeper 实例都运行在支持 async_replication 的版本上(v23.9+),建议启用该功能,因为它可以在没有任何负面影响的情况下提升性能。
关于包含三个节点的仲裁配置示例,可以在带有 test_keeper_ 前缀的集成测试中找到。服务器 #1 的配置示例如下:
如何运行
ClickHouse Keeper 已打包在 ClickHouse 服务器安装包中,只需在 /etc/your_path_to_config/clickhouse-server/config.xml 中添加 <keeper_server> 的配置,然后像平常一样启动 ClickHouse 服务器即可。如果你想以独立方式运行 ClickHouse Keeper,可以通过类似的方式启动它:
如果尚未创建名为 clickhouse-keeper 的符号链接,可以手动创建,或者在运行 clickhouse 时将 keeper 作为参数指定:
四字母命令
ClickHouse Keeper 也提供了与 ZooKeeper 基本相同的 4lw 命令。每个命令由四个字母组成,例如 mntr、stat 等。其中有一些更为实用的命令:stat 提供关于服务器及其已连接客户端的一些通用信息,而 srvr 和 cons 则分别提供关于服务器和连接的详细信息。
4lw 命令有一个白名单配置项 four_letter_word_white_list,其默认值为 conf,cons,crst,envi,ruok,srst,srvr,stat,wchs,dirs,mntr,isro,rcvr,apiv,csnp,lgif,rqld,ydld。
你可以通过 telnet 或 nc 在客户端端口向 ClickHouse Keeper 发送这些命令。
下面是详细的 4lw 命令:
ruok:测试服务器是否在非错误状态下运行。如果服务器正在运行,则会响应imok,否则将完全不会有任何响应。imok的响应并不一定表示服务器已加入仲裁,只表明服务器进程处于活动状态并已绑定到指定的客户端端口。使用 "stat" 获取有关仲裁状态和客户端连接信息的详细内容。
mntr: 输出可用于监控集群健康状态的变量列表。
srvr: 显示服务器的完整详细信息。
stat: 列出服务器和已连接客户端的简要信息。
srst: 重置服务器统计信息。该命令会影响srvr、mntr和stat的结果。
conf: 输出服务配置的详细信息。
cons: 列出当前连接到此服务器的所有客户端的完整连接/会话详情。包括接收/发送的数据包数量、会话 ID、操作延迟、最近一次执行的操作等。
crst: 重置所有连接/会话的统计信息。
envi: 打印当前服务环境的详细信息
dirs: 显示快照和日志文件的总大小(字节)
isro: 检测服务器是否在只读模式下运行。如果处于只读模式,服务器将返回ro,否则返回rw。
wchs: 列出该服务器上的 watch 概要信息。
wchc: 按会话列出服务器上的监控项(watch)详细信息。该命令输出包含关联监控项(路径)的会话(连接)列表。注意:根据监控项数量的多少,此操作可能开销较大(影响服务器性能),请谨慎使用。
wchp: 按路径列出服务器上 watch 的详细信息。该命令会输出包含关联会话的路径(znode)列表。注意:根据 watch 数量的不同,此操作可能会开销较大(即影响服务器性能),请谨慎使用。
dump: 列出当前未完成的会话和临时节点。仅可在 leader 节点上使用。
csnp: 调度一个快照创建任务。成功时返回已提交日志中该快照的最后索引;失败时返回Failed to schedule snapshot creation task.。注意可以通过lgif命令来判断快照是否已完成。
lgif: Keeper 日志信息。first_log_idx:本节点在日志存储中的第一个日志索引;first_log_term:本节点的第一个日志任期(term);last_log_idx:本节点在日志存储中的最后一个日志索引;last_log_term:本节点的最后一个日志任期(term);last_committed_log_idx:本节点在状态机中最后一次提交的日志索引;leader_committed_log_idx:从本节点视角看到的 leader 已提交的日志索引;target_committed_log_idx:目标应提交到的日志索引;last_snapshot_idx:上一个快照中已提交的最大日志索引。
rqld: 请求成为新的 leader。若请求已发送则返回Sent leadership request to leader.,若请求未发送则返回Failed to send leadership request to leader.。注意,如果该节点已经是 leader,则结果与请求已发送时相同。
ftfl: 列出所有功能开关以及这些开关在该 Keeper 实例中是否已启用。
ydld:请求让出领导权并转为 follower 角色。如果接收该请求的服务器是 leader,它会先暂停写操作,等待继任者(当前 leader 本身永远不会被选为继任者)完成对最新日志的追赶,然后再辞去领导身份。继任者将自动选出。如果请求已发送,则返回Sent yield leadership request to leader.,如果请求未发送,则返回Failed to send yield leadership request to leader.。注意,如果节点已经是 follower,则效果等同于请求已成功发送。
pfev: 返回所有已收集事件的值。对于每个事件,返回事件名称、事件值以及事件描述。
HTTP 控制接口
ClickHouse Keeper 提供了一个 HTTP 接口,用于检查副本是否已准备好接收请求。它可用于云环境中,例如 Kubernetes。
启用 /ready 端点的配置示例:
功能开关(Feature flags)
Keeper 与 ZooKeeper 及其客户端完全兼容,但它也为 ClickHouse 客户端引入了一些独特的功能和请求类型。
由于这些功能可能会引入向后不兼容的变更,因此大多数功能默认处于禁用状态,可以通过 keeper_server.feature_flags 配置启用。
所有功能也都可以被显式禁用。
如果你想为 Keeper 集群启用某个新功能,我们建议你先将集群中所有 Keeper 实例更新到支持该功能的版本,然后再启用该功能本身。
下面是一个功能开关配置示例,其中禁用了 multi_read 并启用了 check_not_exists:
可用的功能如下:
| 功能 | 描述 | 默认值 |
|---|---|---|
multi_read | 支持多读(multi read)请求 | 1 |
filtered_list | 支持按节点类型(临时节点或持久节点)过滤结果的列表请求 | 1 |
check_not_exists | 支持 CheckNotExists 请求,用于断言某个节点不存在 | 1 |
create_if_not_exists | 支持 CreateIfNotExists 请求:如果节点不存在则尝试创建该节点;如果节点已存在,则不会应用任何更改,并返回 ZOK | 1 |
remove_recursive | 支持 RemoveRecursive 请求,用于删除该节点及其整个子树 | 1 |
从 25.7 版本开始,部分功能标志(feature flag)默认启用。
将 Keeper 升级到 25.7+ 的推荐方式是先升级到 24.9+ 版本。
从 ZooKeeper 迁移
无法实现从 ZooKeeper 到 ClickHouse Keeper 的无缝迁移。需要先停止 ZooKeeper 集群、转换数据,然后再启动 ClickHouse Keeper。clickhouse-keeper-converter 工具可将 ZooKeeper 日志和快照转换为 ClickHouse Keeper 快照。它仅适用于 ZooKeeper 3.4 及以上版本。迁移步骤如下:
-
停止所有 ZooKeeper 节点。
-
可选但推荐:找到 ZooKeeper 的 leader 节点,将其启动后再停止一次。这会强制 ZooKeeper 创建一致的快照。
-
在 leader 节点上运行
clickhouse-keeper-converter,例如:
- 将快照复制到已配置了
keeper的 ClickHouse 服务器节点上,或启动 ClickHouse Keeper 来替代 ZooKeeper。快照必须在所有节点上持久化保存,否则空节点可能启动得更快并成为 leader。
keeper-converter 工具在 Keeper 独立二进制文件中不可用。
如果已安装 ClickHouse,可以直接使用该二进制文件:
Otherwise, you can download the binary and run the tool as described above without installing ClickHouse.
在丢失法定人数后的恢复
由于 ClickHouse Keeper 使用 Raft,它可以在一定程度上容忍节点宕机,具体取决于集群规模。
例如,对于一个 3 节点集群,如果只有 1 个节点宕机,它仍然可以正常工作。
集群配置可以动态变更,但存在一些限制。重新配置同样依赖 Raft,
因此要向集群添加或移除节点,必须具备法定人数。如果在无法重启的情况下,集群中同时有太多节点宕机,
Raft 将停止工作,并且不允许你通过常规方式重新配置集群。
尽管如此,ClickHouse Keeper 提供了一种恢复模式,允许你仅使用 1 个节点强制重新配置集群。
只有在无法重新启动这些节点,或无法在相同端点上启动新的实例时,才应将该模式作为最后手段使用。
在继续之前需要注意的重要事项:
- 确保故障节点无法再次连接到集群。
- 在步骤中特别指出之前,不要启动任何新节点。
在确认上述事项之后,你需要执行以下操作:
- 选择一个 Keeper 节点作为新的 leader。请注意,将使用该节点上的数据作为整个集群的数据,因此建议选择状态最新的节点。
- 在执行任何其他操作之前,为选定节点的
log_storage_path和snapshot_storage_path目录创建备份。 - 在你计划继续使用的所有节点上重新配置集群。
- 向你选定的节点发送四字母命令
rcvr,它会将该节点切换到恢复模式;或者停止该节点上的 Keeper 实例,并使用--force-recovery参数重新启动。 - 依次启动新节点上的 Keeper 实例,在启动下一个节点之前,确保
mntr命令对zk_server_state的返回值为follower。 - 在恢复模式下,leader 节点在与新节点达成法定人数之前,会对
mntr命令返回错误信息,并拒绝来自客户端和 follower 的任何请求。 - 达成法定人数后,leader 节点会恢复到正常运行模式,使用 Raft 接受所有请求——可通过
mntr进行验证,此时zk_server_state应返回leader。
在 Keeper 中使用磁盘
Keeper 支持 外部磁盘 类型中的一部分,用于存储快照、日志文件和状态文件。
支持的磁盘类型包括:
- s3_plain
- s3
- local
下面是一个配置文件中磁盘定义的示例。
若要将某块磁盘用于日志,需将 keeper_server.log_storage_disk 配置设为该磁盘的名称。
若要将某块磁盘用于快照,需将 keeper_server.snapshot_storage_disk 配置设为该磁盘的名称。
此外,还可以通过分别使用 keeper_server.latest_log_storage_disk 和 keeper_server.latest_snapshot_storage_disk,为最新日志或快照使用不同的磁盘。
在这种情况下,当创建新的日志或快照时,Keeper 会自动将文件移动到正确的磁盘上。
若要将某块磁盘用于状态文件,需将 keeper_server.state_storage_disk 配置设为该磁盘的名称。
在磁盘之间移动文件是安全的,即使 Keeper 在传输中途停止,也不会有数据丢失的风险。 在文件完全移动到新磁盘之前,不会从旧磁盘上删除。
当 keeper_server.coordination_settings.force_sync 被设置为 true(默认即为 true)时,Keeper 无法在所有类型的磁盘上都满足某些一致性保证。
目前,只有类型为 local 的磁盘支持持久同步。
如果使用 force_sync 且未使用 latest_log_storage_disk,则 log_storage_disk 必须是 local 磁盘。
如果使用了 latest_log_storage_disk,则它必须始终是 local 磁盘。
如果禁用 force_sync,则在任意配置中都可以使用任意类型的磁盘。
Keeper 实例的一种可能存储配置如下所示:
此实例会将除最新日志外的所有日志存储在 log_s3_plain 磁盘上,而最新日志将存储在 log_local 磁盘上。
同样的逻辑也适用于快照:除最新快照外的所有快照将存储在 snapshot_s3_plain 磁盘上,而最新快照将存储在 snapshot_local 磁盘上。
更改磁盘配置
在应用新的磁盘配置之前,请手动备份所有 Keeper 日志和快照。
如果定义了分层磁盘配置(为最新文件使用单独的磁盘),Keeper 会在启动时尝试自动将文件移动到正确的磁盘。 仍然提供与之前相同的保证:在文件完全移动到新磁盘之前,不会从旧磁盘上删除它,因此可以安全地多次重启。
如果需要将文件移动到一块全新的磁盘(或从双磁盘配置迁移到单磁盘配置),可以使用多个 keeper_server.old_snapshot_storage_disk 和 keeper_server.old_log_storage_disk 定义。
以下配置展示了如何从之前的双磁盘配置迁移到一个全新的单磁盘配置:
在启动时,所有日志文件都会从 log_local 和 log_s3_plain 移动到 log_local2 磁盘。
同样,所有快照文件都会从 snapshot_local 和 snapshot_s3_plain 移动到 snapshot_local2 磁盘。
配置日志缓存
为了尽量减少从磁盘读取的数据量,Keeper 会在内存中缓存日志条目。 如果请求很大,日志条目会占用过多内存,因此缓存的日志数据量会被限制。 该限制由以下两个配置项控制:
latest_logs_cache_size_threshold- 缓存中存储的最新日志的总大小commit_logs_cache_size_threshold- 接下来需要提交的后续日志的总大小
如果默认值过大,可以通过降低这两个配置项来减少内存使用。
可以使用 pfev 命令检查从每个缓存以及从文件读取的日志量。
也可以使用 Prometheus 端点中的指标来跟踪这两个缓存的当前大小。
Prometheus
Keeper 可以对 Prometheus 暴露指标数据,以供抓取。
设置:
endpoint– Prometheus 服务器用于抓取指标的 HTTP 端点,应以 '/' 开头。port–endpoint所使用的端口。metrics– 开关,用于暴露 system.metrics 表中的指标。events– 开关,用于暴露 system.events 表中的指标。asynchronous_metrics– 开关,用于暴露 system.asynchronous_metrics 表中的当前指标值。
示例
检查(将 127.0.0.1 替换为 ClickHouse 服务器的 IP 地址或主机名):
另请参阅 ClickHouse Cloud 的 Prometheus 集成。
ClickHouse Keeper 用户指南
本指南提供了一组简单且最小化的设置,用于配置 ClickHouse Keeper,并通过一个示例演示如何测试分布式操作。该示例在 Linux 上使用 3 个节点完成。
1. 使用 Keeper 设置配置节点
-
在 3 台主机(
chnode1、chnode2、chnode3)上安装 3 个 ClickHouse 实例。(有关安装 ClickHouse 的详细信息,请参阅快速开始。) -
在每个节点上添加以下条目,以允许通过网络接口进行外部通信。
-
在所有三台服务器上添加以下 ClickHouse Keeper 配置,并为每台服务器更新
<server_id>设置;例如chnode1为1,chnode2为2,依此类推。上面使用的是以下基本设置:
Parameter Description Example tcp_port 供 keeper 客户端使用的端口 9181,等同于 zookeeper 中的默认端口 2181 server_id 在 raft 配置中为每个 ClickHouse Keeper 服务器设置的标识符 1 coordination_settings 用于配置诸如超时等参数的部分 超时:10000,日志级别:trace server 参与的服务器的定义 每台服务器的定义列表 raft_configuration keeper 集群中每台服务器的设置 每台服务器及其相关设置 id keeper 服务中服务器的数字 ID 1 hostname keeper 集群中每台服务器的主机名、IP 或 FQDN chnode1.domain.comport 用于 keeper 服务器间连接监听的端口 9234 -
启用 Zookeeper 组件。它将使用 ClickHouse Keeper 引擎:
上面使用的是以下基本设置:
Parameter Description Example node 用于 ClickHouse Keeper 连接的节点列表 每台服务器的一条配置记录 host 每个 ClickHouse Keeper 节点的主机名、IP 或 FQDN chnode1.domain.comport ClickHouse Keeper 客户端端口 9181 -
重启 ClickHouse 并验证每个 Keeper 实例是否正在运行。在每台服务器上执行以下命令。如果 Keeper 正常运行且处于健康状态,
ruok命令将返回imok: -
system数据库中有一张名为zookeeper的表,其中包含 ClickHouse Keeper 实例的详细信息。我们来查看该表:
该表如下所示:
2. 在 ClickHouse 中配置集群
-
让我们在 2 个节点上配置一个包含 2 个分片且每个分片只有 1 个副本的简单集群。第三个节点将用于满足 ClickHouse Keeper 的仲裁(quorum)要求。在
chnode1和chnode2上更新配置。下面的集群配置在每个节点上定义了 1 个分片,总计 2 个分片且无复制。在此示例中,一部分数据会位于一个节点上,另一部分数据会位于另一个节点上:Parameter Description Example shard 集群定义中的分片列表 每个分片的副本列表 replica 每个副本的配置列表 每个副本的配置项 host 将托管副本分片的服务器的主机名、IP 或 FQDN chnode1.domain.comport 使用原生 TCP 协议进行通信的端口 9000 user 用于对集群实例进行身份验证的用户名 default password 为该用户设置的密码,用于允许连接到集群实例 ClickHouse123! -
重启 ClickHouse 并验证集群是否已创建:
你应该能看到你的集群:
3. 创建并测试分布式表
-
使用
chnode1上的 ClickHouse 客户端在新集群上创建一个新的数据库。ON CLUSTER子句会自动在两个节点上创建该数据库。 -
在
db1数据库中创建一个新表。同样,ON CLUSTER会在两个节点上创建该表。 -
在
chnode1节点上添加几行数据: -
在
chnode2节点上添加几行数据: -
注意,在每个节点上运行
SELECT语句时,只会显示该节点上的数据。例如,在chnode1上:在
chnode2上: -
-
可以创建一个
Distributed表来汇总表示两个分片上的数据。使用Distributed表引擎的表本身不存储任何数据,但允许在多个服务器上进行分布式查询处理。读操作会访问所有分片,写操作可以分布到各个分片上。在chnode1上运行以下查询: -
注意,对
dist_table发起查询会返回来自两个分片的全部四行数据:
总结
本指南演示了如何使用 ClickHouse Keeper 来设置集群。借助 ClickHouse Keeper,可以配置集群并定义可以在分片间复制的分布式表。
使用唯一路径配置 ClickHouse Keeper
本页不适用于 ClickHouse Cloud。此处所述流程已在 ClickHouse Cloud 服务中自动化完成。
描述
本文介绍如何使用内置的 {uuid} 宏配置项,
在 ClickHouse Keeper 或 ZooKeeper 中创建唯一条目。唯一路径
在频繁创建和删除表时非常有用,因为
这避免了需要等待数分钟让 Keeper 垃圾回收
去清理路径条目;每次创建路径时,都会在该路径中使用新的 uuid,
路径从不复用。
示例环境
一个由三个节点组成的集群,将被配置为在所有三个节点上运行 ClickHouse Keeper, 并在其中两个节点上运行 ClickHouse。这样为 ClickHouse Keeper 提供了三个节点(包括一个仲裁节点), 以及一个由两个副本组成的单个 ClickHouse 分片。
| node | description |
|---|---|
chnode1.marsnet.local | 数据节点 - 集群 cluster_1S_2R |
chnode2.marsnet.local | 数据节点 - 集群 cluster_1S_2R |
chnode3.marsnet.local | ClickHouse Keeper 仲裁节点 |
集群示例配置:
将表设置为使用 {uuid} 的步骤
- 在每台服务器上配置宏(Macros)
以服务器 1 为例:
请注意,我们为 shard 和 replica 定义了宏,但 {uuid} 并未在此处定义,它是内置的,无需显式定义。
- 创建数据库
- 利用宏和
{uuid}在集群上创建表
┌─host──────────────────┬─port─┬─status─┬─error─┬─num_hosts_remaining─┬─num_hosts_active─┐ │ chnode1.marsnet.local │ 9440 │ 0 │ │ 1 │ 0 │ │ chnode2.marsnet.local │ 9440 │ 0 │ │ 0 │ 0 │ └───────────────────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘
测试
- 向第一个节点插入数据(例如
chnode1)
- 向第二个节点插入数据(例如
chnode2)
- 通过分布式表查看记录
替代方案
可以通过宏预先定义默认复制路径,并同时使用 {uuid}。
- 在每个节点上为表设置默认默认路径
如果某些节点仅用于特定数据库,你也可以在每个节点上定义一个 {database} 宏。
- 在不显式指定参数的情况下创建表:
Query id: ab68cda9-ae41-4d6d-8d3b-20d8255774ee
┌─host──────────────────┬─port─┬─status─┬─error─┬─num_hosts_remaining─┬─num_hosts_active─┐ │ chnode2.marsnet.local │ 9440 │ 0 │ │ 1 │ 0 │ │ chnode1.marsnet.local │ 9440 │ 0 │ │ 0 │ 0 │ └───────────────────────┴──────┴────────┴───────┴─────────────────────┴──────────────────┘
结果共 2 行。耗时:1.175 秒。
故障排查
示例命令,用于获取表信息和 UUID:
用于获取 ZooKeeper 中上述表的 UUID 相关信息的示例命令
数据库必须为 Atomic。如果是从之前的版本升级,则 default 数据库很可能是 Ordinary 类型。
检查方式:
例如,
ClickHouse Keeper 动态重新配置
本页不适用于 ClickHouse Cloud。此处所述流程已在 ClickHouse Cloud 服务中自动化完成。
描述
如果开启了 keeper_server.enable_reconfiguration,ClickHouse Keeper 对用于动态集群重新配置的 ZooKeeper reconfig 命令提供部分支持。
如果该设置关闭,您可以通过手动修改各副本的 raft_configuration 节来重新配置集群。请确保在所有副本上都编辑这些文件,因为只有 leader 会应用更改。
或者,您也可以通过任何兼容 ZooKeeper 的客户端发送 reconfig 查询。
虚拟节点 /keeper/config 中包含最近一次提交的集群配置,格式如下:
- 每个服务器条目以换行符分隔。
server_type可以是participant或learner(learner 不参与 leader 选举)。server_priority是一个非负整数,用于指定在 leader 选举时应优先选择哪些节点。 优先级为 0 表示该服务器永远不会成为 leader。
示例:
可以使用 reconfig 命令来添加新服务器、删除现有服务器以及修改现有服务器的优先级,下面是一些示例(使用 clickhouse-keeper-client):
以下是 kazoo 的示例:
将现有服务器的优先级更改为 8
reconfig(joining="server.5=localhost:5123;participant;8", leaving=None)
将单节点 keeper 转换为集群
有时需要将用于实验的单个 keeper 节点扩展为一个集群。下面是将其一步步扩展为 3 节点集群的示意流程:
- 重要:新增节点必须分批添加,每批数量需小于当前仲裁数,否则它们会在彼此之间选举出一个 leader。本示例中为逐个添加。
- 现有 keeper 节点必须开启
keeper_server.enable_reconfiguration配置参数。 - 启动第二个节点,使用 keeper 集群的全新完整配置。
- 启动完成后,使用
reconfig将其添加到节点 1。 - 然后,启动第三个节点,并使用
reconfig将其添加进来。 - 在
clickhouse-server配置中添加新的 keeper 节点以更新配置,并重启以应用更改。 - 更新节点 1 的 raft 配置,并在需要时选择性地重启它。
为便于熟悉这一过程,这里提供了一个 sandbox 仓库。
不支持的功能
虽然 ClickHouse Keeper 旨在与 ZooKeeper 完全兼容,但目前仍有一些功能尚未实现(相关开发仍在进行中):
create不支持返回Stat对象create不支持 TTLaddWatch无法与PERSISTENT类型的 watch 一起使用removeWatch和removeAllWatches不支持- 不支持
setWatches - 不支持创建
CONTAINER类型的 znode - 不支持
SASL authentication(SASL 身份验证)