
コストを抑えるためだけにトレースをサンプリングしていませんか?
クエリを実行できるようにするために、高カーディナリティなメトリクスをロールアップしていませんか?
すべてを保存するコストをまかなえないという理由だけで、ログの保持期間を制限していませんか?
こうしたパターンはオブザーバビリティにおいてあまりにも一般的になり、ベストプラクティスとして扱われることさえあります。ベンダーは自社の欠点を隠すために、これらを機能として売り込んでいます。ClickHouse では、これらは単なる回避策であり、ツールを使うエンジニアのニーズではなく、その背後にあるシステムの制約を反映したものにすぎないと考えています。
なぜ SRE が、どのデータを保持し、破棄し、集計すべきかを厳しく管理しなければならないような世界になってしまったのでしょうか。そしてさらに重要なのは、今後もそうあり続ける必要があるのか、という点です。
本記事では、現代のオブザーバビリティを形作っている 3 つの制約として、保持期間(retention)、サンプリング(sampling)、ロールアップ(rollups)を取り上げます。これらは中立的な設計上の選択肢などではなく、スケール、コスト、高カーディナリティデータに苦しむストレージエンジンや、その制約をユーザーに転嫁している SaaS プラットフォームによって課された限界なのです。
かつては、こうしたトレードオフも許容できるものでした。人間の運用担当者なら、欠落したデータを経験と直感で補うことができたからです。しかし、その前提は崩れつつあります。実務者の少なくとも 90% が、異常の検知や根本原因分析の支援に AI を活用することに価値を見出している一方で、既存のシステムはそれを支えられるようには設計されていません。AI やエージェント駆動のワークフローがオブザーバビリティの中心になるにつれて、サンプリング、集計、短い保持期間による弊害ははるかに深刻になります。自動推論に必要なコンテキストが失われるだけでなく、エージェントが自らの結論を根拠立てて説明することも難しくなります。これは実務者の 95% 以上が求めている要件です。
かつては受け入れられていた妥協が、今や明確な足かせとなっています。自動診断や自動推論を支援できるシステムを構築するには、これらの制約を取り除かなければなりません。
これらを解消できれば、単にトレードオフが減るだけでなく、根本的により優れたオブザーバビリティモデルが実現します。死角がなくなり、障害復旧までの時間が短縮され、次世代のエージェント駆動ワークフローに必要な完全なコンテキストが手に入ります。
今すぐ始める
自社のオブザーバビリティデータで Managed ClickStack がどう機能するかご興味はおありですか? 数分で使い始めることができ、$300 分の無料クレジットを進呈しています。
サインアップ保持期間:記憶にかかる税金
保持期間は、オブザーバビリティの利用者が最初に考慮を求められる制約の1つです。これはほぼ自動的な検討事項となっています。ログはどのくらいの期間保持すべきか? トレースはどこまで遡るべきか? 許容できるコストはどれくらいか?
ある程度までは、これは妥当なことです。すべてのデータを無期限に保存する必要はなく、時間の経過とともにデータを期限切れにする正当な理由もあります。しかし問題は保持期間が存在することではなく、それが主要な関心事となってしまい、チームが極端に短い期間の選択を強いられることが多い点にあります。ログは7〜14日間しか保持されないことが多く、トレースはそのデータ量やカーディナリティの高さから、さらにアグレッシブに切り捨てられます。
これはユーザーのニーズによるものではなく、システムの限界によるものです。多くのシステムはクエリ性能を出すためにSSDベースのストレージに依存しており、圧縮率の低さと相まって、長期保持のコストが高くなります。その結果、これらのコストは吸収されるか利用者に転嫁され、エンドユーザーは保持期間を予算の問題として扱わざるを得なくなります。

保持期間を延ばすために、チームは階層を導入し、データを次第に安価で性能の低いストレージへと移していきます。これにより長期保持は可能になりますが、複雑さが増し、過去のデータをクエリする際にリハイドレーションや遅いクエリが必要になります。
しかし、本来そうあるべきではありません。高い圧縮率とオブジェクトストレージを活用すれば、経済性は一変します。オブジェクトストレージ上に1 GBあたり約0.025ドルで保存でき、これに50倍の圧縮を組み合わせれば、生データを一般的なコストの数分の一で保持できます。30日、60日、あるいは1年の保持期間をデフォルトとすべきです。データの失効はコストの圧力ではなく、コンプライアンスやポリシーに基づいて行われるべきです。
オブジェクトストレージの採用は、ストレージ階層の管理を意味するべきではありません。どのデータがホット、ウォーム、あるいはオブジェクトストレージにアーカイブされたものかをユーザーが判断する必要はないはずです。すべてのデータが取り込まれて均等に扱われ、頻繁にアクセスされるデータはクエリパターンに基づいて自動的に高速化されるべきです。階層の導入は、根本的な問題を解決することなく、どこに何を保存するかをユーザーに絶えず考えさせることになり、複雑さと運用の負担を増やすだけです。
この制約を取り除くことは、単に運用の負担を減らすだけにとどまりません。まったく新しい働き方を可能にします。長期保持によって、季節的なパターンや過去のデグラデーション(リグレッション)、以前は見落とされていた問題の分析が可能になります。1つのログパターンを数か月分のデータにわたって遡り、バグが最初に発生した時期や影響を受けたユーザーを把握できます。

データが存在しない場合、エージェントが周期的なパターンを特定するのは困難です。
エージェントがオブザーバビリティのワークフローに組み込まれるにつれ、過去のコンテキストへのアクセスが不可欠になります。人間のオペレーターは過去のインシデントやパターンに関する暗黙知を持っていますが、エージェントにはそれがありません。長期データがなければ、異常と想定通りの動作を区別したり、傾向を推論したりできません。保持期間を制限することは、可視性を低下させるだけでなく、エージェントが機能する能力そのものを制約します。
これらの理由から、保持期間は私たちの最初の敵(ヴィラン)です。データが一切期限切れになってはならないからではなく、基盤となるストレージシステムに起因するコストのせいで、何を保持すべきかを判断する負担がユーザーに押し付けられているからです。
サンプリング:穴だらけのオブザーバビリティ
サンプリングは、意図的にデータを破棄し始める手法です。どれだけ過去まで遡れるかを制限する保持期間とは異なり、サンプリングは何をそもそも見られるかを決定づけます。
主にトレースに適用されるサンプリングは、イベントのサブセットだけを選択的に保持することで機能します。これは通常、ヘッドサンプリングまたはテールサンプリングのいずれかを使用して行われます。ヘッドサンプリングはトレースの開始時に決定を下し、全体が観測される前に保持するか破棄するかを決めます。テールサンプリングはその決定をトレースが完了するまで遅らせ、明示的にエラーとラベル付けされたものや高レイテンシのものなど、特定の基準を満たすトレースをシステムが保持できるようにします。テールサンプリングのほうが情報に基づいた判断ができますが、どちらのアプローチも最終的にはデータを破棄します。たとえば、論理的な問題を示しているものの明示的にエラーとしてラベル付けされていないデータを見落とす可能性があります。同じパターンはロギングにも現れ、エラーログは保持される一方で、データ量の多い情報ログ(infoログ)はサービスごとに選択的に削減されることがあります。

ヘッドベースのサンプリングは事前にトレースを選択するため(決定的またはランダム)、重大なエラーを含むトレースが破棄される可能性があります。一方、テールベースのサンプリングはすべてのスパンを待ってから問題のあるトレースの保持を優先します。テールサンプリングのほうが情報に基づいているとはいえ、どちらのアプローチもデータを破棄することに変わりはなく、重要なシグナルを失うリスクがあります。
その目的は単純です。サンプリングによって書き込まれるデータ量を減らし、ストレージ要件を抑え、クエリ時にスキャンされるデータ量を最小限に抑えます。そうすることでコストを制御します。しかし保持期間と同様に、これはユーザー主導の最適化ではなく、システムによって課された制約であり、何を保持する価値があるかを判断する負担が再びユーザーに転嫁されています。
多くの点で、サンプリングは保持期間よりもさらに制約的です。保持期間が短くても、少なくともその期間内であれば利用可能なデータは完全です。対照的にサンプリングは、取り込みの時点で忠実性を奪ってしまいます。
この忠実性の喪失は、より広範な影響を及ぼします。現代のオブザーバビリティは、ログ、メトリクス、トレースを統合された「ワイドイベント」にまとめた、リッチで高カーディナリティなイベントへの依存度を高めています。これらによって、より深い分析、傾向の検出、時間をかけたより正確な推論が可能になります。サンプリングはこのモデルを崩してしまいます。イベントを取り除くことで、集計を歪め、統計的精度を落とし、意味のある分析を行う能力を制限します。
サンプリングされたメトリクスを外挿して近似結果を出すことは可能です。これは多くの単純な集計タイプには有効ですが、それ以外の集計では難しく、結果としてユーザーは常に推計値に頼らざるを得なくなります。
保持期間と同様に、これもまたエージェントの有効性を制約します。完全なデータがなければ、エージェントはパターンを確実に検出したり、シグナルを関連付けたり、異常について推論したりすることができません。また保持期間と同じく、かつては受け入れられていたトレードオフが、今や厳格な制限となって立ちはだかります。
理想的なシステムでは、効率的な圧縮と低コストなストレージによって、すべてのイベントが完全な忠実性で保持されます。これにより、問題が発生した際に完全なコンテキストを利用できます。その結果、エンジニアの解決までの時間が短縮されるだけでなく、人間と次世代のエージェント主導型ワークフローの双方が、より深く、より正確な分析を行えるシステムが実現します。
ロールアップ:集計の罠
ロールアップは、Prometheusなどのメトリクスシステムが抱える問題の1つである高カーディナリティへの現実的な対応策として登場しました。

高カーディナリティはシリーズの爆発を引き起こします。 出典:Observability Engineering: Achieving Production Excellence, Chapter 16. Efficient Data Storage
ここで「高カーディナリティ」という用語を簡単に定義しておきましょう。時系列データベースにおいて、カーディナリティとは
hostなどのラベルの組み合わせによって作成される一意な時系列の数を指します。HTTP GETリクエストのカウントのようなメトリクスには、host、service、endpoint、status_codeなどのラベルが付くことがあります。一意な組み合わせのそれぞれが、独自のシリーズになります。それらのディメンションが増加するにつれて、シリーズの数は極めて急速に増加する可能性があります。上の図にあるように、ユーザーIDなどの高カーディナリティなラベルは、単独でもシリーズの爆発を引き起こしかねません。
ここに、時系列モデルの限界が現れ始めます。Prometheusのようなシステムは、適度な数の長期間存続するシリーズであればうまく機能しますが、一意なシリーズが増えるごとに、メモリ上、ディスク上、およびクエリ実行時にオーバーヘッドが発生します。container_id や pod_id のような短命で高次元なラベルは、絶えず新しいシリーズを生成してチャーンを引き起こし、この問題を増幅させます。
そのプレッシャーが、ロールアップへと直結します。ユーザーは収集するディメンションの数を減らして死角を生み出すか、保存やクエリが容易な粗い形式にメトリクスを事前集計するかのいずれかを選択します。ベンダーはアクティブなシリーズ数に応じた課金を行うことでこの力学を強化し、データストアのアーキテクチャ上のコストを顧客に直接転嫁します。その結果、**チームは何を観測したいかよりも、**メトリクスのバックエンドがどこまで耐えられるかを考えることへ再び追い込まれます。

ロールアップは、詳細な多数のシリーズをより少なく粗いメトリクスに集約することで高カーディナリティデータを削減し、粒度の細かいコンテキストを犠牲にして効率を向上させます。
ロールアップはストレージとクエリ性能の両方に役立ち、上位レベルの集計に答えやすくするため、魅力的に見えます。しかし、そこには重大なコストが伴います。日常的な想定利用に基づいて、後からどんな質問をしたくなるかを事前に決めておかなければならないのです。インシデント発生時の最も重要な問いは、往々にして予測不能でアドホックであるにもかかわらずです。データがいったんロールアップされると、元の忠実性は失われます。集計が粗すぎたり、誤ったディメンションが除外されたりしていた場合、それらを復元する方法はありません。その結果、計装の不足ではなく、ストレージ層の限界を埋め合わせる必要性から、オブザーバビリティの新たな死角が生まれてしまいます。
この問題は、エージェントがワークフローの一部となることでさらに深刻化します。顧客IDごとにメトリクスをドリルダウンする機能など、重要なディメンションが欠落している場合、エージェントは完全に行き詰まります。問題を特定するために必要なシグナルがもはや存在しないためです。人間とは異なり、直感や代替手段に頼ることはできません。
そして、これこそがロールアップをヴィランたらしめている理由です。スマートな最適化として提示されることが多いものの、多くの場合、完全な忠実性を持つ大規模データに対処できないバックエンドのための回避策にすぎません。本来であれば、ユーザーはそもそもカーディナリティについて深く悩む必要がないのが理想です。リッチで高次元なテレメトリをそのまま保存し、ロールアップはシステムを利用可能にするための前提条件としてではなく、既知のクエリを真に高速化するのに役立つ場合にのみ、選択的に使用されるべきです。
より優れたモデルは実現可能です。ストレージエンジンが高カーディナリティデータを効率的に処理できれば、ロールアップは基盤となる必須要件ではなく、特定のワークフローを高速化するために選択的に使われる任意のツールになります。これは、妥協が減り、死角が減り、デバッグ、分析、そしてますます増えるエージェント主導の推論に必要な完全なコンテキストが保持されるシステムを意味します。
ヴィランが手を組むとき
個々に見ても、保持期間、サンプリング、ロールアップはそれぞれ全体像の一部を削ぎ落とします。これらが組み合わさると、データがサンプリングされ、集計され、最終的に破棄されることで損失が連鎖し、元のシグナルではなく大幅にフィルター処理されたバージョンだけが残ります。システムは単にデータを失っただけでなく、コンテキストを失ってしまったのです。
この重層的な損失は、脆いオブザーバビリティモデルを生み出します。事前に想定していなかった質問には答えられないことがよくあります。根本原因の分析は、各段階をたまたま生き残ったデータに制限され、当て推量になってしまいます。人間のオペレーターにとっては、調査が長期化し、直感やシステムへの理解に頼ることになります。解決までの時間は遅れますが、対処は可能です。
しかしエージェントにとっては、はるかに深刻です。頼るべき予備知識がないため、コンテキストの欠落は完全な停止を意味します。これらの制約が組み合わさることで生じる影響は、単なる可視性の低下にとどまらず、システムを理解し運用する能力そのものに対する根本的な限界となります。
オブザーバビリティのあるべき姿
それでは、保持期間、サンプリング、ロールアップは完全に姿を消すべきなのでしょうか? 必ずしもそうではありません。しかし、それらの役割は根本的に変わるべきです。システムの設計やデータ収集を縛る主要な制約ではなく、コストやアーキテクチャの限界から課されるデフォルトでもなく、意図的に適用される任意の最適化であるべきです。
ロールアップは、特定のクエリを高速化したり、一般的な集計への迅速なアクセスを提供したりする際には価値がありますが、生データに置き換わるものではなく、生データと共存すべきです。性能と忠実性の間の二者択一であってはなりません。全解像度のデータを常に保持し、ロールアップはシステムの基盤ではなく最適化レイヤーとして機能させるべきです。
サンプリングについても同様です。特定のイベントやログがあまり価値を付加しないことが分かっており、それらを削減できるケースはあるかもしれません。しかしこれはストレージや処理の制約による必然性ではなく、データ自体に基づいた情報に基づく判断であるべきです。デフォルトでは、システムは完全なトレースとイベントを取り込んで完全な忠実性を保ち、最も重要な局面で何も失われないようにすべきです。
保持期間も同じ原則に従います。長期保存がデフォルトであるべきであり、それが意思決定を支配しないほど低コストであるべきです。保持ポリシーは、ストレージをアグレッシブに制限する必要性からではなく、コンプライアンスや実際のビジネス要件に基づいて推進されるべきです。
列(カラム)でヴィランを打ち倒す
ヴィランを打ち倒すには、そもそも完全な忠実性を持つ高カーディナリティデータを経済的に処理できるストレージモデルが必要です。
ここで列指向ストレージが状況を一変させます。オブザーバビリティのワークロードは本質的に分析用途(アナリティカル)であり、構造化または半構造化イベントの大規模なストリームを取り込み、時間、サービス、ユーザー、コンテナ、リージョンを横断してフィルタリング、集計、相互関連付けを行う能力が求められます。

オブザーバビリティの本質は、チャート作成のための集計を必要とする分析データの問題です
列指向ストアは、まさにこのパターンのために作られています。各カラムが個別に保存されるため、クエリは必要なフィールドのみを読み取ります。これによりI/Oが大幅に削減され、大規模なデータセットに対する集計が、行指向や検索重視のシステムよりもはるかに高速になります。
列指向データベースは各カラムを個別に格納し、高い圧縮率を実現するためにそれらをソートします
列指向ストレージは、オブザーバビリティデータを極めて効率的に圧縮します。値の重複や規則的な並びパターンにより、従来の方式と比べてはるかに高い圧縮率が実現できます。これをオブジェクトストレージと組み合わせることで、長期保存が経済的に実現可能となります。データ保持を継続的な予算管理の課題として扱うのではなく、チームは生データをはるかに長期間保持できるようになります。その結果、システム側の都合でコンテキストの削除を強いられるのではなく、コンプライアンスやガバナンスの観点から有効期限ポリシーを運用できるようになります。
各カラムを個別に扱うことで、カーディナリティの高さによる影響を局所化できます
このアーキテクチャは、高カーディナリティへの対処にも役立ちます。一意のラベルの組み合わせごとに重いシリーズ単位の構造を作成・維持する時系列システムとは異なり、列指向ストアは各フィールドを個別に分離します。userId のような高カーディナリティのカラムは圧縮効率が落ちる場合がありますが、そのコストはカラム自体の中に閉じ込められ、データセットの他の部分には影響しません。これにより、ユーザー ID、リクエストパス、モデルバージョンといったフィールドが、避けるべき制約ではなく、単にクエリ可能な追加の次元となり、多次元データ全体にわたる効率的なフィルタリングや集計が可能になります。
列指向システムはカーディナリティを完全に排除するわけではなく、コストの一部をクエリ実行時にシフトさせています。
container_idのような高カーディナリティの次元で集計を行うと、数百万ものグループを作成する必要が生じ、ディスクスピリングなどの手法を用いても計算負荷が高くなります。しかし、これはオブザーバビリティにおいて一般的なアクセスパターンではありません。実際の運用では、数百万もの個別のシリーズを可視化したり集計したりする必要はめったにありません。大半のワークフローは、フィルタリングされたサブセット、トップ N の結果、あるいは集約されたビューに焦点を当てているため、このような最悪のケースのクエリは日常的なものではなく例外にとどまります。
この仕組みは、ロールアップやサンプリングの役割も変えます。既知のアクセスパターンを高速化する手段としてロールアップには依然として価値があり、真に価値の低いデータに対するサンプリングにも意味があります。しかし、どちらもシステムの根幹である必要はありません。未加工の高精度データを保持し続けながら、ロールアップやサンプリングは目的を絞った最適化手段としてのみ利用できます。これは、システムを手頃なコストで使える状態にするためだけにこれらの手法が必須となっている、現在のオブザーバビリティスタックとは根本的に異なるモデルです。

ClickHouse が最も適している理由
これらの課題に対処できる列指向データベースは ClickHouse だけではありません。Apache Pinot や Apache Druid といったシステムもアーキテクチャ上の利点の多くを共有しており、いずれも大規模な分析ワークロードの支柱として実績を上げています。しかし、オブザーバビリティの領域においては、リアルタイム性を重視している点で ClickHouse が際立っています。
スパースプライマリインデックスにより、オブザーバビリティのアクセスパターンに沿った効率的なフィルタリングが可能になり、並列実行エンジンによって大規模なデータセットにわたるクエリをスケールできます。スキッピングインデックスと全文検索のサポートがこれらの機能をさらに拡張し、探索的なワークフローを実現します。



