现象:升级clickhouse版本后,出现如下报错,该报错一般出现于数据高速写入时,merge的速度赶不上part产生的速度,导致part数量堆积过多。
DB::Exception: Too many parts (300). Parts cleaning are processing significantly slower than inserts (version 21.4.6.55 (official build))
在clickhouse中,MergeTree家族的engine为了最大化保证写入速度,每个线程的每次插入,都会产生一个part,同一个partition内的多个part则会在后台进行merge,合并成一个更大的part。
clickhouse除了会控制单表层面的part数量之外,为了减轻merge压力(merge一般是在同一个partition内进行),它同样还会控制单个partition内的part数目。道理和前面一样,单个parttition内的part数目过多,自然要经过很多轮merge才能形成最终态,这个过程是非常吃CPU的,势必会影响到写入和查询。
clickhouse使用parts_to_throw_insert来控制单个partition内的part数量上限,如果单个partition内的part数量超过了这个上限,同样会报too many parts(300) 的错误。这个上限是多少呢?默认值是300。
--- 查看系统默认配置
SELECT
name,
value
FROM system.merge_tree_settings
WHERE name IN ('max_parts_in_total', 'parts_to_throw_insert', 'inactive_parts_to_throw_insert')
Query id: 88eba13a-5fe8-476d-bb7b-5b6353d9142b
┌─name───────────────────────────┬─value──┐
│ parts_to_throw_insert │ 300 │
│ inactive_parts_to_throw_insert │ 0 │
│ max_parts_in_total │ 100000 │
└────────────────────────────────┴────────┘
--- 查单表的总part数目
SELECT count()
FROM system.parts
WHERE (database = '<database>') AND (table = '<table>') AND (active = '1')
Query id: c3dec6f3-da47-441e-beed-682536390c46
┌─count()─┐
│ 131150 │
└─────────┘
--- 查单个partition内最多的part数目
SELECT
name,
count() AS cnt
FROM system.parts
WHERE (database = '<database>') AND (table = '<table>') AND (active = '1')
GROUP BY name
ORDER BY cnt ASC
LIMIT 1
查看后台Merge线程池配置和当前线程使用情况,每个clickhouse节点上都是独立的线程池,互不干扰
SELECT
metric,
value
FROM system.metrics
WHERE metric LIKE 'BackgroundMergesAndMutationsPool%'
Query id: ffb22e4e-6114-4711-a023-385795dc4315
┌─metric───────────────────────────────┬─value─┐
│ BackgroundMergesAndMutationsPoolTask │ 0 │
│ BackgroundMergesAndMutationsPoolSize │ 64 │
└──────────────────────────────────────┴───────┘
2 rows in set. Elapsed: