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

ClickHouse哈希分片键场景下跨分片数据重复原因咨询

问题描述

我通过Altinity Kubernetes ClickHouse Operator部署了一个包含4个分片、2个副本的分布式ClickHouse集群,相关DDL语句如下:

创建数据库

CREATE DATABASE my_db ON cluster 'my-cluster'

创建本地表

CREATE TABLE my_db.my_table_local ON cluster 'my-cluster'
(
    `time` DateTime('UTC'),
    `id` String,
    `type` LowCardinality(String),
    `value` Nullable(Float32)    
)
ENGINE = ReplicatedReplacingMergeTree('/clickhouse/my_db/tables/{shard}/my_table_local', '{replica}')
ORDER BY (id, type, time)
PARTITION BY toStartOfMonth(time)
SETTINGS min_age_to_force_merge_seconds = 60;

创建分布式表

CREATE TABLE my_db.my_table ON cluster 'my-cluster' AS my_db.my_table_local
ENGINE Distributed('my-cluster', my_db, my_table_local, cityHash64(id));

所有插入操作均针对分布式表my_db.my_table执行。集群采用K8s Operator部署,每个服务器实例/副本运行在独立Pod中,同时部署了3个ClickHouse-Keeper实例。

目前遇到的问题:偶尔会出现跨分片的数据重复,且这些重复数据会一直存在(已知ReplacingMergeTree无法跨分片去重,且分片数量从未变更)。此前已针对集群故障容错、复制机制做过压力测试(如强制终止服务器及ClickHouse-Keeper节点),了解过非活跃/只读副本的处理方法。

疑问:这种跨分片重复为何会发生?按理解,哈希函数作为分片键应能将插入请求一致路由到同一分片,是否存在例外情况(如分片不可用、ClickHouse-Keeper分片信息损坏等)?


可能的原因分析
  • 分片临时不可用时的写入fallback:当分布式表路由的目标分片所有副本都不可用时,ClickHouse会触发fallback机制,将写入请求转发到集群中其他可用的分片。这种情况下,原本应该落在某分片的数据会被写入其他分片,后续目标分片恢复后,同一id的数据就会分布在多个分片上,导致跨分片重复。可通过查看ClickHouse日志(搜索fallback关键词)确认是否发生过这种情况。

  • 分布式表拓扑缓存不一致:分布式表会缓存集群的分片拓扑信息,如果某个节点的缓存未及时更新(比如K8s Pod重启后缓存未同步,或是ClickHouse-Keeper的拓扑变更通知延迟),可能导致不同节点对分片路由的计算出现差异,同一id被路由到不同分片。可执行SYSTEM RELOAD DISTRIBUTED METADATA手动刷新缓存,观察是否还会出现重复。

  • 客户端重试无幂等控制:如果客户端在写入时遇到超时或报错自行重试,但未做幂等处理,且第一次写入其实已经成功(只是客户端未收到响应),重试时目标分片可能已经恢复,或是重试请求被路由到其他分片(比如第一次写入触发了fallback,重试时目标分片可用),就会导致同一数据被写入多个分片。需要检查客户端的重试逻辑是否使用INSERT ... WITH idempotency_key语法做幂等控制。

  • ClickHouse-Keeper脑裂:虽然部署了3个ClickHouse-Keeper实例,但如果出现网络分区导致脑裂,部分ClickHouse节点可能获取到错误的分片拓扑信息,进而将数据路由到错误的分片。可查看ClickHouse-Keeper的日志,确认是否出现过节点失联、选举异常等情况。

  • 分片键计算存在差异:极端情况下,如果不同节点的cityHash64实现存在差异(比如不同ClickHouse版本的哈希函数更新),或是id字段存在隐式类型转换差异(比如部分节点将id视为String,部分因配置问题解析为其他类型),会导致同一id计算出的哈希值不同,从而路由到不同分片。需确认所有ClickHouse节点版本一致,且表结构的字段类型定义完全统一。


内容的提问来源于stack exchange,提问作者comaes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 15:53:14