无ZooKeeper的ClickHouse复制场景count()查询相关问题咨询
Q1 计数波动问题解答
- 核心原因是你使用的无ZK非ReplicatedMergeTree复制模式的固有特性,不属于错误配置:
- 该模式下无协调器保证多副本数据一致性,写入时Distributed表向同分片的两个副本双写,过程中如果出现单副本写入超时、网络波动等异常,就会出现两个副本数据条数不一致的情况
- Distributed表查询时默认采用随机负载均衡策略选择同分片的副本执行查询,每次查询选择的副本不同,就会出现同一集群多次查询返回结果不一致的现象
- 3分片1副本场景下无需做副本选择,每次查询的节点固定,所以不会出现计数差异
- 如果要降低波动概率,可以显式设置
load_balancing = 'in_order'参数,让查询时优先选择每个分片排序靠前的副本,只有靠前的副本不可用时才切换到后续副本,尽可能保证每次查询的数据源一致。
Q2 排除副本计数方案
以下方案按实用性从高到低排序:
- 查询时临时指定internal_replication参数
执行查询时加上SETTINGS配置即可,无需修改任何集群或表结构:
internal_replication设置为true时,Distributed表查询只会为每个分片选择一个副本执行请求,不会重复计算同分片多副本的数据,返回结果即为原始写入的1亿条。注意写入时不要开启该参数,否则会导致Distributed表只写给单副本,无法实现双写复制的效果。SELECT count(*) FROM log_all SETTINGS internal_replication = true; - 新增单副本查询专用集群配置
在config.xml的remote_servers中新增一套3分片1副本的集群配置,每个分片只保留一个固定副本,再基于该集群新建一个Distributed查询专用表:
写入数据使用原2副本的Distributed表,查询计数使用新的1副本Distributed表,即可直接拿到1亿的正确结果。<log_3shards_1replica> <shard> <replica><host>CH1</host><port>9000</port></replica> </shard> <shard> <replica><host>CH2</host><port>9000</port></replica> </shard> <shard> <replica><host>CH3</host><port>9000</port></replica> </shard> </log_3shards_1replica> - 基于唯一键去重(性能较差)
如果你的日志数据存在全局唯一主键,可以直接用distinct去重计数:
该方案无需修改配置,但大数据量下性能损耗较高,仅适合临时查询使用。SELECT count(DISTINCT 唯一主键字段) FROM log_all;
内容的提问来源于stack exchange,提问作者Jae
相关产品推荐
相关产品推荐

