You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于ClickHouse Keeper的复制集群:查询仅命中单个副本

ClickHouse副本读查询负载均衡问题

环境配置

  • 1个分片(shard)
  • 3个副本(replica)
  • 使用ClickHouse Keeper Server替代外部ZooKeeper
  • 三台虚拟机:VM2(replica 02)、VM3(replica 03)、VM1(ClickHouse Keeper)

核心问题

配置3个副本后,所有读查询仅命中单个副本,无法通过分发查询到多个副本提升性能。

集群配置

<yandex>
    <remote_servers>
        <my_cluster>
            <shard>
                <replica>
                    <host>vm2</host>
                    <port>9000</port>
                </replica>
                <replica>
                    <host>vm3</host>
                    <port>9000</port>
                </replica>
            </shard>
        </my_cluster>
    </remote_servers>

    <zookeeper>
        <node>
            <host>vm1</host>
            <port>2181</port>
        </node>
    </zookeeper>
</yandex>

已尝试操作

  • 执行SELECT * FROM system.replicas;:所有副本显示活跃且同步
  • 执行SELECT * FROM system.clusters WHERE cluster = 'my_cluster';:正确列出所有副本
  • 通过distributed表查询:SELECT * FROM distributed_table;,仍仅单个副本处理请求

疑问

  1. 如何确保ClickHouse将查询分发到所有副本?
  2. 是否需要为读查询配置特定的负载均衡策略?
  3. 有没有办法确认查询使用的是哪个副本?

解决方案

1. 配置副本负载均衡策略

ClickHouse默认对单分片多副本的查询,只会选择第一个可用副本执行,必须显式配置负载均衡规则才能实现查询分发。

方式一:全局集群配置添加负载均衡参数

修改集群配置文件中的shard节点,添加load_balancing参数,可选值包括:

  • random:随机选择可用副本
  • round_robin:轮询选择可用副本
  • least_loaded:选择负载最低的副本

修改后的配置示例:

<yandex>
    <remote_servers>
        <my_cluster>
            <shard>
                <load_balancing>random</load_balancing>
                <replica>
                    <host>vm2</host>
                    <port>9000</port>
                </replica>
                <replica>
                    <host>vm3</host>
                    <port>9000</port>
                </replica>
            </shard>
        </my_cluster>
    </remote_servers>

    <zookeeper>
        <node>
            <host>vm1</host>
            <port>2181</port>
        </node>
    </zookeeper>
</yandex>

方式二:单查询级指定负载均衡策略

在查询语句末尾通过SETTINGS临时指定策略,无需修改全局配置:

SELECT * FROM distributed_table SETTINGS load_balancing = 'round_robin';

2. 确认查询使用的副本

可以通过两种方式验证查询对应的副本:

方式一:查看副本进程列表

在执行查询的同时,分别在每个副本上执行以下语句,检查哪个副本的进程列表中存在目标查询:

SELECT query, host_name FROM system.processes WHERE query LIKE '%distributed_table%';

方式二:查询中返回副本主机名

修改查询语句,直接返回当前处理请求的副本主机名:

SELECT *, hostName() FROM distributed_table;

结果中的hostName()列会显示处理该查询的副本主机名称。

3. 额外注意事项

  • 确保所有副本的集群配置文件完全一致,包括分片、副本定义和ZooKeeper地址
  • 确认distributed表的创建语句正确关联到目标集群,示例:
CREATE TABLE distributed_table ON CLUSTER my_cluster
AS local_table
ENGINE = Distributed(my_cluster, default, local_table, rand());
  • 使用least_loaded策略时,需保证ClickHouse能正常收集副本的负载指标,依赖system.metrics和system.asynchronous_metrics表的数据准确性

内容的提问来源于stack exchange,提问作者Subhashree Mohan Swain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 23:10:15