オブザーバビリティOSS
前提条件
- clickhouse-local がローカル環境にインストールされていること。開始方法については、clickhouse-local セットアップガイドを参照してください。
作成するもの
Map 型に適しています。キーは動的でアプリケーション固有ですが、通常は 1 行あたり数個しか含まれません。
このクイックスタートでは、clickhouse-local を使って CSVファイル から実際の OTel トレースデータを Map(LowCardinality(String), String) カラムを持つテーブルに読み込み、Map データのクエリ、フィルタリング、集計、最適化の方法を学びます。
サンプルデータをダウンロード
このデータセットには、デモ用マイクロサービスアプリケーションからエクスポートされた 6,120 件の OTel トレーススパンが含まれています。各行には、動的なキー・バリューのペアを JSON map として格納した
ResourceAttributes カラムと SpanAttributes カラムが含まれます。
ファイルは、たとえば ~/data/data-otel-traces.csv のように、簡単に参照できるディレクトリに保存してください。data-otel-traces.csv をダウンロード (2.9 MB)1 行分のデータは次のようになります。テーブルを作成してデータを読み込む
clickhouse-local を起動し、CSV に対応するスキーマで次のテーブルを作成します。
重要なカラムは ResourceAttributes Map(LowCardinality(String), String) です。OTel の属性キーは、比較的少数の同じ値が繰り返し現れるため、キー型に LowCardinality を使用しています。file テーブルエンジンを使って CSV を読み込みます。パスは、ファイルを保存した場所に合わせて調整してください。データをクエリする
特定のキーにアクセスする — 角括弧構文を使って、map から値を取り出します。行にそのキーが存在しない場合は、値の型の既定値が返されます (Mapの値でフィルタリング — 特定のサービス名に一致するすべてのスパンを見つけます:キーが存在するか確認する — すべてのスパンに Kubernetes のメタデータが付いているわけではありません。データセット全体で使われているすべてのキーを確認する — どのインストルメンテーションがデータを生成しているかを把握するのに役立ちます。ARRAY JOINでMapを行に展開 — 各キー・バリューのペアを1行ずつに展開します。属性の一覧を作成したり、ダッシュボードにデータを渡したりするのに便利です。mapFilter で Map をフィルタリング — 各スパンから Kubernetes 関連の属性のみを抽出します:エラースパンとそのリソースのコンテキストを特定する — 通常のカラムフィルターとマップアクセスを組み合わせます:
String の場合は空文字列) :mapContains を使うと、どのスパンに含まれているかを確認できます:-Map combinator を使って Map をキーごとに集計する
ClickHouse の 次に、これを他の combinator と組み合わせることもできます。たとえば、OTel でこれが重要な理由: OTel collector が 1 分ごとのステータスコードの内訳を ClickHouse に書き込む場合、
-Map 集約コンビネータを使うと、任意の集約関数を Map カラムに適用し、各キーごとに独立して集計できます。結果も Map となり、キーごとに 1 つのエントリと、その集計済みの値が格納されます。これは、カウンターや Gauge が Map の値として保存される OTel メトリクスで特に有用です。これを確認するために、各行に HTTP ステータスコードごとの件数を Map(String, UInt64) として記録する小さなメトリクス テーブルを作成します。sumMap を使って、各サービスについてステータスコードごとの件数を合計します。-Map 接尾辞は任意の集約関数と組み合わせて使えるため、minMap、maxMap、avgMap も同様に簡単に使えます:sumMapIf を使うと条件付きで集計できます。ここでは、サービスですでにエラーが発生していた分単位のウィンドウだけを合計します。sumMap を使えば、それらを 1 回のクエリで時間単位や日単位の totals に集計できます。ARRAY JOIN も unpivot も不要で、キーの全体集合を事前に把握しておく必要もありません。どの行に現れたキーも、自動的に結果に含まれます。要点
Map(LowCardinality(String), String)は OTel の属性に適した定番の型です。キー集合が変化しても柔軟に扱え、LowCardinalityによってキーの保存効率も高く保てます。- ブラケット構文 (
map['key']) は値にアクセスする最も一般的な方法ですが、線形走査になる点には注意してください。キーが数十個の map であれば問題ありませんが、数百個になると最適とはいえません。 - マテリアライズドカラム は有効な手段です。map のキーが頻繁にフィルタ条件の対象になる場合は、それを実カラムに昇格させることで、索引付きの列指向アクセスが可能になります。
mapContains,mapKeys,mapValues,mapFilterとARRAY JOINを使えば、SQL の中だけで map データを調べたり変換したりできる、豊富な手段が得られます。-Mapaggregate combinator (sumMap,avgMap,maxMapなど) は、行をまたいで各キーを個別に集計します。キー集合を事前に把握していなくても OTel メトリクスのカウンターを集約するのに最適で、ほかの集約関数コンビネータと組み合わせることもできます (たとえばsumMapIf) 。
