概要
ClickHouse と OLTP データベースにおけるデータ更新の違い
データの更新に関して言えば、ClickHouse と OLTP データベースは、その基盤となる設計思想と対象となるユースケースの違いから大きく異なります。例えば、行指向で ACID 準拠のリレーショナルデータベースである PostgreSQL は、Multi-Version Concurrency Control (MVCC) のようなメカニズムを通じてデータの整合性と一貫性を確保し、堅牢なトランザクショナルな更新および削除操作をサポートしています。これにより、高い同時実行環境でも安全かつ信頼できる修正が可能になります。
これに対して、ClickHouse は読み取り重視の分析と高スループットの追加オンリー操作に最適化された列指向データベースです。もともとインプレースでの更新や削除をサポートしていますが、高い I/O を避けるためには慎重に使用する必要があります。代わりに、テーブルを再構築して削除および更新を追加操作に変換することも可能で、これにより非同期で処理されたり、あるいは読み取り時に展開されたりするため、高スループットのデータ取り込みと効率的なクエリ性能を重視し、リアルタイムでのデータ操作に依存しないことが反映されます。
ClickHouse でのデータ更新方法
ClickHouse でデータを更新する方法はいくつかあり、それぞれに利点と性能特性があります。適切な方法は、データモデルと更新するデータの量に基づいて選択するべきです。
両方の操作において、提出された変異の数が一定の時間間隔においてバックグラウンドで処理される変異の数を常に超える場合、適用される必要のある非物質化の変異のキューが成長し続けます。これにより、最終的には SELECT
クエリの性能が劣化します。
要約すると、更新操作は慎重に発行されるべきで、変異のキューは system.mutations
テーブルを使用して注意深く監視されるべきです。OLTP データベースのように頻繁に更新を発行しないでください。頻繁な更新の要件がある場合は、ReplacingMergeTree を参照してください。
メソッド | 構文 | 使用時期 |
---|---|---|
Update mutation | ALTER TABLE [table] UPDATE | データをディスクに即座に更新しなければならない場合に使用します(例:コンプライアンスのため)。SELECT パフォーマンスに悪影響を及ぼします。 |
Lightweight updates | UPDATE [table] SET ... WHERE | 小規模なデータの更新(テーブルの最大〜10%)に使用します。全カラムを書き換えることなく、即時可視性のためのパッチパーツを生成します。SELECT クエリにはオーバーヘッドが追加されますが、予測可能なレイテンシがあります。現在は実験的です。 |
On-the-fly updates | ALTER TABLE [table] UPDATE | SET apply_mutations_on_fly = 1; を使用して有効にします。小規模なデータの更新に使用します。行は、以降のすべての SELECT クエリで更新されたデータとともに即座に返されますが、最初はディスク上では内部的にのみ更新されたとマーキングされます。 |
ReplacingMergeTree | ENGINE = ReplacingMergeTree | 大量のデータを更新する場合に使用します。このテーブルエンジンは、マージ時のデータ重複排除に最適化されています。 |
CollapsingMergeTree | ENGINE = CollapsingMergeTree(Sign) | 個別の行を頻繁に更新する場合や、時間の経過とともに変化するオブジェクトの最新の状態を維持する必要があるシナリオに使用します。例えば、ユーザー活動や記事の統計を追跡する場合です。 |
更新変異
更新変異は ALTER TABLE ... UPDATE
コマンドを通じて発行できます。例えば、
これは非常に I/O 集約型で、WHERE
式に一致するすべてのパーツを書き換えます。このプロセスには原子的な性質はありません。パーツは、変更が準備でき次第、変更されたパーツに置き換えられ、変異中に開始された SELECT
クエリは、すでに変更されたパーツのデータとまだ変更されていないパーツのデータを見ることになります。ユーザーは systems.mutations テーブルを介して進行状況の状態を追跡できます。これらは I/O 集約型の操作であり、クラスターの SELECT
パフォーマンスに影響を与える可能性があるため、慎重に使用する必要があります。
更新変異 について詳しく読む。
軽量更新
軽量更新は、行を「パッチパーツ」を使用して更新する ClickHouse の機能です。これは、従来の変異のように全カラムを書き換えるのではなく、更新されたカラムと行のみを含む特別なデータパーツから成ります。軽量更新の主な特徴:
- 標準の
UPDATE
構文を使用し、マージを待つことなく即座にパッチパーツを生成します - 更新された値は、パッチの適用を通じて
SELECT
クエリで即座に可視化されますが、物理的には次回のマージ時にのみ具現化されます - 予測可能なレイテンシを持つ小規模な更新(最大〜10%のテーブル)用に設計されています
- パッチを適用する必要のある
SELECT
クエリにオーバーヘッドが追加されますが、全カラムの書き換えを回避します
詳細については、"軽量 UPDATE 文" を参照してください。
オン・ザ・フライ更新
オン・ザ・フライ更新は、行を即座に更新するメカニズムを提供し、以降の SELECT
クエリは自動的に変更された値を返します(これにはオーバーヘッドが発生し、クエリ速度が遅くなる可能性があります)。これにより、通常の変異の原子的制限に対応します。以下に例を示します:
オン・ザ・フライ更新では、データを更新するために変異がまだ使用されることに注意してください。これはただ即座には具現化されず、SELECT
クエリで適用されます。バックグラウンドで非同期プロセスとして適用され、変異と同じ重いオーバーヘッドが発生するため、これは I/O 集約型の操作であり、慎重に使用する必要があります。この操作に使用できる式も限られています(詳細については こちら を参照してください)。
オン・ザ・フライ更新 について詳しく読む。
CollapsingMergeTree
更新が高コストである一方で、挿入を活用して更新を実行できるという考え方から、CollapsingMergeTree
テーブルエンジンは、特定の行を削除(カラプス)することで更新する方法として、sign
カラムとともに使用することができます。
sign
カラムに -1
が挿入されると、全行が削除されます。
sign
カラムに 1
が挿入されると、ClickHouse はその行を保持します。
更新対象の行は、テーブル作成時に使用するソートキーに基づいて識別されます。
上記の更新アプローチは、ユーザーがクライアント側で状態を維持する必要があります。 これは ClickHouse の観点からは最も効率的ですが、大規模での取り扱いは複雑になる可能性があります。
CollapsingMergeTree
に関する文書を読むことをお勧めします
より包括的な概要について。