以下の内容はhttps://syu-m-5151.hatenablog.com/entry/2024/05/10/121047より取得しました。


盲目的に始めないためのオブザーバビリティ実践ガイド - Cloud Observability in Actionの読書感想文

誕生日エントリー兼読書感想文です。

www.amazon.jp

はじめに

クラウドコンピューティングの普及とマイクロサービスアーキテクチャの台頭により、システムの複雑性が増大しています。そのような中で、オブザーバビリティ(可観測性)の重要性が高まっています。本書「Cloud Observability in Action」は、クラウドネイティブなシステムにおけるオブザーバビリティの概念と実践方法を包括的に解説した一冊です。

learning.oreilly.com

オブザーバビリティとは、システムの外部から観測できる情報に基づいて、内部の状態を推論し理解する能力のことを指します。本書では、オブザーバビリティを投資対効果の観点から捉え、データの生成から収集、処理、可視化に至るまでのプロセス全体を俯瞰します。OpenTelemetryやPrometheus、Grafana、Loki、Jaegerなどのオープンソースツールを活用し、誰でも実践的な知見を時間以外の費用をかけずに得られるよう工夫されています。

著者自身の豊富な経験に基づくベストプラクティスが随所に盛り込まれているのと参考になるURLをめちゃくちゃに共有してくれております、開発者やSREだけでなく、あらゆるクラウドネイティブ関係者にとって有益な内容となっています。単なるツールの使い方の解説にとどまらず、オブザーバビリティを組織文化として定着させるためのヒントも提供されています。

本書を通して、オブザーバビリティの本質的な価値とその実現に向けた道筋を学ぶことができるでしょう。得られた知見をどのように活用するかは読者次第ですが、システムと組織の継続的な進化を支える原動力として、オブザーバビリティをバズワードとして盲目的に始めずに目を見開いてオブザーバビリティを捉える視座を得られるはずです。

本稿では、各章の要点を丁寧に読み解きながら、私なりの学びと気づきをシェアしていきます。皆様にとっても、オブザーバビリティへの理解を深め、その実践への一歩を踏み出すきっかけとなれば幸いです。

この本の構成

本書「Cloud Observability in Action」では、クラウドネイティブなシステムにおけるオブザーバビリティの概念と実践方法が包括的に解説されています。第1章ではエンドツーエンドの例が示され、ソースからエージェント、宛先までの用語が定義されているとともに、可観測性の文脈におけるユースケース、役割、課題について説明されています。第2章ではログ、メトリック、トレースといったさまざまなテレメトリ信号タイプと、それらの使い分け方、収集方法、コストと利点について述べられています。第3章ではテレメトリが生成される信号ソースについて、種類や選択方法、インストルメントコードの扱い方が解説されています。第4章ではOpenTelemetryを中心に、ログルーターからのさまざまなテレメトリエージェントが紹介されています。第5章では、Prometheusなどの時系列データベースやClickHouseなどの列指向データストアを例に、テレメトリ信号のバックエンド宛先について学ぶことができます。第6章では可観測性フロントエンドについて、純粋なフロントエンドとオールインワンの選択方法が説明されています。第7章ではクラウドオペレーションの側面として、異常検知や過去の失敗からの学習、アラート、使用状況、コスト追跡について述べられています。第8章では分散トレースマイクロサービスの理解・トラブルシューティングへの活用方法が、第9章では継続的なプロファイリング開発者の生産性ツールを中心に開発者の可観測性について詳解されています。第10章ではサービスレベル目標の設定と消費者満足度の問題への対処方法が、第11章では単一の信号タイプでは解決できない課題信号相関によるアプローチが取り上げられています。付録ではOpenTelemetry、Prometheus、Jaeger、Grafanaを使用した完全なエンドツーエンドの例が提供されています

Github Repository

github.com

目次

1 End-to-end observability

本章「1 End-to-end observability」は、クラウドネイティブシステムにおけるオブザーバビリティ(観測可能性)の概念と重要性を詳しく述べています。Observability Engineeringについては読書感想文を書いているので合わせて読んでみてください。

syu-m-5151.hatenablog.com

オブザーバビリティの定義と目的

オブザーバビリティとは、システムから取得できる信号に基づいて、そのシステムの内部状態を継続的に把握し、インサイトを得ることで、システムに影響を与える能力のことです。オブザーバビリティは単に監視(モニタリング)ツールを導入するだけでは不十分です。システムの外側から収集した情報を、そのままダッシュボードなどの可視化ツールに表示するのではなく、行動可能な洞察(アクショナブルなインサイト)を生み出すことが本質的な目的となります。つまり、観測対象のシステムの外側から情報を収集し、分析を行い、それらから具体的なアクション(行動)を引き出すプロセス全体を指します。

クラウドネイティブの分散システムでは、システムを構成するコンポーネントが多数に分かれ、ネットワーク経由で相互に通信を行うため、従来のモノリシックなシステムに比べてシステム全体の状態把握が困難になります。このため、オブザーバビリティが非常に重要な役割を果たします。状況を"飛ばず"に把握し、適切な制御を行えるようになることで、以下のようなユースケースに対応できるようになります。

  • コード変更の影響の把握: 新機能の追加やバグ修正によるシステム全体へのインパクト(パフォーマンスへの影響、副作用の発生、リソース使用量の変化など)をモニタリングし、必要な対処を行える。
  • サードパーティ依存関係の監視: 自社のシステムが依存する外部API(決済サービス、ロケーションサービスなど)の可用性、健全性、パフォーマンスを把握し、問題が発生した際の対応を行える。
  • ユーザー体験(UX)の測定: アプリケーションやサービスの応答性、信頼性をユーザーの視点から継続的に測定し、UXの維持・改善につなげられる。
  • システムの健全性とパフォーマンスの追跡: システム全体のアップタイム、応答時間分布、障害の影響範囲(有償ユーザへの影響、無償ユーザへの影響、重要取引先への影響など)を継続的に監視できる。
  • 障害の影響範囲(ブラストレディウス)の特定: 障害発生時に、その障害がシステム全体にどの程度影響を与えているのか(ブラストレディウス)を特定できる。さらに根本原因を絞り込み、Kubernetesコントロールプレーン、データプレーン、VMなどの障害発生場所を特定できる。
  • サービスの最適化: サービスのパフォーマンス、リソース使用量、コスト、応答時間などを定量的に測定し、ボトルネックの特定や最適化を行える。
  • 開発者生産性の向上: アプリケーションコードのプロファイリングやログ解析などを通じて、パフォーマンスの問題箇所や冗長なコードの特定が可能になり、適切にコード改善を行うことで開発者の生産性を高められる。
  • アクセスとコンプライアンスの監査: 様々なサービスやデータへのアクセス権限を自動的に追跡し、不正アクセスを検知できる。さらに監査証跡を残すことで、規制当局からの検査に備えられる。

オブザーバビリティの目的は、上記のようなユースケースに対して、システムの状況をデータドリブンに把握し、適切な対処を迅速に行えるよう支援することにあります。単なるモニタリングツールの導入ではなく、収集した様々な種類の情報から総合的かつ根本的な理解を得て、それに基づいてアクションを起こすことが重要となります。

オブザーバビリティのコンポーネント

オブザーバビリティを実現するためには、さまざまなコンポーネントが関係してきます。これらのコンポーネント有機的に連携し、それぞれの役割を果たすことで、オブザーバビリティが実現されます。主なコンポーネントは以下の通りです。

  • システム(System under observation): 観測対象となるクラウドネイティブアプリケーションやプラットフォーム全体
  • 信号(Signals): システムから外部に出力される、以下の3種類の情報
    • ログ: アプリケーションの動作履歴をプレーンテキストで記録した情報。エラーメッセージや例外の詳細情報などが含まれる。
    • メトリクス: アプリケーションの運用状況を数値で表した指標。CPU使用率、メモリ使用量、リクエスト処理時間、エラー率などのデータ。
    • トレース: 個々のリクエストがシステムの各コンポーネントを通過する際の、処理フローと時間情報の記録。サービス間の呼び出し関係と、それぞれの処理にかかった時間を特定できる。
  • ソース(Sources): アプリケーションコード、データベース、メッセージキュー、クラウドプロバイダのマネージドサービスなど、信号を生成するコンポーネント
  • エージェント(Agents): 信号を収集し、前処理やルーティングを行う役割。例えばFluentBitはログのエージェント、OpenTelemetry Collectorはメトリクス/トレースのエージェントとして機能する。
  • 宛先(Destinations): ダッシュボード、アラートシステム、長期ストレージ、分析ツールなど、信号を消費し可視化/分析を行う場所。
  • Telemetry: 信号をソースから収集し、エージェントを経由して前処理や分割を行った後、宛先に送信するプロセス全体のこと。

fluentbit.io

以下の図はこれらのコンポーネント間の関係を視覚化しています。

Figure 1.1 Observability overview より引用

オブザーバビリティは一方通行のプロセスではなく、フィードバックループを形成しています。例えば、人間がダッシュボードから情報を得て再起動のアクションを取ったり、アプリケーションがメトリクスに基づいて自動スケーリングを行ったりと、収集した信号に基づいてシステムに影響を与えることになります。

様々な信号を組み合わせて分析することで、より深いシステムの理解につながり、適切なアクションを起こすことができます。単一の信号からは得られない総合的なインサイトを、信号間の相関によって引き出すことが可能になります。

具体例としてのマイクロサービスアプリ "Sock Shop"

本章では、Weaveworksが公開しているマイクロサービスアプリケーション"Sock Shop"を具体例に、オブザーバビリティの実践を説明しています。Sock Shopは、Spring Boot、Go kit、Node.jsなど複数の言語・フレームワークを用いて構築された、オンラインストアのデモアプリです。

kakakakakku.hatenablog.com

Docker コンテナイメージに格納されており、Kubernetes などのコンテナオーケストレーターで実行できます。

Figure 1.2 The example microservices app we use for observability exploration より引用

本章では、このアプリを実際にKubernetes上で起動し、それぞれのコンポーネントが出力するログやメトリクスの具体例が紹介されています。

  • ログの例(ソース: ordersサービス)

    • Javaで実装されたSpring Bootベースのマイクロサービスから出力されるログが示されています。
    • ログを有効に活用するには、FluentBitなどのエージェントを使ってOpenSearchCloudWatch などの宛先にルーティングする必要があります。
  • メトリクスの例(ソース: frontendサービス)

    • フロントエンドのNode.jsサービスから出力されるメトリクスがPrometheus形式で示されています。
    • メトリクスを収集するには、Prometheus自身かOpenTelemetry Collectorなどのエージェントが必要です。長期保持のためにはCortexThanosなどの宛先を用います。

このようにSock Shopは、実際にクラウドネイティブなマイクロサービスアプリケーションが出力する様々な信号を確認できる題材として使われています。

github.com

さらに、トレースについても簡単に触れられており、リクエストの実行フローの可視化や、各サービスの処理時間、ステータスなどを確認できるとされています。オブザーバビリティを実現するには、JaegerZipkinAWS X-Rayなどのトレーシングツールの導入が必要になります。

クラウドネイティブの課題とその解決

クラウドネイティブなシステムには、従来のモノリシック構成のシステムとは異なる以下のような課題があり、オブザーバビリティがその解決を助けます。

  1. 分散システム: コンポーネントが分散し、ネットワーク経由で疎結合に結ばれているため、システム全体を把握することが難しい。モノリシックな構成に比べ、システムの"見えづらさ"が高まる。

  2. コンポーネントの場所の重要性: リクエストを処理する各コンポーネントの実行場所(ノード、アベイラビリティーゾーン、リージョンなど)が、パフォーマンスやレイテンシーに大きく影響する。場所情報の重要性が増す。

  3. コンポーネントの頻繁な入れ替えと揮発性: マイクロサービスのコンポーネントKubernetesのPod、Lambda関数バージョンの入れ替えが非常に頻繁に行われ、さらにIPアドレスも動的に変化するなど、システム構成の揮発性が高まる。

これらの課題に対して、オブザーバビリティは以下のように貢献します。

  • 全ての関連する信号を自動収集し、アクションに結びつける手段を与える システムを"飛ばず"に把握し、状況に応じた適切な制御を行えるようになる。ログ、メトリクス、トレースなど複数の信号を収集・分析することで、システムへの深い理解を得られる。

  • 信号間の相関により、単一の信号からは得られない総合的な把握が可能になる 異なる種類の信号を組み合わせることで、より包括的な視点が得られる。例えばメトリクスの異常からトレースにドリルダウンし、さらにログを確認することで、障害の原因を徹底的に追究できる。

  • オープンスタンダードとオープンソースの採用によりポータビリティが確保され、特定のベンダーやプラットフォームへのロックインを回避できる 例えば、OpenTelemetryを用いてアプリケーションに計装を行えば、後からデータ収集の宛先を柔軟に変更可能になる。異なるクラウドプロバイダ間や、オンプレとクラウドをまたいでも同じ方式が適用できる。

一方で、オブザーバビリティの導入と運用には以下のようなコストがかかります。

  • 計装の開発者の労力 アプリケーションコードにロギングやメトリクス、トレーシングの計装を行う必要があり、継続的な労力を要する。

  • 信号(ログなど)の保持コスト 長期保持が必要なログなどの信号データを保存する、ストレージ費用が発生する。

  • エージェントや計装自体の計算リソースオーバーヘッド 信号収集やルーティングを行うエージェントプロセス自体に、一定のCPU/メモリリソースが必要になる。

  • ネットワーク使用量に応じたコスト 収集された信号のデータ転送に伴うネットワークトラフィックの費用も考慮しなければならない。

これらのコストに見合うだけの投資対効果があるかどうかを、個々の状況において適切に判断する必要があります。効果の測定として、オブザーバビリティツールの導入前後での障害からの平均復旧時間(MTTR)の改善を確認するのが一般的です。その他、開発者のストレス軽減やワークライフバランスの向上など、定性的な効果も期待できます。Return on Investment Driven Observability では、この投資対効果について詳しく議論されています。

本書では、教育的な観点から、ログ、メトリクス、トレースといった概念の境界線に沿って解説を進められています。しかし、実際の現場では、これらの概念が混在していることが多いです。プロジェクトやプロダクトが成熟するにつれ、スコープが広がり、概念の切り分けが難しくなるのです。

例えば、ログデータの中にメトリクスとして活用できる情報が含まれていたり、トレースデータからログ的な情報を抽出したりすることがあります。また、これらの概念を組み合わせて、より高度な分析や監視を行うこともあるでしょう。

本書を活用する際は、このような教育的な側面と実践的な側面のバランスを意識していただければと思いました。概念の境界線を理解することは重要ですが、同時に現場での柔軟な適用も必要不可欠です。本書で得た知識を基礎として、実際のプロジェクトやプロダクトの文脈に合わせて応用していくことが求められます。

オブザーバビリティはクラウドネイティブ時代の必須プラクティス

オブザーバビリティは、クラウドネイティブな分散システムを効果的に運用する上で不可欠なプラクティスと言えます。システムから出力される様々な信号(ログ、メトリクス、トレース)を収集し、相関させることで、システム全体の状況を多角的に把握し、適切な対処を迅速に行えるようになります。

しかしながら、オブザーバビリティの導入と運用には一定のコストがかかります。計装の労力、データ保持コスト、リソースオーバーヘッド、ネットワークトラフィックなどです。これらのコストに見合うだけの効果(MTTRの改善、開発者の生産性向上など)があるかを、個別のユースケースにおいて検討する必要があります。

オープンスタンダードとオープンソースのツールを適切に選択・活用することで、特定のベンダーにロックインされるリスクを回避でき、ポータビリティを確保できます。例えばOpenTelemetryはその好例です。

オブザーバビリティは、単なるモニタリングツールの導入ではなく、システムへの深い理解を得て、適切なアクションにつなげるための実践的な取り組みです。クラウドネイティブ時代において、ソフトウェアエンジニアやSREが理解しておくべき重要な概念であり、実務で実践していく必要があります。

syu-m-5151.hatenablog.com

2 Signal types

オブザーバビリティの3本柱

クラウドネイティブな分散システムを効率的に監視・運用するためには、ログ、メトリクス、トレースという3つの主要な信号タイプを適切に組み合わせたオブザーバビリティが不可欠です。本章では、それぞれの信号タイプについて詳しく解説されており、その特徴、計装の方法、コスト、利点、オブザーバビリティへの貢献などが丁寧に説明されています。さらに、実際のサンプルアプリケーションを用いた具体例を通して、各信号タイプの収集・可視化方法が示されており、監視システムの構築に役立つ実践的な知見が提供されています。

ログ: 人間が読み解くテキストベースの出力

ログはアプリケーションの動作履歴やエラー情報などをテキストで記録したものです。開発者がバグの特定を行ったり、SREが障害の原因を追跡する際に、ログの存在は非常に重要です。近年では構造化データ形式(JSONフォーマットなど)を用いたログが主流となり、コンテキスト情報(ラベル)を付与することで検索性や相関性が向上しています。

本章ではGoの logrus ライブラリを使って、サンプルアプリケーションに構造化ログの出力機能を追加する例が示されています。

github.com

出力されたログは FluentBit エージェントによって収集され、 Loki へ転送されます。GrafanaでLokiのデータソースを設定してを、Lokiを使ってログを可視化・探索することができます。

grafana.com

ログには計装のための開発コストや、大量のログデータを保持するためのストレージコストがかかります。しかし、大半の開発者に理解されており、プログラミング言語の標準ライブラリでサポートされているのがログの大きな利点です。保持コストを抑えるには、データの温度(アクセス頻度)に応じて適切な保持期間を設定することが重要です。

  • ホットデータ: 直近のログであり、即座にアクセス可能で高速な検索性が求められる(数日〜数週間程度)
  • ウォームデータ: すぐには必要ないが将来的に参照する可能性のあるログ(数ヶ月〜数年程度)
  • コールドデータ: アクティブには使わないが規制上保持が義務付けられているログ(長期保持用のオブジェクトストレージなどに格納)

ログは人間が読み解くことを前提とした信号タイプですが、近年では Promtail のようなエージェントによる構造化ログの収集や、Lokiのようなデータストアでのラベルベース検索が可能になってきました。一方で完全にテキスト検索に頼らず、トレースへの移行を推奨する意見 (https://arxiv.org/abs/2303.13402) もあり、ケースバイケースでの適切な選択が重要になってくるでしょう。

grafana.com

メトリクス: 自動化された監視・分析に役立つ数値指標

メトリクスは定期的にサンプリングされる数値の指標であり、システムやアプリケーションの状態を数値で表します。CPU使用率、メモリ使用量、リクエスト処理時間、エラー率など、ほとんどの監視対象項目はメトリクスとして表現できます。メトリクスの大きな利点は、数値であるがゆえに自動化された監視・分析が可能になることです。

本章ではGo製アプリケーションにPrometheus Client Libraryを使ってメトリクスの出力機能を追加し、エラー率のメトリクスを計算するコードが紹介されています。

github.com

このアプリから出力されるメトリクスは Prometheus エージェントによって収集され、GrafanaでPrometheusのデータソースを設定して、Prometheusを使ってメトリクスを可視化・分析します。

grafana.com

メトリクスの計装コストは自動化の恩恵を受けられるケースが多く、比較的低コストです。プログラミング言語の標準ライブラリやミドルウェアによる自動計装の機能が増えてきており、手動での計装コストも限定的です。

一方で、指標の種類が増えるとカーディナリティ爆発の問題が発生する可能性があります。例えばユーザーIDをメトリクスのラベルに含めると、大量のユーザーがいる場合に膨大な種類の指標が生成されてしまいます。このようなカーディナリティの高いメトリクスを時系列データベースで保持・検索しようとすると、パフォーマンスが極端に低下する恐れがあります。そのため、収集するメトリクスの種類を限定する、オートプルーニングを行うなど、適切なカーディナリティ管理が重要になります。

また、大量のメトリクスデータを長期保持する際には、データ圧縮や集約が必須です。Cortex や Thanos のようなシステムが、スケーラブルなメトリクス長期保存のためのベストプラクティスを提供しています。収集するメトリクスの種類、保持期間、データ形式などを検討する必要があります。

メトリクスの主な利用シーンとしては以下が挙げられます。

  • ダッシュボード表示: CPU使用率や処理レイテンシーなどをリアルタイムにモニタリングする
  • アラート発報: メトリクスの閾値超過を検知し、自動的にアラートを通知する
  • 自動スケーリング: リクエスト数などのメトリクスに基づいてリソースを動的に拡張/縮小する
  • SLI/SLO監視: サービスレベルインディケータ(SLI)としてのメトリクスを使い、合意された目標水準(SLO)の達成状況をモニタリングする
  • アノマリー検知: 機械学習で正常値の範囲を予測し、異常値を検出する

メトリクスはオブザーバビリティを実現する上で中心的な役割を担う信号タイプです。数値指標であるがゆえに自動化が容易であり、リアルタイムな監視だけでなく長期的なトレンド分析や容量計画にも活用できます。

トレース: マイクロサービスの処理フローを可視化する

トレースは分散システムにおけるリクエストの処理フローを可視化する手段です。マイクロサービスアーキテクチャを採用する上で、そのコンポーネント間の呼び出し関係を把握することは非常に重要です。トレースはリクエストに固有のIDを割り当て、各サービスでの処理時間とステータスを記録することで、そのリクエストの実行フローを可視化します。

本章では OpenTelemetry Go ライブラリ を使って、サンプルアプリケーションにトレーシングの機能を追加する例が示されています。

github.com

生成されたトレースは Jaeger によって収集・可視化されており、GrafanaでJaegerのデータソースを設定して、JaegerのTrace Viewを見ることができます。

grafana.com

トレースの計装コストは比較的高めですが、マイクロサービス間の呼び出し関係の可視化やボトルネックの特定に役立つため、分散システムを運用する上では非常に重要です。一方で、大量のトレースデータを保持するためのストレージコストや、リクエストへのコンテキスト伝搬によるパフォーマンスオーバーヘッドにも注意が必要です。

トレースデータを保存するためのストレージとしては以下のようなアプローチが一般的です。

  • 専用のデータストア (ClickHouseなど)
  • NoSQLデータベースを活用 (Cassandra、HBase、Elasticsearchなど)
  • オブジェクトストレージとクエリエンジン (Grafana Tempoなど)

各アプローチにはトレードオフがあり、データ量、検索パフォーマンス、コストなどの要件に合わせて適切なものを選択する必要があります。

トレースの主な利用シーンは以下のようになります。

このようにトレースは、マイクロサービスアーキテクチャにおける処理フローの可視化を実現する上で非常に重要な役割を担っています。SREやオンコール担当者がインシデント発生時の初動対応を行う際に活用されることも多くなってきています。

収集する信号の選定とコスト管理

本章の終盤では、オブザーバビリティを実現するために収集すべき信号の選定と、コストコトロールに関する考え方が説明されています。アクションにつながるインサイトを生むか、適切な保持期間が設定できるか、ROI(投資対効果)を考慮する必要があります。

具体的な指針は以下の通りです。

  • 収集する信号がアクションにつながるインサイトを生み出すか? 単にノイズになるだけの信号は避けるべき
  • 信号の保持期間をどう設定するか? タスクや業界の規制に合わせて適切に決める
  • メトリクスの正常な値範囲(ベースライン)を設定し、異常検知に活用する
  • 信号の過剰収集は避け、ROIを意識する 保持するメリットが不明確な信号はコストの無駄
  • 収集する全ての信号で一貫したラベル付けを行う 相関性の確保に役立つ

このように、オブザーバビリティを実現するためには信号の選別と、収集・保持に伴うコスト管理が重要になってきます。収集しすぎても意味がありませんし、重要な情報が欠落していても目的が果たせません。用途に合わせて 適切な種類の信号を適切な量だけ収集する という観点が欠かせません。

オブザーバビリティを支える3本柱の理解と適切な運用が肝心

ログ、メトリクス、トレースは、クラウドネイティブな分散システムのオブザーバビリティを実現する上で、それぞれ異なる役割を担う重要な3つの信号タイプです。

  • ログはテキストベースの出力であり、人間が読み解いて状況を把握したりデバッグを行う際に役立ちます。
  • メトリクスは数値の指標であり、自動化された監視・分析や、アラート発報、自動スケーリングなどに適しています。
  • トレースはマイクロサービス間の処理フローを可視化する手段であり、分散システムを運用する上で欠かせません。

各信号タイプにはそれぞれ長所と短所があり、3つの信号を組み合わせて収集・活用することで、システム全体の状況を多角的に把握できるようになります。しかし、それぞれに計装コストや保持コスト、リソース消費などのオーバーヘッドがあるため、収集する信号とその収集方法については、ユースケースごとのコストとROIを考慮する必要があります。

本章ではサンプルアプリを使った具体例を交えながら、各信号タイプの特徴や計装の方法、Fluentbit、Promtail、Prometheusなどの収集エージェントの利用方法、GrafanaやLoki、Jaegerなどの可視化ツールの活用例が解説されています。これらの知見は監視システムの構築や運用を検討する上で参考になるはずです。

ソフトウェアエンジニアやSREは、3つの信号タイプの特性を理解した上で、システムの要件に合わせて最適な組み合わせと収集方法を選択し、効率的なオブザーバビリティの実現を目指す必要があります。 信号の過剰収集に陥らず、ラベル付けの統一や信号間の相関性の確保など、コストを抑えながら有用な情報を得られる適切な運用が何より重要になります。

オブザーバビリティの実現には、これら3つの主要な信号タイプを適切に組み合わせた上で、効果的な収集と活用を行うことが不可欠です。各信号タイプには一長一短があり、単独では十分なオブザーバビリティを得ることはできません。

ログは人間が読み解くためのテキスト出力ですが、構造化の進展により自動分析の機会も増えてきました。しかしマイクロサービスアーキテクチャにおいては、処理フローの可視化という点でトレースに一部の役割が移行しつつあります。用途に応じてログとトレースを使い分ける必要があります。

一方、メトリクスは数値指標のため自動化が容易であり、リアルタイムの監視だけでなく長期的な分析や容量計画にも活用できます。ただし、メトリクスの種類が増えるとカーディナリティ爆発のリスクがあり、適切なカーディナリティ管理が欠かせません。また、大量データの長期保持にはデータ圧縮や集約が必須になります。

トレースはマイクロサービス間の処理フローを可視化するため、分散システムの運用では欠かせません。一方で、計装コストが高く、大量データの保持やコンテキスト伝搬によるパフォーマンスオーバーヘッドにも留意が必要です。ストレージの選択では、データ量やパフォーマンス要件、コストを考慮する必要があります。

このように、オブザーバビリティを実現するには、3つの信号タイプそれぞれの長所と短所を理解した上で、システムの要件に合わせて最適な組み合わせと収集方法を選択することが肝心です。信号の過剰収集は避け、ラベル付けの統一やコスト管理、信号間の相関性の確保など、効率的な運用が何より重要になります。

収集する信号については、以下の点を考慮する必要があるとしています。

  • アクションにつながるインサイトを生み出すか?
  • 適切な保持期間が設定できるか?
  • メトリクスの正常値範囲(ベースライン)は設定できるか?
  • ROI(投資対効果)を意識した収集が可能か?
  • 信号間で一貫したラベル付けができるか?

ソフトウェアエンジニアやSREは、このような点に留意しながら、効率的なオブザーバビリティの実現に努める必要があります。本章で示された具体例は、実際の監視システム構築の参考になるはずです。コストを抑えつつ、有用な情報を効果的に収集・活用できる環境を整備することが求められます。

3 Sources

クラウドネイティブシステムにおける多様な信号源の理解と活用

本章「3 Sources」では、クラウドネイティブシステムにおけるオブザーバビリティの実現に欠かせない、様々な信号源(ソース)について詳しく解説されています。コンピューティング、ストレージ、ネットワーク、そして自身のコードに至るまで、各ソースからの信号取得の重要性と注意点が丁寧に説明されており、オブザーバビリティの実践に向けた実用的な知見が提供されています。

Figure 3.1 A spectrum of compute, infrastructure, and application level より引用

この図はコンピューティングリソースをインフラストラクチャレベル(VM、コンテナなど)とアプリケーションレベル(マイクロサービスやモノリシックアプリなど)に分けて示しています。インフラストラクチャレベルの監視は主に運用者が関与し、アプリケーションレベルの監視は開発者が関与する、といった役割分担が一般的です。しかしながら実際のプロダクション環境では、これら2つのレベルが複合的に組み合わさっていることが多いため、様々なソースからの信号を包括的に収集・相関させる必要があります。

Figure 3.2 Signal sources in Kubernetes より引用

この図はKubernetesにおけるコントロールプレーンとデータプレーンから出力される様々な信号源を示しています。コントロールプレーンのコンポーネントであれば、主にログとメトリクス、一部でトレースが出力されます。一方のデータプレーンではアプリケーションコンポーネントからログ、メトリクス、トレースが出力されることが一般的です。単一のプロダクト内に多種多様な信号源が存在するため、ホリスティックなオブザーバビリティ対応が求められます。

以上の通り、クラウドネイティブな分散システムにはさまざまな種類の信号源が存在し、それぞれ特有の注意点があります。ソフトウェアエンジニアやSREは、これら多様な信号源の存在を理解した上で、用途に応じて適切な手段を選択し、効率的なオブザーバビリティの実現を目指す必要があります。単一の手法に固執するのではなく、必要に応じて収集方法を使い分けながら、ホリスティックな可視化を実現することが肝心です。そのためには本章で解説された信号源に関する深い理解が不可欠だと思います。

コンピューティング関連のソースの詳細

VMについては、オペレーティングシステムレベルの情報が参照できる点が大きな利点です。本書ではJVMを例に挙げ、JVMはログ、ヒープメモリ使用量、スレッド数など様々なメトリクスを出力することが説明されています。実際のJVM監視ツールとしてはSematextの提供するガイドが紹介されています。JVMは豊富な信号源となり、開発者はこれらのメトリクスを活用してパフォーマンスチューニングやデバッグを行えます。

コンテナの場合、コンテナランタイム自体と、コンテナ内で実行されるアプリケーションの両方から情報が出力されます。コンテナランタイムの例としてDockerデーモンが挙げられ、docker logsコマンドでコンテナログを参照できます。また、Dockerコンテナ内のアプリケーションも標準的にログを標準出力に出力するよう12ファクターアプリの設計思想に従います。コンテナランタイムのメトリクス収集には、cAdvisorTelegrafのDockerプラグインが活用できます。開発者はアプリケーションログを参照し、運用者はコンテナランタイムのメトリクスを監視することで、それぞれの観点からコンテナの状況を把握できます。

Kubernetesでは多岐にわたるコンポーネントから様々なシグナルが出力されるため、包括的な理解が重要になります。コントロールプレーンのコンポーネント(APIサーバー、etcd、kubeletなど)からはログ、メトリクス、監査ログ、トレース(APIサーバーのみ)が出力されます。一方のデータプレーンではアプリケーションからのログ、メトリクス、トレースが主な情報源となります。Figure 3.2がKubernetesにおける様々な信号源を示しています。

本文中でも触れられているように、Kubernetesではログの取り扱いが分散されており、収集の仕組みを整備する必要があります。アプリケーションログはkubectl logsで一時的に参照できますが、本番環境では永続化が必須です。Fluentbit、Fluentdなどのエージェントを使ってクラウドプロバイダーのログ基盤に転送するのが一般的なパターンです。

Kubernetesでは、ログに加えメトリクスとトレースにも注目が集まっています。メトリクスはPrometheus形式で出力されており、kubectl get --raw /metricsで参照できます。一方、トレースはOpenTelemetryを使ってAPIサーバーの動作を追跡できるよう、コミュニティによってサポートが進められています。

ストレージ関連のソースの詳細

RDBMSでは、パフォーマンスモニタリングにおいてクエリプランナーの動作を理解することが肝心です。PostgreSQLの場合はEXPLAINでプランを確認できますし、各種モニタリングツールでも詳細情報にアクセスできます。例えばpgMonitorなら待機リソースのボトルネックやクエリの履歴なども確認できます。ベンダー製品でも同様の情報を得られます。例えばAWS Redshiftでは、CPU、メモリ、ストレージの使用量など基本的なメトリクスに加え、明示的にスロークエリIDを確認できます。

RDBMSではパフォーマンスの観点からクエリプランナーの動作を細かく監視することが重要ですが、NoSQLデータストアではアプローチが異なります。NoSQLデータストアでは、アクセスパターンやストレージレイアウトが重要な監視対象となります。例えば、キャッシュとしても使われるRedisであれば、メモリ使用量のメトリクスが有用です。一方でMongoDB(ドキュメントストア)では、ディスクIOパフォーマンスのメトリクスに注目する必要があります。本書ではElasticsearch(検索エンジン)の事例も紹介されており、背景にあるLuceneのインデックシングプロセスを監視する重要性が説明されています。このようにNoSQLではアクセスパターンに合わせて監視対象を適切に選定することが求められます。

RDBMSやNoSQLデータストアのメトリクスを収集する手段としては、PostgreSQL Server ExporterpgMonitorクラウドベンダー製品の活用が挙げられています。自社運用の場合はPrometheusと組み合わせるといった方法もあり、より詳細なカスタマイズが可能です。一方でクラウドベンダー製品を利用すれば、運用の手間を大幅に削減できます。RDBMSとNoSQLでは監視の着眼点が異なるため、目的に合わせて適切な手段を選ぶ必要があります。

ネットワーク関連のソースの詳細

ネットワークデバイスからは大量のログが出力されます。そのためノイズを除去し、価値のある情報だけを抽出することが課題となります。例えばロードバランサーであれば、リクエストの送信元IPやパスに基づいてフィルタリングすると効率的なモニタリングが行えます。AWS ALBの場合は、リクエスト量、アクティブコネクション数、HTTPステータスコードなどのメトリクスが出力されます。ALB自体の稼働状況だけでなく、バックエンドへのトラフィック情報なども確認できるため、アプリケーションの挙動を多角的に監視することが可能です。より高度な運用では、リクエストコンテンツやレスポンスページのレンダリング時間などもモニタリング対象になりうるでしょう。

VPNVPCから得られる情報では、セキュリティモニタリングが主な用途となります。例えばVPC FlowLogsからSSHやRDPアクセスをモニターすれば、不正アクセスの検知に活用できます。そのほか送受信トラフィックのパターン分析を行えば、DDoS攻撃の検知なども可能になります。VPCフローログは全てのIPトラフィックを記録するため、ネットワークの可視化に役立つと同時に、ログ量が膨大になる点にも注意が必要です。用途に応じて適切にフィルタリングする必要があります。

ネットワーク関連ソースは大量のノイジーなデータが出力されるため、フィルタリングやラベル付けが重要になります。ALBの場合はデプロイ単位や環境単位でリクエストにラベルを付与することで、効率的なモニタリングが可能となります。また、Kubernetesなどのオーケストレーターを利用する場合は、Ingressリソースなどの抽象化されたネットワーク構成から出力されるシグナルをモニターする必要があります。

自身のコード関連の詳細

オープンソースOpenTelemetryは、ログ、メトリクス、トレースの各種信号をベンダーロックインなしに管理できる魅力的なスタンダードです。ただし既存のコードに計装を行うコストがあり、コストとベネフィットのトレードオフを考慮する必要があります。将来の再計装のコストを避けたいのであれば、OpenTelemetryを中心におき、自動計装を最大限活用するのがよいでしょう。

一方でCI/CDパイプライン自体も重要な信号源となります。ここからデプロイ進捗や所要時間、テスト結果などのメトリクスが得られます。新しいビルドが発生する度にこれらのメトリクスを監視することで、パフォーマンスの変化やボトルネックを事前に検知できます。将来的にはDigmaSprkl.devといった専用ツールを使った開発者向けオブザーバビリティも重要になってくるでしょう。特にIDE上でコード変更の影響を可視化したり、プロファイリングデータからボトルネックを特定する機能が期待されています。

信号の収集対象として最後に挙げられているのがプロキシソースです。ここでは監視対象外だが監視が必要なコンポーネントに対し、プロキシサーバーを介することで情報収集を実現する方法が説明されています。Prometheusの場合はKafkaやIoTデバイスなど非対応コンポーネントからExporterを使ってメトリクスを収集できます。またPushgatewayではバッチジョブなど一過性のプロセスからもメトリクス収集が可能になります。

この他にも、ミドルウェアのDockerネットワークドライバを使えばDockerコンテナからログやメトリクスを抽出できます。あるいはSysdigの機能を活用すれば、アプリケーションレベルからカーネル全体の実行状況を詳細に可視化できるでしょう。特にeBPFを利用したSysdigの監視機能は注目すべき点で、プロセス単位でのリソース消費を正確にトレースすることが可能になります。

オブザーバビリティの実現には様々なアプローチが存在します。システムを包括的にオブザーバブルにするには、これらの多様な手段を組み合わせていく必要があります。プロキシソースの活用は強力ですが、各ソースで得られる情報が多すぎるとノイズになりかねません。一方で全くオブザーバブルでない領域が残れば、ブラインドスポットが生まれてしまいます。信号収集の目的とコストを見極め、的を絞って収集・活用を行う工夫が求められます。収集対象の信号は最小限に留め、メタデータの付与や集約を行うといった対策も重要になってくるでしょう。

4 Agents and instrumentation

ObservabilityにおけるAgentsとinstrumentationの役割

本章「Agents and instrumentation」は、Observabilityを実現するための重要な要素であるエージェントと計装について詳しく解説しています。著者は、従来のベンダー固有のエージェントやシグナル固有のエージェントと対比させながら、オープンソースの包括的なObservabilityフレームワークであるOpenTelemetryを紹介しています。

全然、別件でLearning Opentelemetryの読書感想文を書いていたので合わせて読んでみてください。

syu-m-5151.hatenablog.com

OpenTelemetryは、仕様、SDKプロトコル(OTLP)、エージェントから構成される一連のコンポーネントであり、ベンダーに依存せずにログ、メトリクス、トレース、将来的にはプロファイルを収集・処理・取り込むことができます。OpenTelemetryを使えば、シグナルの発生元(リソース属性)とテレメトリシグナル自体の両方について、豊富なメタデータを得ることができます。このメタデータには、各シグナルが生成されたサービス、ホスト、コンテナ、クラウドリソースなどの情報が含まれ、システムの動作を理解し、問題の根本原因を特定する上で非常に重要な役割を果たします。

特に、大規模な分散システムでは、各コンポーネントが生成するログ、メトリクス、トレースを関連付けて分析することが不可欠です。OpenTelemetryは、これを可能にする強力なフレームワークであると言えます。OpenTelemetryが提供する豊富なメタデータと、統一された方法でデータを収集・処理する仕組みにより、複雑なシステムの動作を俯瞰的に把握することができます。

意味論的規約の重要性

また、著者は意味論的規約(semantic conventions)の重要性を指摘しています。OpenTelemetryでは、意味論的規約に基づいてテレメトリデータにメタデータを付与することで、バックエンドでの効果的な相関分析を可能にしています。例えば、トレースデータとログデータに共通の属性を付与しておくことで、特定のリクエストに関連するすべてのログを容易に検索・分析できます。こうした相関分析は、複雑な分散システムの動作を理解し、パフォーマンスの問題や障害の原因を特定する上で欠かせません。

opentelemetry.io

従来、テレメトリデータの相関分析は、各ベンダーやツールに固有の方法で行われてきました。しかし、OpenTelemetryの意味論的規約により、ベンダーに依存しない形で相関分析を行うことができるようになります。これは、マルチクラウド環境やマイクロサービスアーキテクチャを採用している組織にとって特に大きなメリットとなるでしょう。統一された方法でテレメトリデータを収集・処理できれば、システム全体の可視性が向上し、問題の迅速な特定と解決が可能になります。

自動計装と手動計装の使い分け

計装に関しては、**アプリケーションのコードを変更せずに自動的にテレメトリを生成する自動計装の重要性が強調されています。

speakerdeck.com

**自動計装は、アプリケーションフレームワークやライブラリと連携して、HTTPリクエスト、データベースクエリ、外部サービス呼び出しなどの主要な操作を自動的にトレースします。これにより、開発者はアプリケーションのコードを変更することなく、システムの動作を可視化できます。

Figure 4.5 Concept of OpenTelemetry collection (from upstream docs; https://opentelemetry.io/docs/reference/specification/logs/overview/) より引用

自動計装は、Observabilityの第一歩として非常に重要な役割を果たします。特に、レガシーなアプリケーションや、コード変更が困難な場合には、自動計装が唯一の選択肢となることもあるでしょう。また、自動計装により得られるデータは、システムのベースラインを把握する上でも役立ちます。

ただし、自動計装には限界もあります。アプリケーション固有のビジネスロジックに関連する情報は、自動計装では捕捉できないことが多いのです。そのため、より詳細な分析を行うには、OpenTelemetry SDKを使った手動計装が必要になります。

手動計装では、開発者がアプリケーションのコードに直接計装を追加します。これにより、重要なビジネスメトリクスや、アプリケーション固有のイベントを収集することができます。例えば、電子商取引サイトであれば、注文処理の各ステップにおける所要時間や、注文金額などのメトリクスを収集することが考えられます。

自動計装と手動計装は、相互に補完する関係にあります。自動計装でシステムの全体像を把握した上で、手動計装でより詳細な情報を収集するのが理想的です。両者を適切に組み合わせることで、システムの可視性を最大限に高めることができるでしょう。

OpenTelemetry collectorの役割と設定

OpenTelemetry collectorは、エージェントとしての中核的な役割を担っており、あらゆるソースからのテレメトリデータを収集し、フィルタリング、サンプリング、属性の追加などの処理を行った上で、様々なバックエンドシステムに転送します。これにより、OpenTelemetry collectorは、Observabilityデータのハブとして機能し、データの流れを集中管理することができます。

OpenTelemetry collectorの設定は、YAMLを使って行います。設定ファイルでは、受信したテレメトリデータをどのように処理し、どの宛先に転送するかを定義します。各シグナルタイプ(メトリクス、トレース、ログ)ごとにパイプラインを設定し、パイプラインの各段階でレシーバー、プロセッサー、エクスポーターを組み合わせて使用します。

Figure 4.6 The OpenTelemetry collector and its components より引用

この柔軟な設定により、OpenTelemetry collectorは様々な環境に適応できます。例えば、オンプレミスとクラウドが混在する環境では、オンプレミスの既存システムからのデータをOpenTelemetry collectorで収集し、クラウドのバックエンドに転送するといった使い方が可能です。また、複数のバックエンドを併用している場合も、OpenTelemetry collectorを中心とすることで、データの流れを一元管理できます。

ただし、OpenTelemetry collectorの設定には注意が必要です。適切なレシーバー、プロセッサー、エクスポーターを選択し、それぞれの設定を最適化しなければなりません。特に、大規模な環境では、データ量が膨大になることがあるため、フィルタリングやサンプリングの設定が重要になります。また、セキュリティの観点から、データの暗号化や認証の設定も欠かせません。

著者は、OpenTelemetry collectorの具体的な設定例も提示しています。この例では、サンプルアプリケーション「ho11y」からメトリクスとトレースを収集し、Prometheusをメトリクスのバックエンドに、Jaegerをトレースのバックエンドに使用しています。

Figure 4.7 Example OpenTelemetry pipeline for traces and metrics より引用

設定ファイルでは、Prometheusレシーバーを使ってPrometheusフォーマットのメトリクスを収集し、OTLPレシーバーを使ってOTLPフォーマットのトレースを収集しています。収集したデータはバッチ処理された後、Prometheusエクスポーターを通じてPrometheusに、Jaegerエクスポーターを通じてJaegerに送信されます。

このような設定例を参考にしつつ、自身の環境に合わせてOpenTelemetry collectorの設定を最適化していくことが求められます。設定ファイルのバージョン管理を行い、変更履歴を追跡できるようにしておくことも重要でしょう。また、設定の変更が及ぼす影響を事前にテストし、問題がないことを確認してから本番環境に適用するなど、慎重な運用が必要です。

OpenTelemetryの柔軟性と拡張性

OpenTelemetryの技術的な側面に目を向けると、その柔軟性と拡張性が際立っています。OpenTelemetryは、ネイティブなOTLPをサポートするだけでなく、Prometheus、Jaeger、Zipkin、Fluentdなど、既存の様々なフォーマットやプロトコルに対応するレシーバーとエクスポーターを提供しています。これにより、既存のシステムからOpenTelemetryへの移行を段階的に進められるほか、複数のバックエンドシステムを並行して利用することもできます。

この柔軟性は、OpenTelemetryの大きな強みの一つです。従来のモニタリングツールやObservabilityプラットフォームは、独自のデータフォーマットやプロトコルを使用していることが多く、他のシステムとの連携が困難でした。しかし、OpenTelemetryなら、そうした既存のシステムともスムーズにデータをやり取りできます。これにより、ベンダーロックインを回避しつつ、既存の資産を活かしながら、Observabilityの向上を図ることができるのです。

また、OpenTelemetryは、コミュニティ主導で活発に開発が進められているオープンソースプロジェクトです。ユーザーは、OpenTelemetryの機能拡張に自ら貢献することもできます。例えば、新しいレシーバーやエクスポーターを開発し、OpenTelemetryのエコシステムに追加することが可能です。こうしたコミュニティの力によって、OpenTelemetryは今後もさらに発展していくことが期待されます。

パフォーマンスとリソース効率

パフォーマンスの観点では、OpenTelemetry collectorのスループットとリソース使用量に注意を払う必要があります。大規模な環境では、多数のエージェントが生成する膨大なテレメトリデータを効率的に処理しなければなりません。そのため、collectorのパフォーマンスチューニングが重要になります。

例えば、バッチ処理の設定を最適化することで、データ処理のスループットを向上させることができます。一方で、バッチサイズを大きくしすぎると、メモリ使用量が増大するため、適切なバランスを見出す必要があります。また、サンプリングを適用してデータ量を削減することも、パフォーマンス改善に効果的です。ただし、サンプリングによって情報が欠落するリスクがあるため、慎重な設定が求められます。

リソース使用量の観点では、メモリ使用量の制御が特に重要です。OpenTelemetry collectorは、受信したデータをメモリ上に保持するため、データ量が増大するとメモリ使用量も増加します。これを放置すると、メモリ不足によってcollectorのパフォーマンスが低下したり、最悪の場合にはOOM (Out of Memory) キルによってプロセスが強制終了したりする可能性があります。

こうしたリスクを回避するため、OpenTelemetry collectorにはメモリリミッタープロセッサが用意されています。メモリリミッタープロセッサを使用すると、メモリ使用量が一定のしきい値を超えた場合に、データの受信を一時的に制限したり、古いデータを削除したりすることができます。ただし、データの欠落が許容できないケースでは、十分なメモリリソースを確保する必要があります。

また、OpenTelemetry collectorのパフォーマンスは、ホスト環境の影響も受けます。特に、コンテナ環境では、リソース制限の設定によってパフォーマンスが大きく左右されます。適切なCPUとメモリのリソース制限を設定し、必要に応じて縮退運転できるようにしておくことが重要です。

パフォーマンスとリソース効率の最適化には、継続的なモニタリングが欠かせません。OpenTelemetry collectorの主要なメトリクス(CPU使用率、メモリ使用量、データ処理のレイテンシなど)を常に監視し、ボトルネックを特定して改善策を講じる必要があります。また、負荷テストを実施して、実際のピーク時の負荷に耐えられるかを確認しておくことも重要です。

Observabilityの新しい標準としてのOpenTelemetry

本章では、Observabilityの実現に向けて、エージェントと計装が果たす重要な役割が詳細に説明されました。特に、OpenTelemetryは、ベンダーロックインを回避しつつ、多様なテレメトリデータを統一的に扱うことができる画期的なフレームワークです。OpenTelemetryが提供する豊富なメタデータと意味論的規約は、システムの動作を深く理解し、問題の迅速な特定と解決に役立ちます。

従来のモニタリングツールやObservabilityプラットフォームは、ベンダー固有のデータフォーマットやAPIを使用していたため、相互運用性に乏しく、複数のツールを併用するのが難しいという問題がありました。しかし、OpenTelemetryは、このような問題を解決し、Observabilityの新しい標準となる可能性を秘めています。

OpenTelemetryが広く普及することで、異なるベンダーのツールやサービス間でシームレスにテレメトリデータをやり取りできるようになります。これにより、エンドツーエンドの可視化、ベンダーロックインの回避、既存システムとの統合が容易になるでしょう。また、OpenTelemetryのオープンなエコシステムは、イノベーションを促進し、Observabilityのベストプラクティスの共有を加速させるはずです。

自動化と最適化の必要性

自動計装と手動計装を適切に組み合わせることで、アプリケーションコードへの変更を最小限に抑えつつ、システムの可視性を高めることができます。自動計装は、Observabilityの基盤を素早く構築するのに役立ちます。一方、手動計装は、ビジネスに特化した重要なメトリクスを収集するのに欠かせません。

ただし、計装を実施するだけでは不十分です。収集したテレメトリデータを効果的に活用するには、データのクリーンアップ、集計、相関分析など、一連のデータ処理が必要となります。OpenTelemetry collectorは、こうしたデータ処理を自動化し、最適化する上で重要な役割を果たします。

特に、大規模で複雑なシステムでは、膨大なテレメトリデータが生成されるため、データの適切なフィルタリングとサンプリングが不可欠です。OpenTelemetry collectorの柔軟な設定により、環境に合わせたデータ処理を実現できます。また、セキュリティ、パフォーマンス、リソース効率など、運用上の要件を満たすように設定を最適化することも重要です。

Observabilityの継続的な改善

Observabilityは、一朝一夕で実現できるものではありません。システムの変化に合わせて、Observabilityの仕組みも継続的に改善していく必要があります。OpenTelemetryは、この継続的な改善を支援する強力なプラットフォームです。

OpenTelemetryを活用することで、システムの変更に素早く適応できます。新しいサービスやコンポーネントを追加する際に、計装を自動的に適用できます。また、OpenTelemetryの柔軟なアーキテクチャにより、バックエンドのツールやサービスを段階的に入れ替えることも可能です。

ただし、OpenTelemetryを効果的に活用するには、組織全体でのコラボレーションが欠かせません。開発者、運用チーム、セキュリティチーム、ビジネス関係者など、様々なステークホルダーが連携し、Observabilityの目標と戦略を共有する必要があります。また、Observabilityのベストプラクティスを継続的に学習し、実践していくことも重要です。

5 Backend destinations

バックエンドの選択がObservabilityの成功を左右する

本章「Backend destinations」では、Observabilityデータの保存と分析を担うバックエンドの重要性について詳しく解説されています。著者は、適切なバックエンドの選択が、Observabilityの取り組みの成功を大きく左右すると強調しています。

opentelemetry.io

バックエンドは、収集されたログ、メトリクス、トレースなどのテレメトリデータを保存し、それらのデータに対するクエリやアラートの実行、ダッシュボードの作成などを可能にする中核的なコンポーネントです。バックエンドの機能性、パフォーマンス、スケーラビリティ、信頼性は、Observabilityシステム全体の有効性に直結します。

したがって、自社のニーズや要件に合ったバックエンドを選択することが極めて重要です。著者は、バックエンドの選定において考慮すべき主要な基準として、コスト、オープンスタンダードのサポート、バックプレッシャーへの対応、カーディナリティとクエリのパフォーマンスなどを挙げています。

コストの観点では、データの取り込み、保存、クエリに関連する直接的なコストに加えて、エンジニアリングチームのサポート、トレーニング、セキュリティパッチ適用などの間接的なコストも考慮する必要があります。オープンスタンダードのサポートは、ベンダーロックインを回避し、相互運用性を確保するために重要です。OpenTelemetryやOpenMetricsなどの業界標準への対応は、バックエンドの選定において重要な基準となります。

バックプレッシャーへの対応は、大量のテレメトリデータを生成するソースからのデータ取り込みを安定的に行うために不可欠です。バックエンドとソース間にキューイングメカニズムを導入することで、バックプレッシャーに起因するデータ欠損や性能低下を防ぐことができます。

カーディナリティとクエリのパフォーマンスは、特にメトリクスデータを扱う際の重要な考慮事項です。次元の値が大きく変動するメトリクスは、時系列データベース(TSDB)におけるカーディナリティの爆発を引き起こす可能性があります。カラムナーストレージを採用したClickHouseやDruidなどのデータストアは、高カーディナリティのメトリクスにも対応できます。

シグナルタイプごとのバックエンドオプション

本章では、ログ、メトリクス、トレースのそれぞれのシグナルタイプに適したバックエンドオプションについて、クラウドプロバイダー、オープンソース、商用の観点から詳しく解説されています。

ログのバックエンドでは、Amazon CloudWatch Logs、Azure Monitor Logs、Google Cloud Loggingなどのクラウドプロバイダーのサービスや、Elasticsearch、OpenSearch、Grafana Lokiなどのオープンソースソリューション、Splunk、Instana、Logz.ioなどの商用製品が紹介されています。

これらのログバックエンドは、インデックス付きの全文検索、構造化クエリ、アラート、ダッシュボードなどの機能を提供します。ログデータのボリュームが大きい場合や、長期的な保存が必要な場合は、コストとパフォーマンスのバランスを考慮してバックエンドを選択する必要があります。クラウドプロバイダーのサービスは、マネージドな環境で手間のかからない運用が可能ですが、コストが高くなる傾向があります。一方、オープンソースソリューションは、自前での運用が必要ですが、コストを抑えることができます。

Figure 5.2 Time series database concept, showing N time series of the mysvc_http_request_total metric より引用

メトリクスのバックエンドとしては、時系列データベース(TSDB)が主流です。PrometheusやInfluxDBなどのオープンソースのTSDBに加え、各クラウドプロバイダーのマネージドPrometheusサービスや、M3DB、VictoriaMetricsなどのスケーラブルなソリューションが注目されています。

TSDBは、メトリクスデータの効率的な格納と、時間範囲やラベルに基づくクエリを可能にします。PrometheusはKubernetesエコシステムにおける事実上の標準となっており、多くのツールやサービスとの統合が進んでいます。一方、M3DBやVictoriaMetricsは、Prometheusとの互換性を保ちつつ、よりスケーラブルなアーキテクチャを提供します。

トレースのバックエンドは、JaegerやZipkinなどのオープンソースプロジェクトが広く採用されている一方で、クラウドプロバイダーやObservabilityベンダーの商用ソリューションも充実しています。ElasticsearchやOpenSearchもトレースのバックエンドとして使用できます。

トレースデータは、分散システムにおけるリクエストの流れを可視化し、パフォーマンスのボトルネックや異常を特定するために使用されます。Jaegerは、OpenTelemetryとの緊密な統合により、幅広いプログラミング言語フレームワークをサポートしています。商用ソリューションは、AIを活用した自動的な異常検知やパフォーマンス最適化の提案など、高度な分析機能を提供します。

cloud.google.com

カーディナリティの課題とカラムナーデータストア

本章では、メトリクスのバックエンドを選択する際の重要な考慮事項として、カーディナリティの問題が取り上げられています。カーディナリティとは、メトリクスの各次元が取り得る値の数を指します。ユーザーIDやセッションIDのように、値が大きく変動する次元を持つメトリクスを扱う場合、TSDBではカーディナリティの爆発が発生し、データの取り込み、保存、クエリのパフォーマンスに深刻な影響を与える可能性があります。

この課題に対処するために、著者はカラムナーストレージを採用したデータストアの活用を提案しています。カラムナーストレージは、データを列単位で格納することで、高いデータ圧縮率と優れたクエリパフォーマンスを実現します。Apache CassandraApache Druid、ClickHouse、Snowflakeなどが代表的なカラムナーデータストアとして紹介されています。

Figure 5.5 Row-oriented vs. column-oriented storage より引用

特に、ClickHouseを使ったログのバックエンドの例では、OpenTelemetry CollectorとClickHouseを組み合わせることで、ログデータをカラムナーフォーマットで効率的に保存し、SQLを使って柔軟にクエリできることが示されています。

github.com

カラムナーストレージは、高カーディナリティのメトリクスだけでなく、ログやトレースデータの保存と分析にも適しています。ログデータは、多様な構造を持つイベントの集合体であり、カラムナー形式での保存により、クエリのパフォーマンスを大幅に向上させることができます。トレースデータも、スパンのフィールドを列として保存することで、効率的なクエリが可能になります。

カラムナーデータストアは、Observabilityデータの長期的な保存と分析において重要な役割を果たします。データレイクとしてのカラムナーストレージに、ログ、メトリクス、トレースを統合することで、包括的な分析と相関関係の発見が可能になります。また、カラムナー形式のデータは、機械学習データマイニングのワークロードにも適しており、異常検知やパターン認識などの高度な分析にも活用できます。

ポリグロットバックエンドアーキテクチャ

Observabilityデータの種類や特性に応じて、複数のバックエンドを組み合わせて使用するポリグロットなアプローチも有効です。例えば、ログデータにはElasticsearch、メトリクスデータにはPrometheus、トレースデータにはJaegerを使用するといった構成が考えられます。

ポリグロットバックエンドアーキテクチャは、各シグナルタイプに最適化されたバックエンドを選択することで、パフォーマンスとコスト効率を最大化できます。一方で、異なるバックエンド間でのデータの相関分析や一貫性の確保が課題となります。

この課題に対処するために、OpenTelemetryなどの共通の収集および転送層を導入することが推奨されます。OpenTelemetryは、ログ、メトリクス、トレースを統一的に扱うことができ、バックエンドの違いを吸収します。また、Grafanaなどの可視化ツールは、複数のバックエンドからデータを取得し、統合されたダッシュボードを提供することができます。

ポリグロットバックエンドアーキテクチャの採用には、運用の複雑さと管理コストの増加というトレードオフがあります。バックエンドごとにデータの保存期間やアクセス制御を適切に設定し、モニタリングとアラート設定を行う必要があります。また、バックエンド間のデータ同期や整合性の問題にも注意が必要です。

制約と誓約

本章で提示された知見を踏まえると、Observabilityにおけるバックエンドの選定は、システムアーキテクチャとデータ管理の両面から慎重に検討すべき重要な意思決定であると言えます。適切なバックエンドの選択は、Observabilityの取り組みの成功を大きく左右します。

組織は、自社のユースケースに合ったバックエンドを選択する必要があります。コスト、パフォーマンス、スケーラビリティ、相互運用性など、さまざまな要素を総合的に評価し、長期的な視点に立ってバックエンドの選定を行うべきです。また、バックエンドの特性や制約を深く理解し、データモデルに適したアーキテクチャを採用することが重要です。

メトリクスのカーディナリティ問題に代表されるように、バックエンドの選択はデータの特性に大きく依存します。高カーディナリティのメトリクスを扱う場合は、カラムナーストレージの採用を検討すべきです。また、ログやトレースデータの長期的な保存と分析においても、カラムナーデータストアが有力な選択肢となります。

ポリグロットバックエンドアーキテクチャは、各シグナルタイプに最適化されたバックエンドを組み合わせることで、パフォーマンスとコスト効率を最大化できる可能性を秘めています。ただし、運用の複雑さと管理コストの増加には十分な注意が必要です。OpenTelemetryなどの共通の収集および転送層を導入し、可視化ツールを活用することで、バックエンド間のデータ統合と相関分析を実現できます。

6 Frontend destinations

フロントエンドとオールインワンソリューションの役割

本章「Frontend destinations」では、Observabilityデータの可視化と分析を担うフロントエンドとオールインワンソリューションについて詳しく解説されています。フロントエンドは、バックエンドに保存されたObservabilityデータと対話し、ユーザーが様々なグラフィカルおよびテキスト形式でアドホックな質問に答えを見つけるために使用します。一方、オールインワンソリューションは、バックエンドとフロントエンドを一体化したものであり、ベンダーが設計したバックエンドとの組み合わせでのみ使用できます。

著者は、フロントエンドとオールインワンソリューションの選択が、Observabilityの取り組みの成功に大きな影響を与えることを強調しています。適切なツールを選択することで、開発者やビジネスステークホルダーに価値を提供し、機能の出荷やバグ修正の加速、本番環境での問題解決時間の短縮、開発者の生産性向上などを実現できます。

オープンソースとコマーシャルオファリングの比較

本章では、Grafana、Kibana、OpenSearch Dashboardsなどの人気のあるオープンソースフロントエンドや、Jaeger、Zipkin、Apache SkyWalkingなどのオールインワンソリューションについて詳細に説明されています。これらのオープンソースツールは、幅広いバックエンドとの統合、豊富な視覚化オプション、アラート機能などを提供しており、自社のObservabilityソリューションを構築する際の強力な基盤となります。

Figure 6.1 An example Grafana data source, showing configuration options より引用

GrafanaはPrometheusと、KibanaはElasticsearchと、それぞれ緊密に連携しており、メトリクスとログの可視化において重要な役割を果たしています。一方、JaegerやZipkinは、OpenTelemetryとの統合により、幅広いプログラミング言語フレームワークをサポートする分散トレーシングソリューションとして広く採用されています。

Figure 6.6 Jaeger UI showing all traces for a certain tag (http.status_code=404) より引用

また、SigNozやUptraceなど、ClickHouseをバックエンドに使用するオープンソースのオールインワンソリューションも登場しています。これらのツールは、OpenTelemetryを活用してテレメトリデータを収集し、SQLを使ってデータを柔軟にクエリできる点が特徴です。

一方、商用ソリューションは、高度な分析機能、AIを活用した異常検知、パフォーマンス最適化の提案など、より豊富な機能を提供します。DatadogやNew Relicなどの有名ベンダーは、自動計装に基づくアウトオブザボックスの機能や、幅広いインテグレーションを備えています。また、Lightstepのようなunified storage layerを持つソリューションは、異なるシグナルタイプを統合的に扱うことができます。

ツール選定の考慮事項

フロントエンドとオールインワンソリューションの選定においては、以下の点を考慮する必要があります。

  1. コスト: フロントエンドのコストは予測可能ですが、オールインワンソリューションではバックエンドのコストも考慮する必要があります。オープンソースを選択する場合は、サポート、パッチ適用、スケーリングなどの運用コストを見積もることが重要です。

  2. ベンダーロックインの回避: オープンスタンダード(OpenTelemetryなど)をサポートするオールインワンソリューションは、ベンダーロックインを最小限に抑えつつ、運用負荷を軽減できる優れた選択肢です。

  3. オープンソースプロジェクトの健全性: オープンソースツールを選ぶ際は、プロジェクトの背景、ライセンス、コントリビューターの多様性、ドキュメントの品質、Issue対応の速度などを評価することが不可欠です。

  4. 相関分析のサポート: 複数のシグナルタイプをサポートするツールにおいては、時間ベースの相関分析や、あるシグナルタイプから別のシグナルタイプへのスムーズな移動を可能にする機能が重要です。

シングルパネルオブグラスとデータ相関の重要性

著者は、Observabilityにおける「シングルパネルオブグラス」の概念について言及しています。これは、ログ、メトリクス、トレースなどの異なるシグナルタイプを単一のインターフェースで統合的に扱うことを指します。シングルパネルオブグラスを実現することで、システムの動作を包括的に把握し、問題の迅速な特定と解決が可能になります。

ただし、著者は、シングルパネルオブグラスを絶対的な要件とするのではなく、柔軟なアプローチを取ることを推奨しています。つまり、主要なフロントエンドツールを中心に据えつつ、必要に応じて専門的なツールを組み合わせるのが現実的だと述べています。

シングルパネルオブグラスに関連して、データの相関分析が重要な役割を果たします。異なるシグナルタイプ間の関連性を明らかにすることで、複雑なシステムの動作を理解し、パフォーマンスの問題や障害の根本原因を特定できます。著者は、Grafana version 10で導入された相関APIを例に挙げ、変数と変換を使用した相関分析の実現方法を紹介しています。

フロントエンドとオールインワンの選択プロセス

フロントエンドとオールインワンソリューションの選択において、最初に検討すべきは、「構築か、購入か」の意思決定です。社内でObservabilityプラットフォームを構築することが競争上の優位性につながるのでない限り、できる限りアウトソーシングすることが推奨されます。一方、ベンダーやクラウドプロバイダーへの依存を最小限に抑えたい企業では、オープンソースとオープンスタンダードに基づいたソリューションを構築するのが賢明です。

選定プロセスでは、以下の点を評価します。

  1. 総コストの見積もり(ライセンス料、インフラコスト、運用コストなど)
  2. ベンダーロックインのリスク
  3. オープンソースプロジェクトの成熟度と持続可能性
  4. 相関分析を含む主要機能のサポート状況

加えて、全てのステークホルダーを巻き込み、要件を明確にすることが肝要です。技術的な側面だけでなく、ビジネス要件や ユーザビリティなども考慮して、最適なソリューションを選択しましょう。

Observabilityツールの継続的な評価と改善

Observabilityの分野は急速に発展しており、新しいツールやソリューションが次々と登場しています。選択したフロントエンドやオールインワンソリューションが、将来にわたって組織のニーズを満たし続けられるとは限りません。したがって、定期的にツールを評価し、必要に応じて見直しや改善を行うことが重要です。

評価の際は、以下の点を考慮します。

  1. 新しい機能やインテグレーションの追加
  2. パフォーマンスとスケーラビリティの向上
  3. コミュニティの活発さとサポートの継続性
  4. ライセンスやコストモデルの変更

また、Observabilityツールの運用においては、以下のような継続的な改善活動が求められます。

  1. ダッシュボードやアラートの最適化
  2. データ保持期間とコストのバランス調整
  3. 新しいシグナルソースやデータ型の取り込み
  4. ユーザートレーニングとドキュメントの整備

Observabilityは、単なるツールの導入で完結するものではありません。組織全体でObservabilityの文化を醸成し、継続的な改善を通じて、システムの可視性と運用効率を高めていく必要があります。

Observabilityの価値実現に向けて

本章では、Observabilityにおけるフロントエンドとオールインワンソリューションの重要性、それらのツールの選定と運用における考慮事項について詳しく解説されました。Observabilityの真の目的は、システムの動作を深く理解し、問題の迅速な特定と解決を可能にすることで、ビジネス価値の実現を支えることにあります。

適切なツールを選択し、継続的な改善を積み重ねることで、Observabilityの取り組みを成功に導くことができます。オープンソースとオープンスタンダードを活用しつつ、組織のコンテキストに合ったソリューションを構築することが肝要です。また、ログ、メトリクス、トレースなど、異なるシグナルタイプを相関分析できる機能を備えることで、システムの全体像を俯瞰し、問題の根本原因を特定しやすくなります。

フロントエンドとオールインワンソリューションは、Observabilityデータの可視化と分析を通じて、ソフトウェアエンジニアリングとシステム運用に大きな価値をもたらします。本章で得られた知見を活かし、自組織に適したツール戦略を練り上げていきましょう。Observabilityの文化を育み、データドリブンな意思決定を促進することで、ビジネスの俊敏性と回復力を高めることができるはずです。

7 Cloud operations

インシデント管理のベストプラクティス

本章「Cloud operations」では、クラウドネイティブアプリケーションを円滑に運用するための重要な要素であるインシデント管理、ヘルスモニタリング、アラート、ガバナンス、使用状況の追跡について詳しく解説されています。特に、インシデント管理に関しては、インシデントの検出、処理、そしてインシデントから学ぶことの重要性が強調されています。

クラウドネイティブシステムは多数のコンポーネントで構成されており、これらのコンポーネントは相互に依存しています。そのため、ひとつのコンポーネントで問題が発生すると、その影響が全体に波及する可能性があります。こうした複雑なシステムにおいて、エンドユーザーに影響を与える問題が発生した場合、どのコンポーネントが根本原因なのかを特定することは容易ではありません。

したがって、システムの外部から継続的にヘルスモニタリングとパフォーマンスモニタリングを行い、期待通りに機能していないことを素早く検知することが不可欠です。モニタリングシステムは、各コンポーネントの主要なメトリクスを収集し、異常値や閾値超過を検出できるように設定する必要があります。これにより、インシデントの兆候をいち早く捉え、影響が拡大する前に対処できます。

著者が強調しているのは、インシデントが発生した際には、原因分析よりも問題の解決を優先すべきだということです。つまり、エンドユーザーへの影響を最小限に抑えることが最優先事項であり、そのためには問題の切り分けと適切な対処を迅速に行う必要があります。具体的には、関連するログやメトリクスを確認してシステムの状態を把握し、影響範囲を特定した上で、適切な措置を講じる必要があります。また、ステークホルダーに対しても、状況と対応方針を適宜共有することが重要です。

インシデントが収束した後は、再発防止に向けた原因分析が必要です。著者は、非難を伴わないポストモーテム(事後分析)を行うべきだと述べています。ポストモーテムでは、「5 Whys」などの手法を用いて根本原因を掘り下げ、具体的な再発防止策を特定することが重要です。さらに、インシデントの経緯と学びを文書化し、組織内で共有することで、将来のインシデント対応に活かすことができます。

インシデント管理のベストプラクティスを確立するためには、以下のような点に留意する必要があります。

  • インシデントの検知と通知の自動化: モニタリングシステムと連動したアラート設定により、インシデントの兆候を早期に検知し、適切な担当者に自動的に通知する。
  • インシデントの優先度付けとエスカレーション: インシデントの影響度に応じて優先度を設定し、適切なタイミングでエスカレーションを行う。
  • コミュニケーションの明確化: インシデント対応の際の連絡体制とコミュニケーションチャネルを予め定義しておく。
  • ランブックとプレイブックの整備: よくあるインシデントへの対処手順をランブック(運用手順書)やプレイブック(対応シナリオ)としてまとめ、迅速かつ的確な対応を可能にする。
  • ポストモーテムの徹底: インシデントの原因究明と再発防止策の特定を徹底的に行い、組織としての学びを促進する。

これらのプラクティスを確実に実行できるよう、定期的にインシデント対応の訓練を行うことも重要です。様々なシナリオを想定した机上訓練や、実際にシステムの一部に障害を発生させるカオスエンジニアリングなどを通じて、チームのインシデント対応力を高めていくことができます。

アラート設計のポイントと継続的な最適化

アラートは、システムの異常を検知し、適切な担当者に通知するための重要な仕組みです。しかし、アラートの設定が不適切だと、大量の無駄なアラートが発生して対応が追いつかなくなったり、逆に重大な問題を見逃してしまったりする恐れがあります。したがって、アラートの設計には細心の注意を払う必要があります。

著者は、アラートの設計において、以下のような点が重要だと指摘しています。

  • 重要度の設定: インシデントの影響度に応じて、アラートの重要度(critical, warning, infoなど)を適切に設定する。
  • 閾値の調整: アラートの閾値を適切に設定し、誤検知や見逃しを最小限に抑える。
  • アラートのグループ化と抑制: 関連するアラートをグループ化し、不要なアラートを抑制することで、アラートのノイズを減らす。
  • エスカレーションパスの明確化: アラートの重要度に応じて、エスカレーション先と連絡方法を明確に定義する。

これらの設定を適切に行うことで、重要なアラートを見逃すことなく、迅速に対応できるようになります。

本章では、Prometheusを使ったアラートの設定方法が具体的に解説されています。PrometheusではAlertmanagerと呼ばれるコンポーネントが、アラートのグループ化や通知の設定を担当します。Prometheusの設定ファイルでアラートルールを定義し、Alertmanagerの設定ファイルでアラートの通知先やグループ化のルールを指定します。

著者が提示した例では、PrometheusのAPIコール数が一定のしきい値を超えた場合にアラートが発報され、Alertmanagerを経由してWebhookに通知が送信されます。アラートルールの定義では、PromQLと呼ばれるクエリ言語を使ってアラート条件を記述します。また、ラベルやアノテーションを使ってアラートの詳細情報を指定できます。

Figure 7.2 Prometheus and the Alertmanager より引用

Alertmanagerの設定では、アラートのグループ化や通知先の指定、通知メッセージのカスタマイズなどが可能です。たとえば、同じアプリケーションに関連するアラートをまとめたり、アラートの重要度に応じて通知先を変えたりといったことができます。また、抑制ルールを設定することで、特定の条件に一致するアラートを一時的に抑制することもできます。

アラートの設計は一度で完璧にはできません。システムの変更に合わせて、継続的にアラートの設定を見直し、最適化していく必要があります。以下のような点に注意しながら、アラートの改善を進めていくことが重要です。

  • アラートの効果の定期的な評価: アラートが期待通りに機能しているか、定期的に評価する。不要なアラートが多い場合は、閾値の調整やアラートルールの見直しを検討する。
  • システム変更へのタイムリーな対応: システムの変更に合わせて、アラートの設定を速やかに更新する。特に、新しい機能のリリース時には、適切なアラートを設定するように心がける。
  • アラートの受信者の最適化: アラートの受信者が適切か定期的にレビューする。担当者の変更やオンコール体制の見直しに合わせて、アラートの通知先を更新する。
  • エスカレーションパスの確認: 重要なアラートが確実にエスカレーションされるよう、エスカレーションパスを定期的にテストする。

アラートは、インシデント管理において重要な役割を果たします。適切なアラートの設定は、インシデントの早期検知と迅速な対応を可能にします。しかし、アラートの設計は継続的な改善が必要なプロセスです。システムの変更に合わせてアラートを最適化し、運用チームの負荷を最小限に抑えながら、インシデントを確実に検知できるようにしていくことが求められます。

今後の課題

本章では、クラウドネイティブアプリケーションの運用において重要となるインシデント管理、ヘルスモニタリング、アラート、ガバナンス、使用状況の追跡について詳しく解説されました。

インシデント管理については、インシデントの検知から対応、そしてポストモーテムまでのプロセスを適切に定義し、実行することが重要だと述べられています。特に、インシデント発生時には問題の解決を最優先し、その後に原因分析を行うべきだと強調されています。また、ポストモーテムを通じて、インシデントから学びを得て、再発防止につなげることが重要だと指摘されています。

アラートについては、適切な設計と継続的な最適化が必要だと述べられています。アラートの重要度や閾値の設定、アラートのグループ化や抑制、エスカレーションパスの明確化などが、アラートの効果的な運用に欠かせないポイントとして挙げられています。また、Prometheusを使ったアラートの設定方法が、具体的な例を交えて解説されています。

ユーザー行動の追跡に関しては、Real User Monitoringを使ったエンドユーザーの行動分析や、CloudTrailなどを使った内部ユーザーのアクション追跡の重要性が指摘されています。これらのデータを活用することで、パフォーマンスの改善やセキュリティ強化、コンプライアンス対応などに役立てることができます。

さらに、コスト最適化の重要性についても言及されています。クラウドの利用が拡大する中で、リソースの使用状況を可視化し、無駄な支出を削減することが求められます。AWS Cost and Usage ReportsやKubernetes向けのOpenCostなどのツールを活用することで、コストの最適化を進められると述べられています。

クラウドネイティブ時代の運用は、従来のオンプレミス環境とは大きく異なります。インフラストラクチャのプロビジョニングや設定管理の自動化、オブザーバビリティの確保、コストの最適化など、多岐にわたる課題に取り組む必要があります。本章で得られた知見は、これらの課題に立ち向かう上で、重要な指針となるでしょう。

ただし、本章で取り上げられたトピックは、クラウドネイティブの運用における一部に過ぎません。たとえば、カオスエンジニアリングによるシステムの回復力向上や、AIOpsの活用による運用の自動化など、本章では触れられていない重要なテーマもあります。また、クラウドネイティブの運用プラクティスは、急速に進化し続けています。新しいツールやサービス、アプローチが次々と登場する中で、運用チームは常に学習と適応が求められます。

クラウドネイティブの運用は、単なるシステムの維持ではなく、ビジネスの成功に直結する戦略的な活動です。本章で紹介された手法やツールを活用しつつ、組織の文化や目標に合わせてアプローチをカスタマイズしていくことが重要です。運用の自動化や効率化を進める一方で、チーム内のコラボレーションや、開発チームとのコミュニケーションを強化することも忘れてはなりません。

8 Distributed tracing

分散トレーシングでクラウドネイティブシステムを徹底的に可視化

本書「Observability In Action」の第8章「Distributed tracing」では、分散トレーシングという手法を用いて、クラウドネイティブシステムの複雑な動作を可視化する方法について詳しく解説されています。著者は、モノリシックなアプリケーションではログとメトリクスだけで十分だったのに対し、マイクロサービスアーキテクチャではサービス間の関係性を追跡するために分散トレーシングが欠かせないと指摘しています。

分散トレーシングは、個々のリクエストがシステム内の各サービスをどのように通過するかを追跡し、処理のフローと時間情報を記録することで、システム全体の動作を俯瞰的に把握できるようにする技術です。 各サービスはリクエストの処理過程でスパン(span)と呼ばれる情報を生成し、これらのスパンが集まってエンドツーエンドのトレース(trace)を形成します。分散トレーシングツールは、これらのトレースデータを収集、分析、可視化することで、開発者やSREがシステムの動作を理解し、パフォーマンスの問題や障害の原因を特定できるようサポートします。

Figure 8.3 A single request path in the app, as a temporal (waterfall) visualization より引用

本章では、分散トレーシングの基本概念とユースケースが丁寧に説明されています。トレースやスパンといった基本的な用語の定義から始まり、サンプリングやコンテキスト伝搬など、実践的な話題にも踏み込んでいます。 特に、分散トレーシングが単なるツールの導入ではなく、開発チーム全体で取り組むべき文化的な実践であるという指摘が印象的でした。

また、著者自身が開発したサンプルアプリケーションを使って、Jaegerというオープンソースのトレーシングツールでマイクロサービスのトレースを可視化する手順が詳しく解説されています。実際のトレースデータを見ながら、サービスマップやウォーターフォールダイアグラムを使ってシステムの動作を分析する方法を学べるのは、大変有益だと感じました。

Figure 8.7 Troubleshooting the demo microservices app: an example failure trace and the span that caused the failure より引用

本章の後半では、分散トレーシングを導入・運用する上での実用的なアドバイスが提供されています。 トレースのサンプリング方法の選択、分散トレーシングにかかるコスト(オブザーバビリティ税)の見積もり方、ログやメトリクスとの使い分けなど、実際のプロジェクトで直面しそうな課題に対するヒントが豊富に盛り込まれていました。

エンドツーエンドの可視化でシステムをホリスティックに理解

分散トレーシングは、複雑化するクラウドネイティブシステムをエンドツーエンドで可視化し、ホリスティック(包括的)に理解するための強力な手法だと言えます。マイクロサービス間の呼び出しフローを追跡することで、システム全体のアーキテクチャを俯瞰でき、パフォーマンスのボトルネックや障害の波及経路を特定しやすくなります。また、各スパンが処理時間や結果のステータスなどの詳細情報を持つため、トレースデータを分析することで、パフォーマンスの最適化や障害対応を効率化できます。

一方で、分散トレーシングの導入には一定のコストがかかることも事実です。各サービスにおける計装、トレースデータの収集・保存のためのインフラ、分析・可視化ツールの運用など、様々な側面でコストが発生します。 本章でも指摘されているように、これらのコストに見合うだけの価値が得られるかを見極めることが重要です。

分散トレーシングを成功に導く秘訣

分散トレーシングをプロジェクトに導入し、その恩恵を最大限に引き出すためには、単にツールを導入するだけでなく、組織文化やプロセスの変革も必要だと感じました。本章から得られた教訓をまとめると、以下のようになります。

  1. 分散トレーシングをオブザーバビリティ戦略の一環として位置づける
    • ログ、メトリクスと並ぶ重要な柱として、体系的に取り組む
  2. 開発チーム全体でトレーシングの価値を共有する
    • トレーシングがもたらすメリットを開発者に伝え、活用を促す
  3. 計装を自動化し、手間を最小限に抑える
    • OpenTelemetryなどの自動計装を活用する
  4. トレースデータを集約し、関連情報と紐付けて分析する
    • トレースIDを軸に、ログやメトリクスと関連づけて分析する
  5. 可視化ツールを使ってトレースを直感的に理解する
  6. コストとベネフィットのバランスを見極める
    • 過剰な情報収集は避け、本当に必要なスパンに絞り込む

分散トレーシングの未来

本章では、分散トレーシングという手法の現状について詳しく解説されていましたが、この分野は現在も活発に発展し続けています。 特に、OpenTelemetryプロジェクトが、ベンダー中立な分散トレーシングのためのオープンスタンダードとして注目を集めています。各言語のSDKAPIの整備、自動計装の充実など、OpenTelemetryの登場により、分散トレーシングの導入が以前よりも容易になることが期待されます。

また、AIOpsやオブザーバビリティプラットフォームとの連携も、分散トレーシングの今後の発展において重要なトピックだと考えられます。トレースデータを機械学習モデルで分析することで、異常検知やパフォーマンス最適化の自動化が進むかもしれません。さらに、ログやメトリクスなど他のオブザーバビリティデータとトレースを統合的に扱うプラットフォームが登場すれば、よりホリスティックなシステム理解が可能になるでしょう。

組織の分散トレーシングは俺と仲間で育ててる

分散トレーシングは、現代のクラウドネイティブシステムにおいて欠かせないオブザーバビリティ技術の一つです。マイクロサービス間の複雑な相互作用を可視化し、パフォーマンスや信頼性の向上に役立てることができます。本章で得られた知見は、実際のシステム開発・運用の様々な場面で活用できるはずです。

一方で、分散トレーシングはシルバーバレットではありません。ツールの導入だけでなく、チーム全体でトレーシングの価値を共有し、データを効果的に活用するための文化やプロセスの変革が求められます。また、トレーシングにかかるコストを適切にコントロールし、投資対効果を見極めることも重要です。

分散トレーシングに取り組む際は、本章で紹介された基本概念やベストプラクティスを押さえつつ、自分たちのシステムやチームに合ったやり方を模索していくことが大切だと感じました。オープンスタンダードの採用や、他のオブザーバビリティ実践との連携など、新しい潮流にも注目しながら、システムのエンドツーエンドの可視化を追求していきたいと思います。

9 Developer observability

Developer observabilityで開発者の生産性を加速する

本書「Observability In Action」の第9章「Developer observability」では、Developer observabilityの概念とその実現方法について詳しく解説されています。著者は、Developer observabilityを「開発者に行動可能なインサイトを提供することで、開発速度の向上、コードのデバッグ、新機能の性能・リソース使用量の理解を可能にするテレメトリシグナルの活用」と定義しています。Efficient Goも書籍として良かったのでオススメです。日本語の「効率的なGo ―データ指向によるGoアプリケーションの性能最適化」もあるので合わせて読んでみてください。

learning.oreilly.com

従来、開発者は主にコードの作成に注力し、テスト、パッケージング、デプロイ、運用は他の部門が担当するのが一般的でした。しかし、Developer observabilityの登場により、開発者自身がこれらの工程に関与し、迅速なフィードバックループを確立できるようになりました。 これにより、問題の早期発見と修正が可能となり、全体的なコストを削減できます。

本章では、Developer observabilityを実現する具体的な手法としてContinuous profiling(継続的プロファイリング)に焦点が当てられています。Continuous profilingを使うことで、開発者はサービスの現在のパフォーマンスとリソース使用量を把握し、コード変更前後の比較が可能になります。これにより、新機能追加によるトレードオフ定量的に評価できるようになります。

著者は、Continuous profilingの基盤技術として、pprofフォーマット、Flame graph、eBPFなどを紹介しています。pprofは、Googleが開発したプロファイリングデータの可視化・分析ツールであり、プロファイルをProtocol Buffers形式で表現します。 Flame graphは、プロファイルの呼び出しスタックを視覚的に表現する手法で、eBPFはLinuxカーネルを拡張してプロファイル収集を行う仕組みです。これらの技術を理解することが、Continuous profilingを活用する上で重要だと指摘されています。

Figure 9.2 An flame graph using our pprof Go example より引用

本章ではまた、Parca、Pixie、Pyroscopeなど、オープンソースのContinuous profilingツールが紹介されています。これらのツールは、pprofフォーマットをサポートし、eBPFを活用してプロファイルを収集します。クラウドプロバイダーや商用ベンダーも、独自のContinuous profiling機能を提供し始めています。 AWS CodeGuru Profiler、Azure Application Insights Profiler、Google Cloud Profilerなどが代表的な例です。

Figure 9.3 The eBPF call flow in the Linux kernel at a conceptual level (Source: Brendan Gregg. Licensed under CC BY 4.0) より引用

さらに著者は、Continuous profilingをOpenTelemetry collectorの性能分析に活用する具体的な手順を示しています。pprofエクステンションを有効化したOpenTelemetry collectorからプロファイルを収集し、Parcaを使って可視化・分析する一連の流れが丁寧に説明されており、実践的な知見が得られます。

Continuous profilingに加えて、本章ではDeveloper productivityツールについても言及されています。これらのツールは、OpenTelemetryを基盤とし、コード変更が性能やリソース使用量に与える影響を開発者に可視化します。Digma、Sprkl、Tracetest、Rookout、Autometricsなどが代表的な例として紹介されています。

Digmaは、OpenTelemetryのトレースとメトリクスを分析し、コードレベルのインサイトを提供するIDEプラグインです。 開発者は、コードを編集しながら、パフォーマンス、エラー、使用状況に関するフィードバックを得ることができます。

Sprklは、OpenTelemetryを使ってコードをインスツルメントし、コード変更の実行時の振る舞いを探索できるようにします。 コードレベルのトレース、システム内の他のエンティティとの関係、パフォーマンスレポートなどが提供されます。

Tracetestは、OpenTelemetryのトレースを利用して、マイクロサービス間の統合テストを構築するためのツールです。 サービス間の呼び出しフローを定義し、期待されるレスポンスとトレースデータに対してアサーションを記述できます。

ただし著者は、Developer observabilityツールの採用には注意が必要だと指摘しています。シンボル情報の取り扱い、プロファイルの保存とクエリ、他のテレメトリデータとの相関分析、オープンスタンダードへの準拠など、克服すべき課題が残されています。特に本番環境での利用には、パフォーマンスへの影響を慎重に見極める必要があります。

Continuous profilingの技術的側面に迫る

本章では、Continuous profilingの基盤となる技術について詳しく解説されていました。特に、pprofフォーマット、Flame graph、eBPFは、Continuous profilingを支える重要な要素として紹介されています。

pprofは、Googleが開発したプロファイリングデータの可視化・分析ツールであり、プロファイルをProtocol Buffers形式で表現します。pprofのデータフォーマットは、Continuous profilingツールの多くが採用しており、事実上の標準となりつつあります。著者は、pprofの内部構造を詳解し、protocを使ってpprofファイルをデコードする方法も示しています。これにより、開発者はpprofの仕組みを深く理解し、より効果的にContinuous profilingを活用できるようになります。

pprofのデータ構造は、Profileメッセージを中心に構成されています。 Profileメッセージには、サンプルの種類(ValueType)、収集されたサンプル(Sample)、マッピング情報(Mapping)、ロケーション情報(Location)、関数情報(Function)などが含まれます。これらのサブメッセージを組み合わせることで、プロファイリングデータが表現されるのです。

Flame graphは、プロファイルの呼び出しスタックを視覚的に表現する手法です。著者は、Flame graphの読み方を丁寧に解説し、slowTask()quickTask()といった関数の実行時間を色と幅で表現する例を示しています。Flame graphを使いこなすことで、開発者はボトルネックの特定や性能の最適化を直感的に行えるようになります。

Flame graphでは、x軸方向に呼び出しスタックが並べられ、y軸方向にスタックの深さが示されます。 各関数の実行時間は、対応する長方形の幅で表現されます。これにより、どの関数がCPU時間を多く消費しているかが一目で分かります。また、呼び出し元と呼び出し先の関係も、スタックの階層構造から読み取ることができます。

eBPFは、Linuxカーネルを拡張し、プロファイルの収集を可能にする仕組みです。著者は、eBPFの基本概念とContinuous profilingにおける役割を説明しています。eBPFを活用することで、アプリケーションコードに変更を加えることなく、カーネルレベルでのプロファイリングが実現できます。 ただし、eBPFを本番環境で利用するには、カーネルバージョンや設定に注意が必要だと指摘されています。

eBPFプログラムは、カーネル内の特定のイベント(関数の呼び出し、リターン、パケットの受信など)にアタッチされ、イベント発生時に実行されます。これにより、カーネルの動作を詳細に観測し、必要な情報を収集することが可能になります。収集されたデータは、カーネル内のeBPFマップを介してユーザー空間に渡され、分析ツールで処理されます。

これらの技術的な説明は、Continuous profilingの仕組みを深く理解する上で欠かせません。pprofやeBPFを適切に活用することで、開発者はアプリケーションの性能を正確に把握し、改善に役立てることができるでしょう。一方で、これらの技術にはそれぞれ固有の制約や課題があることも忘れてはなりません。著者が示唆するように、Continuous profilingを効果的に実践するには、技術的な理解と、トレードオフを見極める判断力の両方が求められます。

プロファイルの保存と分析の課題に挑む

Continuous profilingを実践する上で、プロファイルデータの保存と分析は大きな課題となります。著者は、列指向のストレージとXOR圧縮という2つのアプローチを紹介しています。

列指向のストレージは、プロファイルデータを効率的に保存し、クエリを高速化するために用いられます。著者は、ParcaチームがGo言語で開発したFrostDBを例に挙げ、列指向データベースがプロファイルの保存に適していることを説明しています。FrostDBは、Apache Parquetをストレージフォーマットに、Apache Arrowをクエリエンジンに採用しており、半構造化スキーマをサポートしています。

列指向ストレージでは、データが列単位で格納されます。つまり、同じ列に属するデータが連続的に配置されるのです。これにより、特定の列に対するクエリが高速化されます。また、列単位の圧縮が可能となり、ストレージ容量を大幅に削減できます。プロファイルデータは、呼び出しスタックや関数名、タイムスタンプなど、複数の列から構成されるため、列指向ストレージとの親和性が高いと言えます。

一方、XOR圧縮は、プロファイルのタイムスタンプを効率的に圧縮するための手法です。著者は、Facebookのエンジニアチームが考案した「Gorilla」アルゴリズムを紹介し、タイムスタンプのデルタ値を符号化することで、ストレージ容量を大幅に削減できると説明しています。

XOR圧縮では、連続するタイムスタンプの差分(デルタ)を計算し、そのデルタ値をXOR演算で符号化します。 これにより、タイムスタンプの繰り返しパターンが効果的に圧縮されます。プロファイルデータは、連続的に収集されるため、タイムスタンプの圧縮に適しているのです。XOR圧縮を適用することで、プロファイルの長期的な保存が現実的になります。

これらの技術は、大規模なプロファイルデータを扱う上で重要な役割を果たします。列指向ストレージを活用することで、開発者は膨大なプロファイルを効率的に保存し、高速にクエリを実行できるようになります。XOR圧縮は、ストレージコストの削減に貢献し、長期的なプロファイルの保持を可能にします。

ただし、著者も指摘するように、プロファイルデータの保存と分析には、まだ多くの課題が残されています。特に、プロファイルに対する表現力豊かなクエリ言語の確立は、喫緊の課題だと言えます。Parcaのラベルベースのクエリ言語やPyroscopeのFlameQLなど、各ツールが独自のアプローチを取っていますが、業界全体で共通の標準が求められています。

加えて、プロファイルデータと他のテレメトリデータとの相関分析も、重要な研究テーマです。分散トレースやメトリクスとプロファイルを組み合わせることで、より総合的なパフォーマンス分析が可能になるはずです。しかし、現状では、これらのデータを統合的に扱うための仕組みが十分に確立されているとは言えません。

Continuous profilingの本格的な実践には、これらの課題を着実に解決していく必要があります。列指向ストレージやXOR圧縮といった要素技術を活用しつつ、クエリ言語の標準化や、テレメトリデータ間の相関分析手法の確立に取り組むことが求められます。著者が強調するように、オープンスタンダードの採用と、コミュニティ全体での知見の共有が、Continuous profilingの発展に欠かせないのです。

あわせて6本にしてみる...

本章では、Continuous profilingを支える基盤技術と、その実践に向けた課題について深く掘り下げていました。pprofやFlame graph、eBPFといった要素技術は、Continuous profilingの中核を成すものであり、開発者がその仕組みを理解することは極めて重要です。また、列指向ストレージやXOR圧縮といった手法は、大規模なプロファイルデータを扱う上で欠かせない存在だと言えるでしょう。

一方で、クエリ言語の標準化や、テレメトリデータ間の相関分析など、Continuous profilingの実践には克服すべき課題が山積みです。これらの課題に正面から向き合い、地道な改善を積み重ねていくことが、私たち開発者に求められています。

オープンスタンダードの採用と、知見の共有。それが、Continuous profiling、ひいてはDeveloper observabilityを発展させるための鍵だと、私は確信しています。 一人一人の開発者が自らの経験を持ち寄り、ベストプラクティスを編み出していく。そのような協調的な取り組みこそが、Developer observabilityの真の力を引き出すのだと思います。

Jaeger の作者で OpenTelemetry の共同創始者でもある Yuri Shkuro の TEMPLE: six pillars of telemetry ではObservability をTraces,Events,Metrics,Profiles,Logs,Exceptions で6 本柱としてクラウドネイティブなシステムの観測性に役立つと主張している。このような考えもあることを知っておくと良いかもです。

medium.com

10 Observability In Action

SLOでサービスの信頼性を定量化し、顧客満足度を高める

本書「Observability In Action」の第10章「Service level objectives」では、サービス品質の定量化とその自動化に不可欠なサービスレベル目標(SLO)について詳しく解説されています。著者は、信頼性に関する規制が今後セキュリティと同様に重要になると指摘し、SLOを用いてサービスの信頼性を測定・報告することが、金融、通信、航空などの業界で注目を集めていると述べています。

SLOは、サービス提供者と消費者の間で交わされるサービスレベルアグリーメントSLA)を定量化し、自動化するための重要な手段です。SLAで約束した内容を数値化したものがSLOであり、そのSLOの達成度を実際に測定するための指標がサービスレベルインジケータ(SLI)です。つまり、SLIで測定し、SLOで目標を定め、SLAで契約を交わす、という関係になります。

Figure 10.1 Interaction and dependencies between SLAs, SLOs, and SLIs より引用

本章では、SLOの対象となるサービスの種類として、同期型、非同期型、特殊型の3つが挙げられています。同期型サービスはリクエスト-レスポンス型のWebサービスや、RPCベースのシステムが該当します。非同期型サービスは、メッセージキューやPub/Subシステムなどが含まれます。特殊型サービスには、バッチジョブ、ストレージ、データベースなどが含まれます。それぞれのサービス特性に応じて、適切なSLIを設定する必要があります。

SLIの具体例としては、サービスの可用性、エラー率、レイテンシ、スループットなどが挙げられています。これらの指標をもとに、サービスの品質を定量的に評価し、改善のための目標(SLO)を設定します。例えば、「99.9%の可用性を維持する」「エラー率を0.1%以下に抑える」といったSLOを定めることで、サービス品質の向上を図ることができます。

SLOを設定する際は、可用性と速度のバランスを考慮する必要があります。可用性を上げるためには変更を控えめにする必要がありますが、それでは新機能の追加が滞ってしまいます。逆に、変更を頻繁に行えば、可用性が下がるリスクがあります。サービスの特性に応じて、適切なSLOを設定することが重要だと著者は指摘しています。

本章ではまた、PrometheusをベースとしたオープンソースのSLOツールであるPyrraとSlothについて詳しく解説されています。これらのツールを使うことで、PrometheusのメトリクスをSLIとして扱い、SLOの達成状況を容易に可視化できます。

PyrraはPrometheusのレコーディングルールを生成することでSLOを実装します。ServiceLevelObjectiveリソースを定義すると、それに対応するPrometheusのルールが自動生成されます。一方、SlothはPrometheusのルールグループを生成し、SLIやエラーバジェットの計算を行います。どちらのツールもSLOの実装を大幅に簡略化してくれます。

著者はまた、SLOの商用ソリューションについても言及しています。Nobl9、Datadog、Honeycomb、Dynatraceなど、多くのベンダーがSLOの機能を提供し始めていると指摘しています。特にNobl9は、SLOに特化した包括的なソリューションを提供していると紹介されています。

最後に著者は、SLOを定義する際にはOpenSLOなどのオープンスタンダードを活用すべきだと強調しています。ベンダーロックインを避け、相互運用性を確保するためにも、オープンな仕様に準拠することが重要だと述べています。

SLOの実装と運用における留意点

本章では、SLOの実装と運用に関する具体的な留意点についても言及されていました。

まず、SLOの設定には、サービスの利用者と提供者の間での合意形成が不可欠です。著者は、営業担当者、プロダクトオーナー、エンジニアリングチームが連携し、サービスの特性に応じた適切なSLOを定義すべきだと述べています。その際、エラーの許容範囲や、SLOの対象期間などを明確にすることが重要です。

SLOの達成度を測定するためのSLIの設定も、慎重に行う必要があります。SLIは、サービスの品質を数値化するための指標であり、サービスの種類によって適切なものを選ぶ必要があります。著者は、REDメソッド(Rate、Errors、Duration)など、SLIの選定に関する参考資料を紹介しています。

SLOの運用においては、エラーバジェットの管理が鍵を握ります。エラーバジェットとは、SLOを達成するために許容されるエラーの範囲のことです。エラーバジェットを適切に設定し、モニタリングすることで、SLOの違反を未然に防ぐことができます。エラーバジェットの消費速度(バーンレート)を追跡することも、SLOの管理に役立ちます。

本章で紹介されたPyrraやSlothなどのSLOツールを活用することで、SLOの実装と運用を大幅に効率化できます。これらのツールは、PrometheusのメトリクスをSLIとして扱い、SLOのモニタリングとアラートの設定を容易にしてくれます。ただし、ツールの選定には注意が必要です。機能、性能、価格などを総合的に評価し、自社のニーズに合ったものを選ぶことが重要です。

SLOの導入には、組織文化の変革も欠かせません。サービスの品質を定量的に評価し、継続的に改善していくためには、開発者、運用者、ビジネス関係者が一丸となって取り組む必要があります。SLOを中心とした品質管理のプラクティスを組織全体に浸透させ、データドリブンな意思決定を促進することが求められます。

サービスの継続的な改善の為のSLO

本章では、サービス品質の定量化と自動化に不可欠なSLOについて、詳細に解説されていました。SLOは、SLAで約束したサービス品質を数値化し、SLIで測定するための重要な手段です。サービスの種類に応じて適切なSLIを選定し、SLOを設定することで、サービスの継続的な改善が可能になります。

SLOの実装には、PyrraやSlothなどのオープンソースツールが役立ちます。これらのツールを活用することで、PrometheusのメトリクスをSLIとして扱い、SLOのモニタリングを容易に行えます。一方、Nobl9やDatadogなどの商用ソリューションも、SLOの管理に強力な機能を提供しています。

github.com

syu-m-5151.hatenablog.com

SLOの運用では、エラーバジェットの管理が鍵を握ります。サービスの品質を維持しつつ、変更を加速するためには、適切なエラーバジェットの設定と消費速度の追跡が欠かせません。また、SLOの導入には組織文化の変革も必要です。サービス品質の定量的な評価と継続的な改善を、組織全体の習慣とすることが重要です。

SLOは、単なる技術的な指標ではありません。それは、サービス提供者と消費者の間の信頼関係を築くための重要な手段でもあります。SLOを導入することで、サービスの品質に対する説明責任を果たし、ユーザーの満足度を高めることができるのです。

本章を通して、SLOの重要性と実践的な手法について理解を深めることができました。測定できないものは改善できないと言われます。サービスの品質を定量化し、データに基づいて改善を進めていくこと。それがSLOの本質であり、私たちに求められる姿勢だと感じました。

皆さんの組織では、SLOをどのように活用されていますか?PyrraやSlothなどのツールの利用経験や、SLOの運用で得られた知見などがあれば、ぜひ共有いただきたいと思います。SLOを通じて、サービスの品質と信頼性を高めていくために、私たちにできることは何でしょうか。

サービスの信頼性を定量化し、顧客の期待に応えていく。そのためのアプローチとして、SLOは大きな可能性を秘めています。本章で得られた知見を活かし、SLOの実践を通じて、より信頼性の高いサービスを提供していきたいと思います。

11 Signal correlation

シグナル相関で複雑なシステムの動作を俯瞰的に理解する

本書「Observability In Action」の最終章「Signal correlation」では、複数のオブザーバビリティシグナルを関連付けることで、クラウドネイティブシステムの動作をより深く理解する方法が解説されています。著者は、ログ、メトリクス、トレース、プロファイルといった個々のシグナルだけでは、システムの全体像を把握するのに十分ではないと指摘しています。シグナル相関は、異なるシグナルタイプを結び付けることで、より迅速かつ正確に有用な洞察を得るためのメタデータ主導のプロセスだと定義されています。

マイクロサービスアーキテクチャを採用する現代のシステムは、多数のサービスが連携して一つのリクエストを処理します。そのため、障害やパフォーマンスの問題が発生した際に、どのサービスが原因となっているのかを特定するのが難しくなります。シグナル相関は、インシデント対応、根本原因分析、サービスの性能改善など、様々な場面で威力を発揮します。メトリクスからトレースへ、トレースからログへ、といったように、複数のシグナルを行き来しながら、問題の全容を明らかにできるのです。

本章では、シグナル相関の基本概念として、相関スタックが紹介されています。これは、計装層、バックエンド層、フロントエンド層から構成され、相関を実現するための階層的な仕組みを表しています。

Figure 11.1 The correlation stack より引用

計装層では、アプリケーションコードとテレメトリエージェントが、テレメトリデータを生成し、メタデータで enrichment を行います。バックエンド層では、収集されたテレメトリデータがメタデータとともに保存され、相関のためのクエリに応える役割を担います。そして、フロントエンド層で、ユーザーがシグナル間を自在に行き来しながら、システムの動作を探索できるようになります。

特に、OpenTelemetryの果たす役割の大きさが強調されています。OpenTelemetryは、セマンティック規約を通じて、リソース属性やシグナル属性といったメタデータを標準化します。これにより、ベンダーに依存しない形で、シグナル間の相関を自動化できるようになります。OpenTelemetryのリソース属性を使えば、Kubernetesのノードや、その上で動作するアプリケーションを一意に識別できます。また、シグナル属性によって、HTTPリクエストやRPCコールなど、個々のシグナルにも豊富なメタデータを付与できるのです。

また、著者は相関パスという概念を導入し、あるシグナルタイプから別のシグナルタイプへの遷移を表現しています。

Table 11.1 Overview of signal correlations より引用

トレースからメトリクスへ、メトリクスからログへ、ログからトレースへ、といったように、様々な組み合わせが考えられます。それぞれの遷移では、関連する情報が引き継がれ、より広い文脈でシステムの動作を理解できるようになります。

例えば、トレースからメトリクスへの相関では、トレースが表す分散トランザクションから、レイテンシーや、エラー率などの代表的なメトリクスを導き出せます。逆に、メトリクスからトレースへの相関では、異常な振る舞いを示すメトリクスから、その原因となっているトレースに迫ることができるでしょう。

ログとトレースの相関も、非常に有用です。あるサービスのログから、そのサービスが関与するトレースを特定したり、トレースに含まれる各サービスのログを収集したりできます。これにより、分散トランザクションの流れと、各時点で記録されたイベントを突き合わせながら、問題の原因を追跡できるようになります。

本章では、このようなシグナル相関の概念を、様々な角度から掘り下げています。相関を実現するためのメタデータの標準化、相関パスの種類と活用方法、OpenTelemetryを中心とするオープンな技術スタックなど、相関に関する重要なポイントが網羅的に解説されていました。

OpenTelemetry、Jaeger、Grafanaを使ったメトリクスとトレースの相関

本章では、メトリクスとトレースの相関を実現する具体的な方法として、OpenTelemetry、Jaeger、Grafanaを使った例が紹介されています。

サンプルアプリケーションは、OpenTelemetryを使って計装され、トレースを生成します。同時に、Prometheus形式のメトリクスにトレースIDを埋め込むことで、エグゼンプラ(exemplars)を実現しています。OpenTelemetryコレクタは、トレースをJaegerに、メトリクスをPrometheusに転送します。

コード例を見ると、OpenTelemetryのGoライブラリを使って、メトリクスの各ポイントにトレースIDをラベルとして埋め込んでいます。これがエグゼンプラの肝となる部分です。メトリクスを公開する際には、Prometheusの HTTP ハンドラを使い、レスポンスフォーマットとして OpenMetrics を指定しています。

OpenTelemetryコレクタの設定では、Prometheusエクスポータと Jaeger エクスポータを使って、それぞれのバックエンドにデータを送信しています。Prometheusエクスポータでは、enable_open_metrics オプションを有効にすることで、エグゼンプラのサポートが有効になります。

実際にエグゼンプラがどのように埋め込まれているかは、curl コマンドで /metrics エンドポイントにアクセスすることで確認できます。traceID というラベルに、トレースIDが格納されているのが分かります。

Grafanaのダッシュボードでは、メトリクスのグラフ上に小さな点として表示されるエグゼンプラをクリックすることで、該当するトレースにジャンプできます。これにより、メトリクスの異常を発見した際に、すぐにトレースを確認し、問題の原因を特定できるようになります。

Figure 11.2 Screenshot of the Grafana dashboard with exemplars (the small dots at the bottom) for the echo service より引用

Figure 11.3 Screenshot of the Jaeger view for the echo service, focusing on the error span representing a 500 response

このように、オープンソースツールを組み合わせることで、シグナル相関を比較的簡単に実現できることが示されています。各ツールが担う役割を理解し、適切に設定することが重要だと感じました。特に、OpenTelemetryがデータ収集の中心となり、Jaegerがトレースの保存と可視化を、Prometheusがメトリクスの保存と集計を、そしてGrafanaが相関の UI を提供するという、それぞれの得意分野を活かした構成が印象的でした。

もちろん、本格的な運用のためには、データ量の増大への対応や、セキュリティの確保など、さらなる検討が必要でしょう。しかし、本章の例は、シグナル相関を実践するための第一歩として、大いに参考になると感じました。

シグナル相関の実装における課題と対策

本章では、シグナル相関の実装における課題についても言及されています。

まず、標準化の欠如が挙げられています。APMやモニタリングツールごとに、シグナルのフォーマットや用語が異なるため、システム間で相関を行うのが難しくなります。これに対しては、OpenTelemetryのような標準化されたフレームワークを採用することが有効だと指摘されています。OpenTelemetryは、ベンダー中立なオープンスタンダードであり、多くのプログラミング言語フレームワークをサポートしています。これにより、様々なシステムから一貫性のあるテレメトリデータを収集できるようになります。

次に、メタデータの不足が課題として挙げられています。相関を実現するには、リソースや環境に関する豊富なメタデータが必要ですが、既存のシステムではそれが十分に提供されていないことが多いのです。特に、レガシーなアプリケーションや、サードパーティAPIを利用している場合、メタデータの取得が困難を極めることがあります。ここでも、OpenTelemetryのセマンティック規約に従うことで、メタデータの自動付与が可能になります。ただし、完全な自動化は難しく、場合によってはカスタムの計装が必要になるでしょう。

シグナルのボリューム、カーディナリティ、サンプリングも、相関の実装を難しくする要因です。大量のデータを処理するために、適切なインデックス設計や集計、フィルタリングが欠かせません。特に、ログデータは非構造化データであるため、関連する情報を抽出するのが一苦労です。また、メトリクスの次元が増えすぎると、カーディナリティ爆発を引き起こし、クエリのパフォーマンスが大幅に低下してしまいます。トレースのサンプリングは、データ量を抑えるための有効な手段ですが、重要なスパンが欠落してしまうリスクもあります。

これらの課題に対しては、適切なアーキテクチャの選択と、きめ細かなチューニングが求められます。例えば、ログデータの処理には、Elasticsearchなどの全文検索エンジンや、FluentdやLogstashなどのログ収集基盤が役立ちます。メトリクスのカーディナリティ対策としては、PrometheusのRelabelingやRecordingRuleを活用できるでしょう。トレースのサンプリングでは、重要な操作をあらかじめ識別し、適切なサンプリングレートを設定することが重要です。

データのプライバシーとセキュリティの確保も、重要な課題の一つです。法規制やコンプライアンス要件に従って、個人情報を適切にマスキングしたり、データの取り扱いを制限したりする必要があります。特に、SaaSサービスを利用する場合、データの保存場所や、アクセス制御について、慎重に検討しなければなりません。暗号化やアクセスログの監査など、セキュリティ対策も欠かせません。

最後に、ユーザーエクスペリエンスの向上が求められます。せっかく相関機能を実装しても、使い勝手が悪ければ活用されません。インサイトを得やすいUIの設計や、エンドツーエンドでの一貫したサポートが重要だと指摘されています。例えば、メトリクスの異常検知から、関連するトレースやログへの seamless なナビゲーションができれば、問題の調査が大幅に効率化できるでしょう。Exploratoryなデータ分析をサポートするためには、データのクエリ性や、ビジュアライゼーションの柔軟性も欠かせません。

これらの課題は、一朝一夕には解決できないかもしれません。しかし、シグナル相関の重要性を認識し、地道な改善を積み重ねていくことが大切です。特に、OpenTelemetryを中心とするオープンソースの活用と、コミュニティでの知見共有が、課題の克服に大きく役立つはずです。

将来に向けたシグナル相関の可能性

本章のエッセンスは、シグナル相関がオブザーバビリティの真価を引き出すための鍵だということだと思います。複雑化するシステムの動作を理解し、問題の迅速な特定と解決を実現するには、複数のシグナルを組み合わせて分析する必要があります。OpenTelemetryを活用することで、ベンダーロックインを回避しつつ、メタデータ主導の自動化された相関が可能になるでしょう。

一方で、相関の実装には多くの課題が立ちはだかります。データのボリューム、カーディナリティ、プライバシーなど、技術的にも運用的にも乗り越えるべきハードルは少なくありません。しかし、著者が強調するように、これらの課題に真正面から向き合い、地道な改善を重ねていくことが重要です。

シグナル相関は、オブザーバビリティの究極の目標とも言えます。全てのシグナルを横断的に分析し、システム全体の動作を俯瞰的に把握する。そこから得られる洞察は、開発者の生産性向上だけでなく、ビジネス上の意思決定にも大きな価値をもたらすはずです。

セキュリティの分野でも、シグナル相関の重要性が増しています。複数のログソースを相関させることで、不正アクセスや情報漏洩の兆候をいち早く検知できます。また、トレースデータとの相関により、脆弱性の原因となるコードを特定することも可能になるでしょう。セキュリティインシデントの防止と、影響範囲の特定に、シグナル相関が大きく貢献する可能性があります。

さらに、AIOpsの文脈でも、シグナル相関への期待が高まっています。機械学習ビッグデータ分析と組み合わせることで、システムの異常をリアルタイムに検知し、自動的に対処するような仕組みが実現できるかもしれません。複雑さを増すシステムの運用を、人間の手に頼らずに自動化していくために、シグナル相関が重要な基盤となるはずです。

クラウドネイティブ時代のシステムは、ますます分散化・動的化が進んでいくでしょう。コンテナやサーバーレス、マイクロサービスなど、新しいアーキテクチャが次々と登場する中で、オブザーバビリティの重要性はこれまで以上に高まっています。その中で、シグナル相関は、システムの可視性と制御可能性を飛躍的に向上させる、強力な武器になり得ます。

本章を通して、シグナル相関の重要性と実践的な手法について理解を深めることができました。OpenTelemetryを中心とするオープンな標準の採用と、コミュニティ全体での知見の共有が、相関技術の発展には欠かせません。課題を一つ一つ克服しながら、より高度な相関の実現を目指していきたいと思います。

皆さんの組織では、シグナル相関にどのように取り組まれていますか?OpenTelemetryの活用状況や、相関分析から得られた知見など、ぜひ共有いただければと思います。

シグナル相関は、オブザーバビリティ分野における次のブレークスルーになるかもしれません。 複数のシグナルを行き来しながら、システムの本質的な理解に迫っていく。そのためのデータ基盤とスキルを獲得することが、私たちに求められているのではないでしょうか。

冒頭でも述べたように、単一のシグナルだけでは、もはやシステムの全容を把握することはできません。ログ、メトリクス、トレース、そしてプロファイル。これらの多様なシグナルを縦横無尽に相関させる力こそが、複雑さに立ち向かうための何よりの武器となるはずです。

本書のラストを飾るに相応しい、示唆に富んだ一章でした。ここで得られた学びを胸に、オブザーバビリティのさらなる高みを目指して精進したいと思います。シグナル相関の可能性を追求し、より俊敏で、よりレジリエントなシステムを作り上げていく。それが、私たちソフトウェアエンジニアとSREに託されたミッションなのだと、改めて感じた次第です。

さいごに

本書「Cloud Observability in Action」を通じて、クラウドネイティブ時代におけるオブザーバビリティの重要性と、その実現に向けた具体的な方法論を学ぶことができ視座を得られました。

著者が一貫して訴えかけているのは、オブザーバビリティがツールの導入だけで達成できるものではない、ということです。ログ、メトリクス、トレース、プロファイルなど、様々なシグナルを適切に収集・分析するための技術的な基盤は不可欠ですが、それ以上に重要なのは、オブザーバビリティの文化を組織全体に根付かせ、データドリブンな意思決定を日常的に実践していくことだと説いています。 また、オープンスタンダードとオープンソースソフトウェアの活用が強く推奨されています。ベンダーロックインを避け、持続可能なイノベーションを実現するために、OpenTelemetryに代表されるようなオープンな標準や、コミュニティ主導のオープンソースプロジェクトが果たす役割の大きさを再認識させられました。

本書の内容を実践するのは容易ではありませんが、その努力は決して無駄にはならないはずです。オブザーバビリティの向上は、システムの信頼性と俊敏性を高めるだけでなく、ビジネスの成功とも直結するからです。

本書で得られた知見を咀嚼し、行動に移していくこと。それが、著者のメッセージを真に理解し、オブザーバビリティの価値を自らの組織にもたらすための鍵となるでしょう。

クラウドの時代において、オブザーバビリティは「あったら良いもの」ではなく「なくてはならないもの」になりつつあります。本書はその重要性を説き、実践への道筋を示してくれる、頼もしい道しるべだと言えます。

みなさん、最後まで読んでくれて本当にありがとうございます。途中で挫折せずに付き合ってくれたことに感謝しています。 読者になってくれたら更に感謝です。Xまでフォロワーしてくれたら泣いているかもしれません。

参考資料




以上の内容はhttps://syu-m-5151.hatenablog.com/entry/2024/05/10/121047より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14