オブザーバビリティのための ClickHouse 活用
はじめに
このガイドは、ClickHouse を用いて独自の SQL ベースのオブザーバビリティソリューション(特にログとトレースに焦点を当てたもの)を構築したいユーザー向けに作成されています。ここでは、インジェストに関する考慮事項、アクセスパターンに最適化されたスキーマ設計、非構造化ログの構造化など、独自ソリューションを構築するうえでのあらゆる側面をカバーします。
ClickHouse 単体は、オブザーバビリティ向けのすぐに使えるソリューションではありません。しかし、オブザーバビリティデータのための非常に高効率なストレージエンジンとして利用でき、他に類を見ない圧縮率ときわめて高速なクエリ応答時間を実現します。ユーザーがオブザーバビリティソリューションの一部として ClickHouse を利用するには、ユーザーインターフェースとデータ収集フレームワークの両方が必要です。現時点では、オブザーバビリティシグナルの可視化には Grafana を、データ収集には OpenTelemetry を使用することを推奨しています(いずれも公式にサポートされている連携です)。

データ収集には OpenTelemetry (OTel) プロジェクトを使用することを推奨していますが、Vector や Fluentd など他のフレームワークやツールを利用しても同様のアーキテクチャを構成できます(Fluent Bit を用いた例を参照してください)。Superset や Metabase など、他の可視化ツールも存在します。
なぜ ClickHouse を使うのか
あらゆる集中型の Observability ストアにおいて最も重要な機能は、多様なソースから集まる膨大なログデータを高速に集約・分析・検索できることです。この集中管理によりトラブルシューティングが効率化され、サービス障害の根本原因を特定しやすくなります。
ユーザーはますますコストに敏感になっており、既製のソリューションのコストが、それらがもたらす価値に対して高額かつ予測しづらいと感じています。そのため、クエリ性能が許容できる範囲で、コスト効率が高く予測可能なログストレージの価値はこれまで以上に高まっています。
その性能とコスト効率の高さから、ClickHouse は Observability 製品におけるログおよびトレースのストレージエンジンとして、事実上の標準となっています。
より具体的には、以下の理由から、ClickHouse は Observability データの保存に理想的です。
- 圧縮 - Observability データには、HTTP コードやサービス名など、値が限定された集合から取られるフィールドが含まれるのが一般的です。値がソートされた状態で格納される ClickHouse のカラム指向ストレージにより、この種のデータは非常に高い圧縮率を実現します。特に、時系列データ向けの各種専用コーデックと組み合わせた場合に効果的です。他の多くのデータストアでは、通常 JSON 形式など元データとほぼ同程度のストレージ容量が必要になるのに対し、ClickHouse はログやトレースを平均で最大 14 倍まで圧縮します。大規模な Observability 環境でストレージを大幅に節約できるだけでなく、ディスクから読み出すデータ量が減ることでクエリの高速化にも寄与します。
- 高速な集約処理 - Observability ソリューションでは、エラーレートを示す折れ線グラフや、トラフィックソースを示す棒グラフなど、チャートによるデータの可視化が多用されます。これらのチャートを支えるのが集約処理、すなわち GROUP BY であり、問題診断のワークフローでフィルタを適用した際にも高速かつ応答性よく動作する必要があります。ClickHouse のカラム指向フォーマットとベクトル化されたクエリエンジンの組み合わせは、高速な集約処理に最適であり、スパースインデックスによってユーザー操作に応じたデータの高速フィルタリングが可能になります。
- 高速な線形スキャン - 他の技術スタックでは、ログの高速クエリのために逆インデックスに依存することが多く、その結果としてディスクやリソースの使用量が増大しがちです。ClickHouse も追加のオプションとして逆インデックスを提供しますが、線形スキャンは高度に並列化されており(特に設定を変更しない限り)マシン上のすべてのコアを活用します。これにより、理論上は(圧縮済みで)秒間数十 GB のデータをスキャンし、高度に最適化されたテキストマッチ演算子で一致を検索することが可能です。
- SQL の親しみやすさ - SQL はあらゆるエンジニアに広く浸透している言語です。50年以上の歴史の中で、データ分析の事実上の標準言語としての地位を確立しており、現在も3番目に人気のあるプログラミング言語であり続けています。Observability もまた、SQL が最適な対象となる「データの問題」にすぎません。
- 分析関数 - ClickHouse は、SQL クエリをより簡潔かつ記述しやすくするために設計された分析関数によって ANSI SQL を拡張しています。これらは、データを多角的に切り分けながら根本原因分析を行うユーザーにとって不可欠です。
- セカンダリインデックス - ClickHouse は、特定のクエリパターンを高速化するために、ブルームフィルターなどのセカンダリインデックスをサポートしています。これらはカラム単位で任意に有効化でき、ユーザーはきめ細かな制御を行いながら、コストとパフォーマンスのトレードオフを評価できます。
- オープンソース & オープンスタンダード - オープンソースのデータベースとして、ClickHouse は OpenTelemetry などのオープンスタンダードを採用しています。プロジェクトにコントリビュートし、積極的に参加できる点は魅力的であり、同時にベンダーロックインの問題を回避できます。
可観測性に ClickHouse を使用すべきタイミング
可観測性データに ClickHouse を使用するには、SQL ベースの可観測性というアプローチを採用する必要があります。SQL ベースの可観測性の歴史については このブログ記事 を参照してください。要約すると、次のとおりです。
SQL ベースの可観測性は、次のような場合に適しています。
- 自身やチームが SQL に慣れている(もしくはこれから学びたいと考えている)
- ベンダーロックインを避け拡張性を確保するために、OpenTelemetry のようなオープンな標準に準拠することを好む
- 収集から保存、可視化まで、オープンソースによるイノベーションに支えられたエコシステムを運用する意思がある
- 管理対象となる可観測性データ量が中規模から大規模(あるいは非常に大規模)へと成長していくことを想定している
- TCO(総保有コスト)を自らコントロールし、可観測性コストの膨張を避けたい
- コスト管理のためだけに、可観測性データの保持期間を短く制限された状態に甘んじたくない
SQL ベースの可観測性が適さない可能性があるのは、次のような場合です。
- SQL を学ぶ(あるいは生成する)ことが、自身やチームにとって魅力的ではない
- パッケージ化されたエンドツーエンドの可観測性環境を求めている
- 可観測性データ量が非常に小さく(例: <150 GiB)、今後も増加が見込まれない
- ユースケースがメトリクス中心であり、PromQL を必要としている。この場合でも、メトリクスには Prometheus を用いつつ、ログとトレースには ClickHouse を使用し、プレゼンテーションレイヤーで Grafana によって統合することは可能です。
- さらにエコシステムが成熟し、SQL ベースの可観測性がより「すぐ使える」状態になるまで待ちたい
ログとトレース
Observability のユースケースには、ログ、トレース、メトリクスという 3 つの明確な柱があります。各柱はデータ型とアクセスパターンが異なります。
現在、ClickHouse を次の 2 種類の Observability データの保存先として推奨しています。
- ログ - ログは、システム内で発生するイベントにタイムスタンプを付けて記録したものであり、ソフトウェア動作のさまざまな側面に関する詳細な情報を保持します。ログ内のデータは一般的に非構造化または半構造化であり、エラーメッセージ、ユーザーアクティビティのログ、システム変更、その他のイベントを含むことがあります。ログは、トラブルシューティング、異常検知、そしてシステム内の問題発生に至るまでの具体的なイベントの把握に不可欠です。
- Traces - Traces は、分散システム内でリクエストがさまざまなサービスを横断していく過程を捉え、その経路とパフォーマンスの詳細を記録します。Trace のデータは高度に構造化されており、タイミング情報を含め、リクエストがたどる各ステップをマッピングする span と trace で構成されます。Traces はシステムパフォーマンスに関する有益な洞察を提供し、ボトルネックやレイテンシ問題の特定、マイクロサービスの効率最適化に役立ちます。
ClickHouse はメトリクスデータの保存にも使用できますが、この柱については、Prometheus データフォーマットや PromQL のサポートなどの機能がまだ開発途上であり、ClickHouse における成熟度はそれほど高くありません。
分散トレーシング
分散トレーシングは、オブザーバビリティにおける重要な機能です。分散トレース(単にトレースとも呼ばれます)は、システム内を流れるリクエストの経路を表現します。リクエストはエンドユーザーまたはアプリケーションから送信され、システム全体へと広がり、一般的にはマイクロサービス間の一連の処理フローとして現れます。このシーケンスを記録し、その後に発生するイベント同士を相関付けることで、アーキテクチャの複雑さやサーバーレスであるかどうかに関わらず、オブザーバビリティの利用者や SRE はアプリケーションフロー内の問題を診断できるようになります。
各トレースは複数のスパンで構成され、リクエストに紐づく最初のスパンはルートスパンと呼ばれます。このルートスパンは、リクエスト全体を開始から終了まで記録します。ルートの下に続くスパンは、リクエスト処理の中で発生するさまざまなステップや操作についての詳細な洞察を提供します。トレーシングがなければ、分散システムにおけるパフォーマンス問題の診断は極めて困難になり得ます。トレーシングは、リクエストがシステム内を移動する際のイベントシーケンスを詳細に示すことで、分散システムのデバッグと理解を容易にします。
多くのオブザーバビリティベンダーは、この情報をウォーターフォール形式で可視化し、各処理の相対的な時間を、長さが比例した横棒を用いて表現します。たとえば Grafana では、次のように表示されます。

ログやトレースの概念をより深く理解する必要があるユーザーには、OpenTelemetry のドキュメント を参照することを強く推奨します。