本页不适用于 ClickHouse Cloud。本文所述流程在 ClickHouse Cloud 服务中已实现自动化。
实现细节
clickhouse-keeper-converter 工具可以将 ZooKeeper 数据转换为 ClickHouse Keeper 快照。ClickHouse Keeper 的服务器间协议也与 ZooKeeper 不兼容,因此无法构建混合的 ZooKeeper / ClickHouse Keeper 集群。
ClickHouse Keeper 对访问控制列表 (ACL) 的支持方式与 ZooKeeper 相同。ClickHouse Keeper 支持同样的一组权限,并提供完全相同的内置方案:world、auth 和 digest。digest 身份验证方案使用 username:password 这一组凭据,其中密码采用 Base64 编码。
不支持外部集成。
配置
.xml 文件几乎相同。
Keeper 配置设置
<keeper_server>,包含以下参数:
其他常用参数继承自 ClickHouse server 配置 (
listen_host、logger 等) 。
内部协调设置
<keeper_server>.<coordination_settings> 部分,包含以下参数:
Quorum 配置位于
<keeper_server>.<raft_configuration> 部分,包含各服务器的描述。
整个 quorum 只有一个参数 secure,用于为 quorum 参与者之间的通信启用加密连接。如果节点之间的内部通信需要 SSL 连接,可将该参数设为 true;否则可不指定。
每个 <server> 的主要参数有:
id— quorum 中的服务器标识符。hostname— 该服务器所在主机的主机名。port— 该服务器监听连接的端口。can_become_leader— 设为false可将服务器配置为learner。如果省略,则默认为true。
如果你的 ClickHouse Keeper 集群拓扑发生变化 (例如替换某台服务器) ,请务必保持
server_id 与 hostname 的映射一致,并避免打乱现有 server_id 的对应关系,或将已有 server_id 复用于其他服务器 (例如,在依赖自动化脚本部署 ClickHouse Keeper 时就可能发生这种情况) 。如果某个 Keeper 实例所在的主机可能发生变化,我们建议定义并使用主机名,而不是直接使用 IP 地址。更改主机名等同于移除并重新添加该服务器,而在某些情况下这可能无法做到 (例如,没有足够的 Keeper 实例来形成 quorum) 。默认禁用
async_replication,以避免破坏向后兼容性。如果你的集群中所有 Keeper 实例运行的版本都支持 async_replication (v23.9+) ,我们建议启用它,因为它可以提升性能且没有任何缺点。test_keeper_ 前缀的集成测试中提供了三节点 quorum 的配置示例。下面是服务器 #1 的示例配置:
如何运行
<keeper_server> 配置添加到 /etc/your_path_to_config/clickhouse-server/config.xml,然后像平常一样启动 ClickHouse server 即可。如果你想运行独立运行的 ClickHouse Keeper,也可以用类似的方式启动:
clickhouse-keeper) ,您可以创建一个,或将 keeper 指定为 clickhouse 的参数:
四字母命令
mntr、stat 等。还有一些比较常用的命令:stat 提供有关 server 和已连接客户端的常规信息,srvr 提供 server 的扩展信息,cons 提供 connections 的扩展信息。
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 发送这些命令。
ruok:测试 server 是否正在运行且未处于 error 状态。如果 server 正在运行,会返回imok;否则将完全没有响应。返回imok并不一定表示 server 已加入 quorum,它只说明 server 进程处于活动状态,并已绑定到指定的客户端端口。要查看与 quorum 相关的状态以及客户端 connection 信息,请使用stat。
mntr:输出一组可用于监控集群健康状态的变量。
srvr:列出 server 的完整信息。
stat:列出 server 和已连接客户端的简要信息。
srst:重置服务器统计信息。该命令会影响srvr、mntr和stat的结果。
conf: 打印当前服务配置的详细信息。
cons:列出连接到此服务器的所有客户端的完整连接/会话信息。包括收发数据包数量、会话 ID、操作延迟、最近执行的操作等信息……
crst:重置所有连接的连接/会话统计信息。
envi: 输出服务环境的详细信息
dirs:显示快照和日志文件的总大小 (单位为字节)
isro:用于检查 server 是否以只读模式运行。处于只读模式时,server 会返回ro;否则返回rw。
wchs:列出服务器上 watches 的简要信息。
wchc:按会话列出服务器上的 watch 详细信息。该命令会输出会话 (连接) 及其关联的 watch (路径) 列表。请注意,具体开销取决于 watch 的数量,此操作可能代价较高 (会影响服务器性能) ,请谨慎使用。
wchp:按路径列出服务器上的 watches 详细信息。它会输出路径 (znodes) 及其关联会话的列表。请注意,watches 数量较多时,此操作的开销可能很大 (即会影响服务器性能) ,请谨慎使用。
dump:列出未完成的会话和临时节点。此命令仅在 leader 上有效。
csnp:调度一个快照创建任务。成功时返回已调度快照的最后一个已提交日志索引,失败时返回Failed to schedule snapshot creation task.。lgif命令可帮助你判断快照是否已完成。
lgif:Keeper 日志信息。first_log_idx:当前节点在日志存储中的第一个日志索引;first_log_term:当前节点的第一个日志任期;last_log_idx:当前节点在日志存储中的最后一个日志索引;last_log_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:请求让出 leader 角色并切换为跟随者。如果接收该请求的 server 是 leader,它会先暂停写入操作,等待继任者 (当前 leader 不可能成为继任者) 完成对最新日志的追平,然后辞去 leader 身份。继任者将自动选出。如果请求发送成功,则返回Sent yield leadership request to leader.;如果请求未发送,则返回Failed to send yield leadership request to leader.。如果该节点本身已经是跟随者,结果与请求已发送时相同。
pfev:返回所有已收集事件的值。对于每个事件,会返回事件名称、事件值及其描述。
HTTP 控制
/ready 端点的配置示例:
功能开关
keeper_server.feature_flags 配置启用。
也可以显式禁用所有功能。
如果您想为 Keeper 集群启用某个新功能,建议先将集群中的所有 Keeper 实例升级到支持该功能的版本,再启用该功能本身。
下面是一个功能开关配置示例,其中禁用了 multi_read,并启用了 check_not_exists:
从 25.7 版本开始,部分功能开关默认启用。
建议将 Keeper 升级到 25.7+ 的方式是先升级到 24.9+ 版本。
从 ZooKeeper 迁移
clickhouse-keeper-converter 工具可将 ZooKeeper 的日志和快照转换为 ClickHouse Keeper 快照。该工具要求 ZooKeeper 版本为 3.4 或更高。
迁移前准备
迁移步骤
- 停止向所有 ClickHouse 节点摄取数据。
- 停止所有 ClickHouse 节点上的后台任务 (参见上文) 。
- 停止所有 ZooKeeper 节点。
- 可选但建议执行:找到 ZooKeeper 的 leader 节点,将其重新启动后再停止。这样会强制 ZooKeeper 在转换前先将一致性快照写入磁盘。
-
在 leader 节点上运行
clickhouse-keeper-converter。如果你安装了完整的 ClickHouse 可执行文件,请改用keeper-converter子命令 (clickhouse keeper-converter) 。如果两者都不可用,请下载该可执行文件。
- 将快照复制到所有 ClickHouse Keeper 节点。在任何节点启动之前,每个节点上都必须已有该快照——如果某个节点在没有快照的情况下启动,可能会以空状态将自己选举为 leader。
- 更新 ClickHouse 配置,使其指向新的 Keeper 集群。
- 在所有节点上启动 ClickHouse Keeper,然后重启 ClickHouse。
- 将各项指标与迁移前的基线进行比较,以验证一致性。
- 恢复后台任务并重启数据摄取。
整合多个 ZooKeeper 集群
clickhouse-keeper-converter 工具仅支持一对一转换 (一个 ZooKeeper 集群对应一个 Keeper 快照) ,因此若要进行整合,需要修改转换器的源代码以合并多个快照:
- 在每个 ZooKeeper 集群上分别运行
clickhouse-keeper-converter,并将各自的输出写入不同的目录。 - 按顺序对快照文件进行反序列化。合并时,重新计算
numChildren值,以避免不同源集群的命名空间之间发生节点 ID 冲突。 - 将合并后的输出写入目标 ClickHouse Keeper 快照目录。
处理加密和 ACL
world、auth、digest) 。在转换过程中如何处理 ACL,取决于你的 ZooKeeper 配置:
- 完全加密或完全未加密:可直接转换。转换器会保留现有的 ACL 信息。
- 部分加密:转换前,先为超级管理员账户授予权限,并使用
setAcl -R清除受影响 path 上的 ACL。转换完成后,如有需要,再在 ClickHouse Keeper 中重新启用加密。
验证迁移
- 公共路径:多个源集群中都存在且数据相同的路径——这些路径应在合并后的输出中去重。
- 差异化路径:仅存在于特定集群下的路径 (例如每个分片组在
/clickhouse/tables下的路径) ——这些路径必须从正确的源中保留下来。
迁移后调优
这些设置需在 Keeper 配置 的
coordination_settings 下进行配置。
丢失 quorum 后的恢复
- 确保故障节点无法再次连接到集群。
- 在步骤明确说明之前,不要启动任何新节点。
- 选择一个 Keeper 节点作为新的 leader。请注意,该节点的数据将用于整个集群,因此建议选择状态最新的节点。
- 在执行任何其他操作之前,先备份所选节点的
log_storage_path和snapshot_storage_path文件夹。 - 在你打算使用的所有节点上重新配置集群。
- 向你选定的节点发送四字命令
rcvr,这会将该节点切换到恢复模式;或者停止所选节点上的 Keeper 实例,然后使用--force-recovery参数重新启动它。 - 逐个启动新节点上的 Keeper 实例,并确保在启动下一个节点之前,
mntr对zk_server_state返回follower。 - 在恢复模式下,leader 节点会对
mntr命令返回错误消息,直到它与新节点达成 quorum;同时会拒绝来自客户端和跟随者的任何请求。 - 达成 quorum 后,leader 节点将恢复正常运行模式,并开始接受所有请求。可使用
mntr通过zk_server_state返回leader来验证 Raft 已恢复正常。
在 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 的 keeper_server.coordination_settings.force_sync 设置为 true (默认值即为 true) 时,对于所有类型的磁盘,都无法满足某些保证。
目前,只有 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_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 磁盘。
配置日志缓存
latest_logs_cache_size_threshold- 缓存中保存的最新日志总大小commit_logs_cache_size_threshold- 接下来需要提交的后续日志总大小
你可以使用
pfev 命令查看从各个缓存和文件中读取的日志量。
你也可以使用 Prometheus 端点提供的指标来跟踪这两个缓存的当前大小。Prometheus
endpoint– Prometheus 服务器抓取指标的 HTTP 端点。以 ’/’ 开头。port–endpoint的端口。metrics– 用于控制是否暴露 system.metrics 表中的指标的标志。events– 用于控制是否暴露 system.events 表中的指标的标志。asynchronous_metrics– 用于控制是否暴露 system.asynchronous_metrics 表中当前指标值的标志。
127.0.0.1 替换为你的 ClickHouse 服务器的 IP 地址或主机名) :
ClickHouse Keeper 用户指南
1. 使用 Keeper 设置来配置节点
-
在 3 台主机 (
chnode1、chnode2、chnode3) 上安装 3 个 ClickHouse 实例。 (有关 ClickHouse 的安装详情,请参阅快速入门。) -
在每个节点上,添加以下配置项,以允许通过网络接口进行对外通信。
-
将以下 ClickHouse Keeper 配置添加到三台服务器中的每一台,并为各服务器更新
<server_id>设置;例如,chnode1应设为1,chnode2应设为2,依此类推。以下是上文中使用的基本设置: -
启用 ZooKeeper 组件。它将使用 ClickHouse Keeper 引擎:
以上是前面用到的基本设置:
-
重启 ClickHouse,并验证每个 Keeper 实例都在运行。在每台服务器上执行以下命令。如果 Keeper 正在运行且状态正常,
ruok命令将返回imok: -
system数据库中有一张名为zookeeper的表,包含你的 ClickHouse Keeper 实例的详细信息。我们来查看这张表:表如下所示:
2. 在 ClickHouse 中配置集群
-
我们来配置一个简单集群:在其中 2 个节点上设置 2 个分片,且每个分片只有 1 个副本。第三个节点将用于满足 ClickHouse Keeper 的法定人数要求。更新
chnode1和chnode2上的配置。以下集群在每个节点上定义了 1 个分片,总共 2 个分片,且不使用复制。在此示例中,部分数据会位于一个节点上,另一部分数据会位于另一个节点上: -
重启 ClickHouse 并验证集群已创建:
你应该会看到你的集群:
3. 创建并测试分布式表
-
在
chnode1上使用 ClickHouse client,在新集群中创建一个新数据库。ON CLUSTER子句会自动在两个节点上创建该数据库。 -
在
db1数据库中创建一个新表。同样,ON CLUSTER会在两个节点上创建该表。 -
在
chnode1节点上插入两行数据: -
在
chnode2节点上再插入两行数据: -
请注意,在每个节点上执行
SELECT语句时,只会看到该节点上的数据。例如,在chnode1上:在chnode2上: -
-
你可以创建一个
Distributed表,用来表示这两个分片上的数据。使用Distributed表引擎的表本身不存储任何数据,但支持在多个服务器上进行分布式查询处理。读取会访问所有分片,写入也可以分发到各个分片。请在chnode1上运行以下查询: -
可以看到,查询
dist_table会返回来自这两个分片的全部四行数据:
摘要
使用唯一路径配置 ClickHouse Keeper
本页不适用于 ClickHouse Cloud。本文所述流程在 ClickHouse Cloud 服务中已实现自动化。
说明
{uuid} 宏设置,
在 ClickHouse Keeper 或 ZooKeeper 中创建唯一的条目。唯一的
路径 在频繁创建和 drop 表时很有帮助,因为
这样可以避免每次都要等待几分钟,让 Keeper 的垃圾回收
删除 路径 条目;这是因为每次创建 路径 时,都会在该
路径 中使用新的 uuid;路径 永远不会被重复使用。
示例环境
集群配置示例:
将表配置为使用 {uuid} 的步骤
- 在每台服务器上配置宏 服务器 1 的示例:
请注意,我们为
shard 和 replica 定义了宏,但 {uuid} 并未在此定义——它是内置的,无需单独定义。- 创建数据库
- 使用宏和
{uuid}在集群中创建表
- 创建分布式表
测试
- 向第一个节点插入数据 (例如
chnode1)
- 向第二个节点插入数据 (例如,
chnode2)
- 通过分布式表查看记录
备选方案
{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 条目以换行符分隔。
server_type的值可以是participant或learner(learner 不参与 leader 选举) 。server_priority是一个非负整数,用于指定在 leader 选举中应优先选择哪些节点。 优先级为 0 表示该 server 永远不会成为 leader。
reconfig 命令来添加新服务器、移除现有服务器,以及调整现有服务器的优先级。以下是一些示例 (使用 clickhouse-keeper-client) :
kazoo 的示例:
joining 中的服务器应采用上文所述的 server 格式。各服务器条目之间应以逗号分隔。
添加新服务器时,可以省略 server_priority (默认值为 1) 和 server_type (默认值
为 participant) 。
如果要更改现有服务器的优先级,请将该服务器及目标优先级一起添加到 joining 中。
服务器主机、端口和类型必须与现有服务器配置相同。
服务器会按照它们在 joining 和 leaving 中出现的顺序添加和移除。
joining 中的所有更新都会先于 leaving 中的更新处理。
Keeper 重新配置的实现有一些注意事项:
-
仅支持增量重新配置。带有非空
new_members的请求会被拒绝。 ClickHouse Keeper 的实现依赖 NuRaft API 动态更改成员关系。NuRaft 只能一次 添加一台服务器或移除一台服务器,每次只能处理一个。这意味着对配置的每次更改 (joining中的每一项、leaving中的每一项) 都必须单独决定。因此不提供批量 重新配置,因为这会对最终用户造成误导。 同样也无法更改服务器类型 (participant/learner) ,因为 NuRaft 不支持这一点,而 唯一的办法是先移除再添加服务器,这同样会造成误导。 -
不能使用返回的
znodestat值。 -
from_version字段不会被使用。所有设置了from_version的请求都会被拒绝。 这是因为/keeper/config是一个虚拟节点,也就是说它不会存储在 持久化存储中,而是会针对每个请求根据指定的节点配置动态生成。 作出这一决定是为了避免数据重复,因为 NuRaft 已经存储了该配置。 -
与 ZooKeeper 不同,无法通过提交
sync命令来等待集群重新配置完成。 新配置最终会生效,但不保证具体时间。 -
reconfig命令可能会因各种原因失败。你可以检查集群的状态,查看更新 是否已应用。
将单节点 keeper 转换为集群
- 重要:新增节点必须分批添加,且每批数量必须小于当前 法定人数,否则它们会自行选举出一个 leader。本例中按每次一个节点添加。
- 现有 keeper 节点必须开启
keeper_server.enable_reconfiguration配置参数。 - 使用 keeper 集群的完整新配置启动第二个节点。
- 节点启动后,使用
reconfig将其添加到节点 1。 - 然后启动第三个节点,并使用
reconfig将其添加进来。 - 更新
clickhouse-server配置,将新的 keeper 节点添加进去,然后重启以应用更改。 - 更新节点 1 的 raft 配置,并可选择重启它。
不支持的功能
create不支持返回Stat对象create不支持 生存时间 (TTL)addWatch不支持PERSISTENT监听- 不支持
removeWatch和removeAllWatches - 不支持
setWatches - 不支持创建
CONTAINER类型的 znode - 不支持
SASL 身份验证