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

ClickHouse分布式表通过Spark JDBC写入数据后行数翻倍问题问询

ClickHouse分布式表写入数据量翻倍问题解决方案

问题根因

该问题由两个核心配置错误导致:

  1. 集群分片配置与实际部署不匹配:你配置的2个分片为node1、node2,但实际存储本地MergeTree表的是node2、node3,无本地表的接入节点node1被加入分片列表,导致路由逻辑异常。
  2. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 16:06:11