datax同步数据到ClickHouse时同步时间特别长,原因:Too many partitions for single INSERT block (more than 100).

场景描述

今天将 Hive 分区中数据同步到 ClickHouse 时,发现有的任务运行时间很短,但是有的任务运行时间特别长,看了一下数据量,发现有的接近千万条数据,但是几分钟就同步完了,但是有的才几万条数据,要同步半个多小时,还有的任务几百万条数据,甚至要同步四五个小时。开始以为是配置文件中 channel(作业并发数), batchSize(批量插入条数),speed(作业速率) 这些条件限制了任务运行的时间,但是尝试将这些条件限制成一样的,再次运行任务,发现之前慢的任务还是慢,快的任务还是很快就完成了。

问题原因

发现不是配置的原因,就跑去看 datax 同步时产生的 log 日志,发现如下问题:

CommonRdbmsWriter$Task - 回滚此次写入, 采用每次写入一行方式提交. 因为:ClickHouse exception, code: 1002, host: 10.129.170.80, port: 8123; Code: 252. DB::Exception: Too many partitions for single INSERT block (more than 100). The limit is controlled by 'max_partitions_per_insert_block' setting. Large number of partitions is a common misconception. It will lead to severe negative performance impact, including slow server startup, slow INSERT queries and slow SELECT queries. Recommended total number of partitions for a table is under 1000…10000. Please note, that partitioning is not intended to speed up SELECT queries (ORDER BY key is sufficient to make range queries fast). Partitions are intended for data manipulation (DROP PARTITION, etc). (TOO_MANY_PARTS) (version 22.3.2.1)

根据上面日志可以看出,原因是单次插入的数据分区太多了,超过默认配置的 100 个了,因为 ClickHouse 为了防止可能出现极限情况,批量插入时,在逻辑中判断涉及到的分区是否超过 max_partitions_per_insert_block,如果超过,则立即执行一次插入。如果频繁插入的话,那么肯定是比较耗时的。还有如果每次插入涉及的分区太多,在插入的时候也比较耗时,原因是每个数据目录都需要和 zookeeper 进行交互。

ClickHouse 每次写入都会生成一个 data part,如果每次写入一条或者少量的数据,那会造成 ClickHouse 内部有大量的 data part(会给 merge 和查询造成很大的负担)。为了防止出现大量的 data part,ClickHouse 内部做了很多限制。max_partitions_per_insert_block 参数用来限制单个插入的 Block 中包含的最大分区数量,数据插入太频繁,ClickHouse 不支持频繁插入操作。(是因为 MergeTree 的 merge 的速度跟不上 data part 生成的速度)。

解释: max_partitions_per_insert_block官方文档)参数用来限制单个插入 Block 中,包含的最大分区数量,默认值为 100。设置为 0 时,表示不限制。

解决办法

调整分区数或者 max_partitions_per_insert_block 参数。

  1. 合理设置分区字段
    调整表结构,调整分区方式。

  2. 避免同一批次写入包含太多分区的数据
    减小写入的批量大小,避免单个插入的不同分区数超过限制。

  3. 修改 max_partitions_per_insert_block 参数,调大这个值
    如果无法调整批量大小,可适当修改 max_partitions_per_insert_block 参数,放大限制。

    • 配置文件修改: 在 users.xml 配置文件中进行配置。配置在 <profiles> 块中。CK 的配置文件是即时生效,不需要重启服务器。
    • 在一个会话中临时修改:SET max_partitions_per_insert_block = 1000。用于临时导入大量数据的情况。

参考文章:
https://www.cnblogs.com/MrYang-11-GetKnow/p/15900553.html
https://www.jianshu.com/p/8aa2a20ab00a

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值