ClickHouse分布式表通过Spark JDBC写入数据后行数翻倍问题问询
ClickHouse分布式表写入数据量翻倍问题解决方案
问题根因
该问题由两个核心配置错误导致:
- 集群分片配置与实际部署不匹配:你配置的2个分片为node1、node2,但实际存储本地MergeTree表的是node2、node3,无本地表的接入节点node1被加入分片列表,导致路由逻辑异常。
- JDBC写入配置错误:如果JDBC URL配置了多个集群节点地址,旧版Yandex ClickHouse JDBC驱动会将每批数据重复写入所有配置的节点,最终写入总量等于实际数据量*节点数,2分片场景下刚好出现数据翻倍。
解决方案
1. 修正集群分片配置
所有节点的config.xml中remote_servers部分,将分片节点替换为实际部署了本地MergeTree表的node2、node3,移除无本地表的接入节点node1,修改后的配置如下:
<remote_servers> <trial-cluster> <shard> <replica> <default_database>trial</default_database> <host>node2</host> <port>9000</port> <password>zxcv</password> </replica> </shard> <shard> <replica> <default_database>trial</default_database> <host>node3</host> <port>9000</port> <password>zxcv</password> </replica> </shard> </trial-cluster> </remote_servers>
修改完成后重启所有节点的ClickHouse服务生效。
2. 修正JDBC写入地址配置
确保Spark作业中的jdbcUrl仅指向部署了分布式表的接入节点node1,不要配置多个节点地址,示例如下:
jdbc:clickhouse://node1:8123/trial
避免驱动自动路由到多个节点重复写入。
3. 优化写入参数
在Spark写入逻辑中新增以下配置项,避免重复写入同时提升性能:
.option("clickhouse.insert_distributed_sync", "true") .option("rewriteBatchedStatements", "true")
参数说明:
clickhouse.insert_distributed_sync控制分布式表写入为同步模式,避免异步写入重试导致的重复数据rewriteBatchedStatements开启批量语句重写,优化JDBC批量写入性能
修改后的完整写入逻辑如下:
df .write() .format("jdbc") .mode(SaveMode.Append) .option("driver", "ru.yandex.clickhouse.ClickHouseDriver") .option("url", jdbcUrl) .option("user", "default") .option("password", pass) .option("ssh", "false") .option("createTableOptions", createTableOptions) .option("dbtable", tableName) .option("truncate", "true") .option("batchsize", batchSize) .option("numPartitions", maxWritePartitions) .option("isolationLevel", "NONE") // 新增配置 .option("clickhouse.insert_distributed_sync", "true") .option("rewriteBatchedStatements", "true") .save();
4. 验证写入结果
清空历史测试数据后写入小批量测试数据,分别执行以下查询校验数据量:
- 分别在node2、node3执行本地表计数:
SELECT COUNT() FROM trial.illogs,两个节点计数之和等于Spark DataFrame的行数即表示分片写入正常 - 在node1执行分布式表计数:
SELECT COUNT() FROM trial.illogs,结果与Spark DataFrame行数一致即表示写入逻辑正常
提示:如果后续有条件建议将JDBC驱动替换为官方维护的
com.clickhouse.jdbc.ClickHouseDriver,旧版Yandex驱动已停止维护,存在较多已知问题。
内容的提问来源于stack exchange,提问作者Sriram R
相关产品推荐
相关产品推荐

