メインコンテンツまでスキップ
メインコンテンツまでスキップ

ClickHouseデータの挿入

基本的な例

ClickHouseでは、馴染みのある INSERT INTO TABLE コマンドを使用できます。最初のガイドで作成したテーブルにデータを挿入してみましょう "ClickHouseでのテーブル作成"

これが成功したか確認するために、次の SELECT クエリを実行します。

これにより、次の結果が返されます。

ClickHouseにデータを挿入することとOLTPデータベース

ClickHouseはOLAP(オンライン分析処理)データベースとして、高いパフォーマンスとスケーラビリティに最適化されており、秒間に数百万行を挿入できる可能性があります。 これは、高度に並列化されたアーキテクチャと効率的な列指向圧縮の組み合わせによって実現されていますが、即時の整合性には妥協があります。 具体的には、ClickHouseは追加のみの操作に最適化されており、最終的な整合性のみの保証を提供します。

対照的に、PostgresなどのOLTPデータベースは、完全なACID準拠でトランザクション挿入に特化して最適化されており、強い整合性と信頼性の保証を確保しています。 PostgreSQLはMVCC(マルチバージョン同時実行制御)を使用して同時トランザクションを処理し、データの複数のバージョンを維持します。 これらのトランザクションは、通常少数の行を対象とし、信頼性の保証により挿入パフォーマンスにかなりのオーバーヘッドが発生します。

高い挿入パフォーマンスを維持しつつ強い整合性の保証を確保するために、ユーザーはClickHouseにデータを挿入する際に以下の単純なルールを守るべきです。 これらのルールに従うことで、ユーザーがClickHouseを初めて使用する際に一般的に直面する問題を避けることができ、OLTPデータベースに対して機能する挿入戦略を模倣することができます。

挿入のベストプラクティス

大規模なバッチサイズで挿入する

デフォルトでは、ClickHouseに送信された各挿入により、ClickHouseはすぐに挿入からのデータを含むストレージの一部を作成し、保存する必要のある他のメタデータも含まれます。 したがって、より多くのデータを含む少量の挿入を送信することに比べ、より少ないデータを含む大量の挿入を送信することは、必要な書き込みの数を減少させます。 一般的には、一度に少なくとも1,000行のかなり大きなバッチでデータを挿入することをお勧めします。理想的には10,000行から100,000行の間です。 (さらなる詳細は ここ)。

大規模なバッチが不可能な場合は、以下の非同期挿入を使用してください。

再試行を無駄なくするために一貫したバッチを確保する

デフォルトでは、ClickHouseへの挿入は同期的であり、冪等性があります(同じ挿入操作を複数回実行しても、一度だけ実行した場合と同じ効果があります)。 MergeTreeエンジンファミリーのテーブルの場合、ClickHouseはデフォルトで挿入の重複排除を自動的に行います。

これは、次のような場合に挿入が頑強であることを意味します:

    1. データを受信するノードに問題がある場合、挿入クエリはタイムアウトまたはより具体的なエラーを返し、確認応答が得られません。
    1. データがノードに書き込まれたが、ネットワークの中断により確認応答を送信者に返せない場合、送信者はタイムアウトまたはネットワークエラーを受け取ります。

クライアントの視点では、(i) と (ii) は区別が難しいかもしれません。しかし、どちらの場合でも、確認応答を受け取っていない挿入はすぐに再試行できます。 再試行した挿入クエリが、元の(確認応答を受け取っていない)挿入と同じデータを同じ順序で含んでいる限り、ClickHouseは自動的に再試行した挿入を無視します。

MergeTreeテーブルまたは分散テーブルに挿入する

MergeTree(またはレプリカテーブル)に直接挿入し、データがシャードされている場合はノードのセット間でリクエストのバランスを取り、internal_replication=trueを設定することをお勧めします。 これにより、ClickHouseはデータを利用可能なレプリカシャードにレプリケートし、データが最終的に整合性を持つことが保証されます。

クライアント側の負荷分散が不便な場合、ユーザーは分散テーブルを介して挿入することができ、これによりノード間で書き込みが分散されます。再度、internal_replication=trueを設定することをお勧めします。 ただし、このアプローチは、分散テーブルを持っているノードにローカルに書き込みを行い、その後シャードに送信する必要があるため、パフォーマンスがやや低下することに注意が必要です。

小さなバッチの非同期挿入を使用する

クライアント側のバッチ処理が非現実的なシナリオがあります。例として、ログ、メトリックス、トレースなどを送信する100台または1000台の単一目的エージェントを持つ可観測性のユースケースがあります。 このシナリオでは、データのリアルタイム輸送が重要であり、迅速に問題や異常を検出するために重要です。 さらに、観測システムでのイベントスパイクのリスクがあり、これが原因でクライアント側で可観測データをバッファリングしようとした場合に大きなメモリスパイクや関連する問題を引き起こす可能性があります。 大規模なバッチを挿入できない場合、ユーザーは非同期挿入を使用してClickHouseにバッチ処理を委任できます。

非同期挿入では、データは最初にバッファに挿入され、その後、以下の3つのステップでデータベースストレージに書き込まれます。

非同期挿入が有効になっている場合、ClickHouseは:

(1) 非同期的に挿入クエリを受け取ります。 (2) クエリのデータを最初にメモリ内のバッファに書き込みます。 (3) 次のバッファフラッシュが行われるときに、データをデータベースストレージの一部としてソートして書き込みます。

バッファがフラッシュされる前に、同じクライアントまたは他のクライアントからの他の非同期挿入クエリのデータがバッファに収集される可能性があります。 バッファフラッシュから作成された部分には、複数の非同期挿入クエリのデータが含まれる可能性があります。 一般的に、これらのメカニズムはデータのバッチ処理をクライアント側からサーバー側(ClickHouseインスタンス)に移行します。

注記

データは、データベースストレージにフラッシュされる前はクエリによって検索できないことに注意してください。また、バッファフラッシュは構成可能です。

非同期挿入を構成するための詳細はこちらで、深く掘り下げた情報はこちらをご覧ください。

公式のClickHouseクライアントを使用する

ClickHouseには、最も人気のあるプログラミング言語でのクライアントが用意されています。 これらは、挿入が正しく行われることを保証し、例えばGoクライアントのように直接、またはクエリ、ユーザー、接続レベルの設定で有効にした場合には非同期挿入をネイティブにサポートするように最適化されています。

使用可能なClickHouseクライアントおよびドライバの完全なリストは、クライアントとドライバを参照してください。

ネイティブ形式を優先する

ClickHouseは、多くの入力形式を挿入(およびクエリ)時にサポートしています。 これはOLTPデータベースとの大きな違いであり、外部ソースからのデータの読み込みを大幅に容易にします。特に、テーブル関数やディスク上のファイルからのデータ読み込み機能と組み合わせると便利です。 これらの形式は、アドホックデータロードやデータエンジニアリングタスクに理想的です。

最適な挿入パフォーマンスを実現したいアプリケーションでは、ネイティブ形式を使用して挿入することをお勧めします。 これはほとんどのクライアント(GoやPythonなど)でサポートされており、列指向のフォーマットであるため、サーバーが最小限の作業を行えば済みます。 これにより、データを列指向フォーマットに変換する責任がクライアント側に置かれます。これは、効率的に挿入をスケールさせるために重要です。

また、行形式が好ましい場合は、RowBinary形式(Javaクライアントで使用)を使用することもできます。これは、ネイティブ形式よりも書き込みやすいことが一般的です。 これはJSONのような他の行形式に比べて、圧縮、ネットワークオーバーヘッド、サーバー上の処理の面でより効率的です。 JSONEachRow形式は、速やかに統合したいが書き込みスループットが低いユーザー向けに考慮されることがあります。この形式は、ClickHouse内での解析にCPUオーバーヘッドが発生することに注意してください。

HTTPインターフェースを使用する

多くの従来のデータベースとは異なり、ClickHouseはHTTPインターフェースをサポートしています。 ユーザーは、上記のいずれかの形式を使ってデータを挿入およびクエリするためにこれを使用できます。 これは、トラフィックをロードバランサーで簡単に切り替えることができるため、ClickHouseのネイティブプロトコルよりも好まれることがよくあります。 ネイティブプロトコルでは小さな違いが挿入パフォーマンスにあると予想され、オーバーヘッドが少し低くなります。 既存のクライアントは、これらのプロトコルのいずれか(場合によっては両方、例えばGoクライアント)を使用しています。 ネイティブプロトコルでは、クエリの進捗を簡単に追跡できます。

詳細についてはHTTPインターフェースを参照してください。

Postgresからデータをロードする

Postgresからデータをロードするために、ユーザーは次のものを使用できます:

  • PeerDB by ClickHouse、PostgreSQLデータベースのレプリケーションのために特別に設計されたETLツール。これは次の両方で利用可能です:
  • 以前の例で示されたように、データを直接読み込むためのPostgreSQLテーブルエンジン。既知のウォーターマーク(例:タイムスタンプ)に基づいたバッチレプリケーションが十分な場合や、単発の移行が適している場合があります。このアプローチは1,000万行のスケールに対応できます。より大きなデータセットの移行を考えているユーザーは、各データのチャンクを扱う複数のリクエストを考慮する必要があります。各チャンクのパーティションを移動する前にステージングテーブルを使用できます。これにより、失敗したリクエストを再試行できます。このバルクローディング戦略に関する詳細は、こちらをご覧ください。
  • データはCSV形式でPostgreSQLからエクスポートできます。これをClickHouseに挿入することができ、ローカルファイルまたはオブジェクトストレージを介して、テーブル関数を使用して行います。
大きなデータセットの挿入に関するヘルプが必要ですか?

大きなデータセットの挿入や、ClickHouse Cloudへのデータインポート中にエラーが発生した場合は、[email protected]までご連絡いただければ、サポートいたします。