前言
clickhouse频繁插入数据时出现DB::Exception: Too many parts (300)
通常是因为ClickHouse在插入数据时生成了太多的parts文件,而这些文件合并的速度跟不上插入的速度,导致超过了默认的parts_to_throw_insert值,即300个parts。
1、报错问题
DB::Exception: Too many parts (300)

2、解决方法
2.1、方法1
- 修改clickhouse中的config.xml文件,添加以下配置参数(尝试增加可合并的分区数,修改ClickHouse配置文件中的<merge_tree>标签)
<merge_tree>
<parts_to_delay_insert>600</parts_to_delay_insert>
<parts_to_throw_insert>600</parts_to_throw_insert>
<max_delay_to_insert>5</max_delay_to_insert>
<max_suspicious_broken_parts>5</max_suspicious_broken_parts>
</merge_tree>
- 修改后,重启clickhouse
2.2、方法2
减少并发数:降低写入ClickHouse的并发数,增加每批处理的数据量。例如,将200并发调整到50并发,每批数据量从1万条调整到5万条,这样可以减少生成的parts文件数量,避免超过默认值。
2.3、方法3
优化Merge线程池大小:通过设置background_pool_size参数来优化,这个参数通常设置为CPU核心数的两倍。如果修改后仍然出现问题,可能需要临时调整其他参数,例如number_of_free_entries_in_pool_to_lower_max_size_of_merge,以允许表正常进行merge操作
2.4、方法4
存储方式优化:对于数据量较小的情况,可以选择Compact存储方式,以减少merge的压力和时间。对于数据量大的情况,使用Wide存储方式
2.5、方法5
合理设置分区:如果每次插入涉及的分区太多,可能会导致异常和插入耗时。合理设置分区字段,避免每次插入请求涉及过多分区
2.6、方法6
设置数据过期时间:如果单表存储的数据量过大,建议设置数据的过期时间,或者采用其他数据库存储过大数据量的表
总结
以上方案,仅供参考
拓展
我遇到的问题及解决根本方法
1、查看分区数
SELECT
database,
table,
count() AS parts_count
FROM system.parts
WHERE active = 1
GROUP BY database, table
ORDER BY parts_count DESC;

2、问题分析
我们发现,ssa_connector_change_detail_local表的parts_count数量非常大,由于我的表ssa_connector_change_detail_local是一个同步数据的表,三方一直在推数据,并且这张表存入的每一条数据都要反复查询当前条数据是否存在,存在就删除在插入,不存在直接插入。一直在进行删除和插入的处理,这样的写法即使将parts_to_delay_insert增加到6000甚至更大都没有用,时间久了,治标不治本。
3、解决方案
优化ssa_connector_change_detail_local的数据插入方案,批量新增或者批量删除。但是我的处理方案是,直接将这张表的业务停掉,这样就解决根本问题了
8937

被折叠的 条评论
为什么被折叠?



