この例外が意味すること
ClickHouse は、MergeTree テーブル内のアクティブなデータパーツ数に対する設定済みの上限を INSERT が超える場合、Too many parts 例外をスローします。この例外には、多くの場合、Merges are processing significantly slower than inserts というメッセージも含まれます。
同期 INSERT は、それぞれ少なくとも 1 つのデータパーツを作成します。insert に複数のパーティション値の行が含まれている場合、ClickHouse は影響を受ける各パーティションに対して 1 つずつパーツを作成できます。バックグラウンドマージによって小さなパーツはより大きなパーツへと結合されますが、ClickHouse がマージする速度を上回るペースで新しいパーツが作成されると、アクティブなパーツ数は増え続けます。
この例外は、次のいずれかの設定によってトリガーされる可能性があります。
parts_to_throw_insert: 単一のパーティション内のアクティブなパーツ数を制限します。max_parts_in_total: テーブル内のアクティブなパーツ総数を制限します。
原因を特定する
次のクエリを使って、アクティブなパーツ数が最も多いパーティションを特定します。
SELECT
database,
table,
partition_id,
count() AS active_parts,
sum(rows) AS rows,
formatReadableSize(sum(bytes_on_disk)) AS size_on_disk
FROM system.parts
WHERE active
AND database = '<database_name>'
AND table = '<table_name>'
GROUP BY
database,
table,
partition_id
ORDER BY active_parts DESC;max_parts_in_total によって適用されるテーブル全体の上限を確認するには、テーブル内のすべてのアクティブなパーツを数えます。
SELECT
database,
table,
count() AS active_parts,
sum(rows) AS rows,
formatReadableSize(sum(bytes_on_disk)) AS size_on_disk
FROM system.parts
WHERE active
AND database = '<database_name>'
AND table = '<table_name>'
GROUP BY
database,
table;一般的な原因には次のようなものがあります。
- 頻繁に行われる小規模な同期 insert。
- カーディナリティの高いパーティション化キー。
- 多数のパーティション値にまたがる行を含む insert。
- ストレージのスループット制限、空きディスク容量の不足、またはその他のリソース競合により、バックグラウンドマージが追いつかない。
現在実行中のマージは system.merges で確認でき、マージの失敗についてはサーバーログを確認できます。
例外の解決
同期 INSERT のバッチ化
挿入する前に、クライアント側で行をバッチ化します。各バッチには少なくとも 1,000 行、理想的には 10,000~100,000 行を含めてください。1 秒あたりおよそ 1 回の同期 INSERT を目安にしてください。INSERT の回数を減らして 1 回あたりのサイズを大きくすると、作成されるパーツが減り、バックグラウンドマージに必要な処理も少なくなります。
非同期挿入を使用する
クライアント側でのバッチ処理が現実的でない場合は、ClickHouseが受信データをサーバー側でまとめて処理できるよう、非同期挿入を使用してください。
INSERT INTO <table_name>
SETTINGS
async_insert = 1,
wait_for_async_insert = 1
VALUES (...);ClickHouse がデータの書き込みに成功した後でのみ insert を確認応答するよう、wait_for_async_insert = 1 のままにしてください。
パーティショニングキーを見直す
カーディナリティの低いパーティショニングキーを使用し、ユーザー識別子やリクエスト識別子のような値でパーティション化することは避けてください。ClickHouse は同じパーティション内でのみパーツをマージするため、パーティション数が多いと効率的にマージできなくなります。詳しくは、パーティショニングキーの選び方を参照してください。
マージのボトルネックを調査する
データの挿入がすでに適切にバッチ化されている場合は、ストレージ性能、利用可能なディスク容量、競合するバックグラウンドタスクを確認してください。マージ速度は、ストレージシステム、テーブルエンジン、ソートキー、圧縮、および利用可能な CPU と I/O の処理能力に左右されます。
第一の対処としてパーツ数の制限引き上げは避けてください
parts_to_throw_insert や max_parts_in_total を増やしても、パーツが過剰に作成される原因そのものは解決できません。制限値を引き上げれば例外の発生を遅らせることはできますが、その一方でファイルシステムやメタデータのオーバーヘッドが増え、クエリパフォーマンスが低下する可能性があります。これらの設定を変更するのは、原因を特定し、システムに十分な余力があることを確認した後にしてください。
復旧を確認する
insert戦略またはパーティション化方式を変更したら、診断クエリをもう一度実行します。アクティブなパーツの数は安定し、その後、バックグラウンドでのマージが追いつくにつれて減少していくはずです。バックログが解消されるまで、insert の失敗、空きディスク容量、および system.merges の監視を続けてください。