序章

システムとインフラストラクチャの監視は、あらゆる規模の運用チームの中心的な責任です。 業界は、サーバーの監視、重要なデータの収集、さまざまな環境でのインシデントや状況の変化への対応に役立つ多くの戦略とツールを共同で開発してきました。 ただし、ソフトウェアの方法論とインフラストラクチャの設計が進化するにつれて、監視は新しい課題に対応し、比較的なじみのない領域で洞察を提供するように適応する必要があります。

このシリーズのこれまでのところ、メトリック、監視、およびアラートとはと、優れた監視システムの品質について説明してきました。 インフラストラクチャとアプリケーションからのメトリックの収集と、インフラストラクチャ全体で監視する重要な信号について説明しました。 前回のガイドでは、個々のコンポーネントと優れたアラート設計の品質を理解することにより、メトリックとアラートを実践する方法について説明しました。

このガイドでは、高度に分散されたアーキテクチャとマイクロサービスのモニタリングとメトリック収集がどのように変化するかを見ていきます。 クラウドコンピューティング、ビッグデータクラスター、インスタンスオーケストレーションレイヤーの人気の高まりにより、運用の専門家は、大規模な監視を設計する方法を再考し、より優れたインストルメンテーションで固有の問題に取り組む必要があります。 展開の新しいモデルが異なる理由と、これらの新しい要求を満たすために使用できる戦略について説明します。

高度に分散されたアーキテクチャはどのような課題を生み出しますか?

監視するシステムをモデル化してミラーリングするために、監視インフラストラクチャは常にある程度分散されています。 ただし、マイクロサービス、コンテナー、交換可能なエフェメラルコンピューティングインスタンスを中心とした設計など、多くの最新の開発手法により、監視環境が劇的に変化しました。 多くの場合、これらの進歩の核となる機能は、監視を最も困難にする要因そのものです。 これらが従来の環境とどのように異なるか、そしてそれがモニタリングにどのように影響するかを見てみましょう。

作業は基礎となるリソースから切り離されています

多くのシステムの動作における最も基本的な変更のいくつかは、ソフトウェアを設計できる新しい抽象化レイヤーの爆発的な増加によるものです。 コンテナテクノロジーは、展開されたソフトウェアと基盤となるオペレーティングシステムの関係を変えました。 コンテナにデプロイされたアプリケーションは、従来の方法でデプロイされたアプリケーションとは、外部、他のプログラム、およびホストオペレーティングシステムとの関係が異なります。 カーネルとネットワークの抽象化により、チェックするレイヤーに応じて、オペレーティング環境の理解が異なる可能性があります。

このレベルの抽象化は、一貫したデプロイメント戦略を作成し、ホスト間での作業の移行を容易にし、開発者がアプリケーションのランタイム環境を厳密に制御できるようにすることで、多くの点で非常に役立ちます。 ただし、これらの新機能は、複雑さが増し、各プロセスを動かすリソースとの関係がより遠くなるという犠牲を払って提供されます。

ネットワークベースの通信の増加

新しいパラダイムの共通点の1つは、タスクを調整および実行するための内部ネットワーク通信への依存度が高まっていることです。 以前は単一のアプリケーションのドメインであったものが、情報を調整および共有する必要のある多くのコンポーネントに分散される可能性があります。 これには、通信インフラストラクチャと監視に関していくつかの影響があります。

まず、これらのモデルは小規模な個別のサービス間の通信に基づいて構築されているため、ネットワークの健全性がこれまで以上に重要になります。 従来のよりモノリシックなアーキテクチャでは、タスクの調整、情報の共有、および結果の整理は、通常のプログラミングロジックを使用するアプリケーション内で、または比較的少量の外部通信を介して主に達成されていました。 対照的に、高度に分散されたアプリケーションの論理フローは、ネットワークを使用して同期し、ピアの状態をチェックし、情報を渡します。 ネットワークの状態とパフォーマンスは、以前よりも多くの機能に直接影響します。つまり、正しい動作を保証するには、より集中的な監視が必要です。

ネットワークはこれまで以上に重要になっていますが、参加者の数が増え、個々の通信回線が存在するため、ネットワークを効果的に監視する機能はますます困難になっています。 いくつかのアプリケーション間の相互作用を追跡する代わりに、同じ機能を確保するために、数十、数百、または数千の異なるポイント間の正しい通信が必要になります。 複雑さの考慮に加えて、トラフィック量の増加は、利用可能なネットワークリソースに追加の負担をかけ、信頼性の高い監視の必要性をさらに悪化させます。

より高度に分割された機能性と責任

上記で、現代のアーキテクチャが作業と機能を多くのより小さな個別のコンポーネント間で分割する傾向を通過させることについて述べました。 これらの設計は、明快さとわかりやすさを特に価値のあるものにしますが、ますますとらえどころのないものにするため、監視環境に直接影響を与える可能性があります。

良好な動作順序を確保するには、より堅牢なツールと計装が必要です。 ただし、特定のタスクを完了する責任は断片化され、異なるワーカー間(場合によっては多くの異なる物理ホスト上)に分割されるため、パフォーマンスの問題やエラーの責任がどこにあるかを理解するのは難しい場合があります。 数十のコンポーネントに触れるリクエストと作業単位(その多くは候補のプールから選択されます)により、従来のメカニズムを使用したリクエストパスの視覚化や根本原因分析が非現実的になる可能性があります。

短命で一時的なユニット

従来の監視を適応させる上でのさらなる苦労は、短命または一時的なユニットを賢明に追跡することです。 関心のある単位がクラウドコンピューティングインスタンス、コンテナインスタンス、またはその他の抽象化であるかどうかにかかわらず、これらのコンポーネントは、従来の監視ソフトウェアによって行われた仮定の一部に違反することがよくあります。

たとえば、問題のあるダウンしたノードと、スケールダウンのために意図的に破棄されたインスタンスを区別するために、監視システムは、以前に必要だったよりも、プロビジョニングおよび管理レイヤーをより深く理解している必要があります。 最近の多くのシステムでは、これらのイベントが頻繁に発生するため、毎回手動で監視ドメインを調整することは現実的ではありません。 これらの設計により、展開環境はより急速に変化するため、監視レイヤーは、価値を維持するために新しい戦略を採用する必要があります。

多くのシステムが直面しなければならない1つの質問は、破壊されたインスタンスからのデータをどうするかです。 変化する要求に対応するためにワークユニットを迅速にプロビジョニングおよびプロビジョニング解除することもできますが、古いインスタンスに関連するデータをどのように処理するかを決定する必要があります。 基盤となるワーカーが利用できなくなったからといって、データがすぐにその価値を失うとは限りません。 毎日数百または数千のノードが出入りする可能性がある場合、短命のインスタンスの断片化されたデータからシステムの全体的な運用状態についてのナラティブを最適に構築する方法を知るのは難しい場合があります。

モニタリングをスケーリングするにはどのような変更が必要ですか?

分散アーキテクチャとマイクロサービスに固有の課題のいくつかを特定したので、これらの現実の中で監視システムがどのように機能するかについて話し合うことができます。 ソリューションの中には、さまざまなタイプのメトリックについて最も価値のあるものを再評価して分離するものもあれば、それらが存在する環境を理解するための新しいツールや新しい方法を含むものもあります。

粒度とサンプリング

サービス数の増加による総トラフィック量の増加は、考えるのが最も簡単な問題の1つです。 新しいアーキテクチャによって引き起こされる転送数の急増を超えて、監視アクティビティ自体がネットワークをダウンさせ、ホストリソースを盗み始める可能性があります。 ボリュームの増加に最適に対処するには、監視インフラストラクチャをスケールアウトするか、使用するデータの解像度を下げることができます。 どちらのアプローチも検討する価値がありますが、2番目のアプローチは、より拡張可能で広く役立つソリューションであるため、ここでは2番目のアプローチに焦点を当てます。

データのサンプリングレートを変更すると、システムがホストから収集する必要のあるデータの量を最小限に抑えることができます。 サンプリングは、メトリックコレクションの通常の部分であり、メトリックの新しい値を要求する頻度を表します。 サンプリング間隔を長くすると、処理する必要のあるデータの量が減るだけでなく、データの解像度(詳細レベル)も減ります。 注意して最小の有用な解像度を理解する必要がありますが、データ収集率を微調整すると、システムが適切にサービスできる監視クライアントの数に大きな影響を与える可能性があります。

低解像度に起因する情報の損失を減らすための1つのオプションは、同じ頻度でホスト上のデータを収集し続けることですが、ネットワークを介して転送するために、より消化しやすい数にコンパイルします。 個々のコンピューターは、メトリック値を集約して平均化し、要約を監視システムに送信できます。 これにより、多数のデータポイントが引き続き考慮されるため、精度を維持しながらネットワークトラフィックを削減できます。 これは、ネットワークへのデータ収集の影響を減らすのに役立ちますが、それ自体では、ホスト内でこれらの番号を収集することに伴う負担を軽減するのには役立ちません。

複数のユニットから集約されたデータに基づいて意思決定を行う

上記のように、従来のシステムと最新のアーキテクチャの主な違いの1つは、要求の処理に関与するコンポーネントの内訳です。 分散システムとマイクロサービスでは、作業の単位は、ある種のスケジューリングまたはアービトレーションレイヤーを介してワーカーのプールに与えられる可能性がはるかに高くなります。 これは、監視を中心に構築する可能性のある自動化されたプロセスの多くに影響を及ぼします。

交換可能なワーカーのプールを使用する環境では、ヘルスチェックとアラートポリシーが成長して、監視するインフラストラクチャと複雑な関係を持つ可能性があります。 個々の作業者のヘルスチェックは、欠陥のあるユニットを自動的に廃止してリサイクルするのに役立ちます。 ただし、大規模な自動化が実施されている場合は、単一のWebサーバーが大きなプールで障害を起こしてもそれほど重要ではありません。 システムは自己修正して、正常なユニットのみがリクエストを受信するアクティブなプールにあることを確認します。

ホストヘルスチェックは欠陥のあるユニットを検出できますが、プール自体のヘルスチェックがアラートに適しています。 現在のワークロードを満たすプールの機能は、個々のワーカーの機能よりもユーザーエクスペリエンスに大きく影響します。 正常なメンバーの数、プールアグリゲートの待機時間、またはプールエラー率に基づくアラートは、自動的に軽減することがより困難で、ユーザーに影響を与える可能性が高い問題をオペレーターに通知できます。

プロビジョニングレイヤーとの統合

一般に、分散システムの監視レイヤーは、展開環境とプロビジョニングメカニズムをより完全に理解している必要があります。 自動化されたライフサイクル管理は、これらのアーキテクチャに関係する個々のユニットの数のために非常に価値があります。 ユニットが未加工のコンテナー、オーケストレーションフレームワーク内のコンテナー、クラウド環境のコンピューティングノードのいずれであるかに関係なく、ヘルス情報を公開し、イベントをスケーリングして応答するコマンドを受け入れる管理レイヤーが存在します。

プレイ中のピースの数は、統計的に失敗する可能性を高めます。 他のすべての要因が等しい場合、これらの問題に対応して軽減するには、より多くの人間の介入が必要になります。 監視システムは障害とサービスの低下を特定する責任があるため、プラットフォームの制御インターフェイスに接続できれば、これらの問題の大部分を軽減できます。 監視ソフトウェアによってトリガーされる即時の自動応答は、システムの運用状態を維持するのに役立ちます。

監視システムと展開プラットフォームの間のこの緊密な関係は、他のアーキテクチャでは必ずしも必要ではなく、一般的でもありません。 しかし、自動化された分散システムは、事前構成されたルールと監視されたステータスに基づいてスケーリングおよび調整する機能を備えた、自己調整を目的としています。 この場合の監視システムは、環境を制御し、いつアクションを実行するかを決定する上で中心的な役割を果たします。

監視システムがプロビジョニング層の知識を持っている必要があるもう1つの理由は、一時的なインスタンスの副作用に対処するためです。 作業インスタンスで頻繁にターンオーバーが発生する環境では、監視システムは、アクションが意図的であったかどうかを理解するためにサイドチャネルからの情報に依存します。 たとえば、プロビジョナーからAPIイベントを読み取ることができるシステムは、サーバーがオペレーターによって意図的に破壊された場合と、サーバーが突然応答しなくなり、関連するイベントがない場合とでは、異なる反応を示す可能性があります。 これらのイベントを区別できることで、基盤となるインフラストラクチャが頻繁に変更される可能性がある場合でも、監視が有用で正確で信頼できる状態を維持するのに役立ちます。

分散トレース

高度に分散されたワークロードの最も困難な側面の1つは、さまざまなコンポーネント間の相互作用を理解し、根本原因分析を試みる際の責任を分離することです。 1つの要求が数十の小さなプログラムに影響を与えて応答を生成する可能性があるため、ボトルネックやパフォーマンスの変化がどこで発生したかを解釈するのは難しい場合があります。 各コンポーネントがレイテンシーと処理オーバーヘッドにどのように寄与するかについてのより良い情報を提供するために、分散トレースと呼ばれる技術が登場しました。

分散トレースは、インストルメンテーションシステムへのアプローチであり、各コンポーネントにコードを追加して、サービスを通過するときに要求処理を明らかにすることで機能します。 各リクエストには、インフラストラクチャのエッジで一意の識別子が与えられ、タスクがインフラストラクチャを通過するときに渡されます。 次に、各サービスはこのIDを使用して、エラーと、リクエストを最初に確認したときと次のステージに渡したときのタイムスタンプを報告します。 リクエストIDを使用してコンポーネントからのレポートを集約することにより、正確なタイミングデータを含む詳細なパスをインフラストラクチャ全体で追跡できます。

この方法を使用すると、プロセスの各部分に費やされた時間を理解し、遅延の深刻な増加を明確に特定できます。 この追加のインストルメンテーションは、メトリック収集を多数の処理コンポーネントに適応させる方法です。 x軸に時間とともに視覚的にマッピングすると、結果の表示には、さまざまなステージ間の関係、各プロセスの実行時間、および並行して実行する必要のあるイベント間の依存関係が表示されます。 これは、システムを改善する方法と時間がどのように費やされているかを理解するのに非常に役立ちます。

分散システムの運用応答性の向上

分散アーキテクチャが根本原因の分析と運用の明確化を実現するのをどのように困難にするかについて説明しました。 多くの場合、人間が問題に対応して調査する方法を変更することは、これらのあいまいさに対する答えの一部です。 状況を系統的に分析できるように情報を公開するようにツールを設定すると、利用可能なデータの多くのレイヤーを分類するのに役立ちます。 このセクションでは、大規模な分散環境で問題をトラブルシューティングするときに成功するための準備方法について説明します。

すべてのレイヤーで4つのゴールデンシグナルのアラートを設定する

システムの問題に確実に対応できるようにするための最初のステップは、問題がいつ発生しているかを知ることです。 インフラストラクチャとアプリケーションからの指標の収集に関するガイドでは、4つのゴールデンシグナルを紹介しました。これは、GoogleSREチームが追跡するのに最も重要であると特定したモニタリング指標です。 4つの信号は次のとおりです。

  • レイテンシー
  • トラフィック
  • エラー率
  • 飽和

これらは、システムをインストルメント化するときに開始するのに最適な場所ですが、高度に分散されたシステムでは、通常、監視する必要のあるレイヤーの数が増えます。 基盤となるインフラストラクチャ、オーケストレーションプレーン、および作業層はそれぞれ、重要な変更を識別するために設定された思慮深いアラートによる堅牢な監視を必要とします。 アラート条件は、プラットフォームに固有の一時的な要素を説明するために複雑になる可能性があります。

全体像を把握する

システムが異常を識別してスタッフに通知したら、チームはデータの収集を開始する必要があります。 このステップを続行する前に、影響を受けるコンポーネント、インシデントがいつ開始されたか、およびどの特定のアラート条件がトリガーされたかを理解しておく必要があります。

インシデントの範囲を理解し始めるための最も便利な方法は、高レベルから始めることです。 システム全体から情報を収集して一般化するダッシュボードと視覚化を確認することから、調査を開始します。 これは、相関する要因をすばやく特定し、ユーザーが直面する直接的な影響を理解するのに役立ちます。 このプロセス中に、さまざまなコンポーネントやホストからの情報をオーバーレイできるようになります。

この段階の目標は、アイテムの精神的または物理的なインベントリの作成を開始して、より詳細にチェックし、調査の優先順位付けを開始することです。 さまざまなレイヤーを横断する一連の関連する問題を特定できる場合は、最下位レイヤーを優先する必要があります。基本レイヤーを修正すると、多くの場合、より高いレベルで症状が解決されます。 影響を受けるシステムのリストは、後で緩和策が展開されたときに修正を検証する場所の非公式のチェックリストとして機能します。

特定の問題のドリルダウン

インシデントの妥当な高レベルのビューがあると感じたら、優先度の高い順にリストのコンポーネントとシステムに詳細をドリルダウンします。 個々のユニットに関する詳細なメトリックは、最も責任の低いリソースへの障害のルートを追跡するのに役立ちます。 よりきめ細かいダッシュボードとログエントリを確認しながら、影響を受けるコンポーネントのリストを参照して、副作用がシステム全体にどのように伝播しているかをさらに理解してください。 マイクロサービスでは、相互に依存するコンポーネントの数が多いため、問題が他のサービスに頻繁に波及します。

この段階では、最初のインシデントの原因となったサービス、コンポーネント、またはシステムを分離し、発生している特定の問題を特定することに重点を置いています。 これは、新しくデプロイされたコード、障害のある物理インフラストラクチャ、オーケストレーションレイヤーの間違いやバグ、またはシステムが適切に処理できなかったワークロードの変更である可能性があります。 何が起こっているのか、そしてその理由を診断することで、問題を軽減し、運用状態を回復する方法を見つけることができます。 この問題を解決することで他のシステムで報告された問題がどの程度修正されるかを理解すると、軽減タスクの優先順位付けを継続するのに役立ちます。

問題の解決の軽減

詳細が特定されたら、問題の解決または軽減に取り組むことができます。 多くの場合、より多くのリソースを提供するか、ロールバックするか、トラフィックを別の実装に再ルーティングすることで、サービスを復元するための明白で迅速な方法があります。 これらのシナリオでは、解決は3つのフェーズに分けられます。

  • 問題を回避し、即時サービスを復元するためのアクションの実行
  • 根本的な問題を解決して、完全な機能と運用状態を回復します
  • 失敗の理由を完全に評価し、再発を防ぐために長期的な修正を実装する

多くの分散システムでは、冗長性と高可用性コンポーネントにより、サービスが迅速に復元されますが、冗長性を復元したり、システムを劣化状態から解放したりするには、バックグラウンドでさらに多くの作業が必要になる場合があります。 最初の緩和策がカスケードサービスの問題を解決するかどうかを判断するための測定スティックとして、以前にコンパイルされた影響を受けるコンポーネントのリストを使用する必要があります。 監視システムの高度化に伴い、プロビジョニングレイヤーにコマンドを送信して、障害が発生したユニットの新しいインスタンスを起動したり、誤動作しているユニットをサイクルアウトしたりすることで、これらのより完全なリカバリプロセスの一部を自動化できる場合もあります。

最初の2つのフェーズで可能な自動化を考えると、運用チームにとって最も重要な作業は、多くの場合、イベントの根本原因を理解することです。 このプロセスから収集された知識を使用して、将来の発生を予測し、システムの反応をさらに自動化するのに役立つ新しいトリガーとポリシーを開発できます。 監視ソフトウェアは、多くの場合、新たに発見された障害シナリオから保護するために、各インシデントに対応して新しい機能を取得します。 分散システムの場合、分散トレース、ログエントリ、時系列の視覚化、および最近の展開などのイベントは、イベントのシーケンスを再構築し、ソフトウェアと人間のプロセスを改善できる場所を特定するのに役立ちます。

大規模な分散システムに固有の特定の複雑さのため、重要なイベントの解決プロセスを、システムを学習して微調整する機会として扱うことが重要です。 関連する個別のコンポーネントと通信パスの数により、複雑さの管理に役立つ自動化とツールに大きく依存することになります。 これらのコンポーネントの応答メカニズムとルールセット(およびチームが遵守する運用ポリシー)に新しいレッスンをエンコードすることは、監視システムがチームの管理フットプリントを抑えるための最良の方法です。

結論

このガイドでは、分散アーキテクチャとマイクロサービス設計が監視および可視性ソフトウェアにもたらす可能性のある特定の課題のいくつかについて説明しました。 システムを構築する最新の方法は、従来の方法のいくつかの仮定を破り、新しい構成環境を処理するためにさまざまなアプローチを必要とします。 モノリシックシステムから、エフェメラル、クラウド、またはコンテナベースのワーカーと大量のネットワーク調整にますます依存するシステムに移行する際に考慮する必要のある調整について検討しました。 その後、システムアーキテクチャがインシデントへの対応と解決に影響を与える可能性のあるいくつかの方法について説明しました。