Monitoring in the time of Cloud Native — Part 5

クラウドネイティブにおけるモニタリング — Part 5

gavin.zhou
9 min readSep 17, 2019

今回からクラウドネイティブにおけるモニタリングに関しての記事をご紹介していきたいと思います。

とても長い文章になるので、いくつかに分けて投稿していきたいと思います。

今回は可観測性の3本柱についてです。

The Three Pillars of Observability

ログ、メトリック、トレースを理解するために、より具体的な例を出しましょう。私たちのシステム、もしくはサブシステムのインフラストラクチャー以下のようだと仮定してみましょう。

Logs

ログは、時間の経過とともに発生した個別のイベントの不変の記録です。イベントはログと比較すると区別されると考える人もいますが、すべての意図と目的において、イベントとログは互換性があると思います。

イベントログは、通常下の3つの形になっています。

  1. Plaintext ― ログの記録は自由形式のテキストになっています。これはまた、ログの一番一般的なフォーマットです。
  2. Structured― 最近はとてもたくさんの人に指示されています。一般的に、JSON形式で出力されるログです。
  3. Binary ―レプリカントや point-in-time (ポイントイン)リカバリに使われる Protobufフォーマット、 MySQL binlogs(バイナリログ)、 tcpdump に対するフロントエンドとして機能するBDSファイヤウォール pf に使われるsystemd の journal ログ、 pflog フォーマットでのログを考えてみてください。

特に、ログは、平均とパーセンタイルが表面化しないロングテールに「十分なコンテキスト」とともに貴重な洞察を提供する際に際立ちます。 上記の例に戻って、これらのさまざまなサービスのすべてがさまざまな精度でログを出力すると仮定します。 一部のサービスは、リクエストごとに他のサービスよりも多くのログ情報を出力する場合があります。 ログだけを見ると、データの状況は次のようになります。

上の図を見てすぐに見て分かるのはデータポイントが大量にあることです。自分たちにとって興味深いものを記録うることは、ものすごく便利です。特にとても詳細な情報を検索するときには特にです。でも単純にこの大量のデータを見るとき、リクエストのライフサイクルが何であるか、リクエストがどのシステムを通過したか、特定のシステムの全体的な状態さえ一目で推測することは不可能です。もちろん、そのデータは豊富ですが、あらなる加工はありません。それ以上はできません。

端的に言えば我々が必要としているものは「情報」なのです。ここでの「情報」の興味深い面というのは、どんな情報を自分たちが求めているか、です。リクエストのライフサイクルに関しての情報が必要ですか?もしくは、特定のサービスのリソースユーティライゼーションについての情報が必要ですか?もしくは特定のホストのヘルスについて?なぜ特定のサービスがクラッシュしたのか、 key-valueストアで配布されたレプリケーションラグについて?最終的に一貫したシステムが収束するまでにかかった時間について?GCポーズについて?その症状について?根本的な原因について?すごくフランクに言ってしまえば、収集できるデータポイントは無限にあります。応じることのできるリクエストも無限にあります。ものすごく些細なものから難しいものまで。

しかし、二つのとても重要な情報は、ライフサイクル全体にわたるリクエストの運命(通常は短命)とシステム全体の運命(リクエストライフサイクルよりも桁違いに長い期間にわたって測定さえるもの)に関係します。 トレースとメトリックの両方が、ログを基に構築された「アブストラクション」であり、2つの直交軸に沿って情報をエンコードします。1つは「要求中心」、もう1つは「システム中心」です。

Traces

トレースは、分散システムを介したエンドツーエンドの要求フローをエンコードする、原因に関連する一連の分散イベントという意味です。 単一のトレースにより、リクエストが通過した「パス」とリクエストの「構造」の両方を可視化できます。 リクエストのパスにより、リクエストのサービスに関係するサービスを理解しやすくなります。トレースの「構造」は、リクエストの実行における非同期の分岐点と影響を理解するのに役立ちます。

マイクロサービス環境でのユーティリティを中心としたトレースに関する議論はありますが、ネットワークやディスクなどのリソースと非自明な方法で相互作用する、またはむしろ競合する、十分に複雑なアプリケーションは、 トレースが提供できるという利点を活用できます。

トレースの背後にある基本的な考え方は簡単です。アプリケーション、プロキシ、フレームワーク、ライブラリ、ミドルウェアなど、リクエストの実行パスにある可能性のある特定のポイントを特定し、これらのポイントを計測して相互に調整します。 これらのポイントは、実行フロー(OSスレッドまたはグリーンスレッド)の分岐、またはライフサイクルの過程で要求が発生する可能性のあるネットワークまたはプロセスの境界を越えたホップまたはファンアウトを表すため、特に重要です。

一般的に、有向非巡回グラフと呼ばれるものですが、そのグラフは「前処理」セマンティクスを使用して因果関係を保持しながら、各レイヤーで行われた作業量を識別するために使用されます。コード内の特定のポイントにインストルメンテーションを追加することで、これが実行されます。リクエストが開始されると、グローバルに固有のIDが割り当てられ、それがリクエストパス全体に伝播されるため、計測の各ポイントはメタデータを挿入または強化してから、リクエストの蛇行するフローの次のホップにIDを渡すことができます。実行フローがこれらのサービスのいずれかでインストルメントされたポイントに達すると、メタデータとともにレコードが出力されます。 これらのレコードは通常、帯域外でコレクターに送信される前にディスクに非同期的に記録され、システムのさまざまな部分から放出されたさまざまなレコードに基づいて実行フローを再構築できます。

この情報を収集し、遡及的な(レトロスペクティブな)分析とトラブルシューティングの因果関係を維持しながら実行のフローを再構築することにより、リクエストのライフサイクルをよりよく理解することができます。一番重要なことは、リクエストのライフサイクル全体を理解することにより、「複数のサービスにまたがるリクエストをデバッグする」ことができ、応答時間またはリソース使用率の増加の原因を特定できます。 そのため、トレースは、システムの「どのコンポーネント」が「なぜ」時々リクエストのライフサイクル中に触れて応答が遅くなるのかを理解するのに役立ちます。

Metrics

メトリックの正式的な定義は:

「特定のプロセスまたはアクティビティに関する情報を提供する一連の数字。」とされています。

メトリックはデータの数値表現であるため、数学的モデリングと予測の力をフル活用して、現在および将来の時間間隔、つまり「時系列」でのシステムのビヘイビアに関する知識を引き出すことができます。 時系列の公式定義は:

「特定の活動に関連する数字のリスト。それは、定期的に記録され、その後調査される。 時系列は、一般的に販売、注文、収入などの調査に使用される。」と定義されています。

メトリックは、時間間隔で測定される単なる「数値」であり、数値はストレージ、処理、圧縮、および取得用に最適化されています。 そのため、メトリックを使用すると、データの保持期間が長くなり、クエリするのが容易になります。これを使用して、ダッシュボードを構築し、履歴のトレンドを反映できます。 さらに、メトリックを使用すると、データの解像度を徐々に低下させることができるため、一定期間が経過すると、データを毎日または毎週のように集約できます。

歴史的な時系列データベースの最大の欠点の1つは、探索的分析やフィルタリングにあまり向いていないメトリックの「識別」です。 階層メトリックモデルと、 Graphite などのシステムのタグまたはラベルの欠如は、この点で特に痛いです。 Prometheus のような最新の監視システムは、メトリック名とラベルと呼ばれる追加のキーと値のペアを使用して、すべての時系列を表します。

これにより、データモデルの高度な「次元性」が可能になります。 メトリックは、メトリック名とラベルの両方を使用して識別されます。 Prometheusのメトリックは変わることがありません。 メトリックの名前を変更したり、ラベルを追加または削除すると、新しい時系列が作成されます。 時系列に格納される実際のデータは「サンプル」と呼ばれ、「float64」値とミリ秒精度のタイムスタンプという2つのコンポーネントで構成されます。

Orangesys.ioでは、kuberneteの運用、DevOps、監視のお手伝いをさせていただいています。ぜひ私たちにおまかせください。

--

--

No responses yet