Monitoring in the time of Cloud Native — Part 6
クラウドネイティブにおけるモニタリング — Part 6
今回からクラウドネイティブにおけるモニタリングに関しての記事をご紹介していきたいと思います。
とても長い文章になるので、いくつかに分けて投稿していきたいと思います。
今回はリソースの使用率、使いやすさ、操作のしやすさ、費用対効果の面でのそれぞれの長所と短所 についてです。
The pros and cons of each in terms of resource utilization, ease of use, ease of operation, and cost effectiveness
リソースの使用率、使いやすさ、操作のしやすさ、費用対効果の面でのそれぞれの長所と短所
3つの基準を3つの基準で評価してから、それぞれの長所を活用した優れた可観測性エクスペリエンスを作成する方法を見てみましょう。
- 生成、インストルメンテーションの簡単さ
- 加工の簡単さ
- クエリ、検索の簡単さ
- 情報の質
- 費用対効果
Logs
ログは、初期処理が含まれていないため、はるかに簡単に生成できます。 それが単なる文字列またはJSONのblobであるという事実により、ログラインの形式で出力するデータを非常に簡単に表現できます。 ほとんどの言語、アプリケーションフレームワーク、およびライブラリには、ロギングのサポートが組み込まれています。 ログラインを追加するのは印刷ステートメントを追加するのと同じくらい簡単なので、ログの計測も簡単です。 また、ログは、検索スペースが単一のサービスに「ローカライズ」されている限り、ドリルダウン分析に適したリッチな「ローカル」コンテキストばかりの非常に詳細な情報を表示するという点でも非常に優れたパフォーマンスを発揮します。
残念ながら、ログの有用性はすぐに終わります。 ログについて説明する他のすべてのことは、大変なだけです。 ログの生成は簡単かもしれませんが、人気のあるさまざまなロギングライブラリのパフォーマンスの特性には、多くの要望があります。 ほとんどのパフォーマンスログライブラリは、割り当てられている場合は非常に少なく、非常に高速です。 ただし、多くの言語およびフレームワークのデフォルトのロギングライブラリは重要な部分ではありません。つまり、ロギングのオーバーヘッドにより、アプリケーション全体が最適なパフォーマンスに影響されやすくなります。 さらに、信頼できるメッセージ配信を保証するために「 RELP 」などのプロトコルを使用しない限り、ログメッセージも失われる可能性があります。 これは、請求または支払いの目的でログデータを使用している場合に特に重要になります。 最後に、ロギングライブラリがログを動的にサンプリングできない限り、ロギングにはアプリケーション全体のパフォーマンスに悪影響を及ぼす可能性があります。 Slackで以下のように言及している方がいました:
【編集】で私が見た面白かったことは、ログがmadのようなAWSのEC2クラシックのパケット割り当てを介して実行されるため、実行中のインスタンスでほとんどのログをオフにするとパフォーマンスがほぼ2倍になることです。 パフォーマンスを制御およびモニタリングしようとすると、パフォーマンスの50%以上が失われることを発見し、興味深く感じました。
処理側では、生のログはほとんどの場合、ElasticsearchやBigQueryなどのデータストアに保存される前に、Logstash、fluentd、Scribe、Hekaなどのツールによって正規化、フィルタリング、処理されます。アプリケーションが大量のログを生成する場合、ログをKafkaなどのブローカーでさらにバッファリングしてから、Logstashで処理できるようにする必要があります。 BigQueryのようなホスト型ソリューションは、制限を超えることはできない割り当てがあります。ストレージの面では、Elasticsearchは素晴らしい検索エンジンかもしれませんが、実行には実際の運用コストがかかります。組織にELKの運用の専門家である運用エンジニアのチームが配置されている場合でも、他の欠点がある可能性があります。適切な事例 — 私の友人の一人が、サービスへのトラフィックが落ちたからではなく、ELKが膨大な量のインデックス付けに追いつかなかったために、Kibanaのグラフで頻繁に急な下り勾配を見る方法について私に話してくれました。 グの取り込み処理がELKの問題ではない場合でも、KibanaのUIの使用方法を完全に理解している人は誰もいません。
ログ管理用のホストされた商用の商品が不足しているわけではありませんが、それらの商品はおそらくその非常識な価格設定で知られています。 多くの組織が、ログ管理について経費のとてもかかる外部委託しています。それはログ管理を社内で運用するのが難しく、高価で壊れやすいことの証です。
ロギングのコストオーバーヘッドの問題に対してしばしば提案される解決策は、実行可能なデータをサンプリングするか、ログに記録することです。 しかし、積極的にサンプリングした場合でも、何が実行可能かを優先的に決定する必要があります。 そのため、「実行可能な」データをログに記録する機能は、実行可能なデータや将来必要になるデータを予測できる機能に完全に依存しています。 システムをより深く把握すると、現在収集されているデータが将来の真の情報源であることが証明できるという事実に基づいた推測を行うことができるかもしれませんが、潜在的にすべてのコードラインが障害になっているため、ログラインのソースになる可能性があります。
Metrics
全体的に、ログに対するメトリックベースのモニタリングの最大の利点は、ログの生成とストレージとは異なり、メトリックの転送とストレージに一定のオーバーヘッドがあるという事実です。 ログとは異なり、メトリックのコストは、ユーザートラフィックやデータの急激な増加を招く可能性のある他のシステムアクティビティのロックステップで増加しません。
つまり、メトリックを使用すると、アプリケーションへのトラフィックが増加しても、ディスクの使用率、処理の複雑さ、視覚化の速度、ログのように運用コストが大幅に増加することはないということです。メトリックのストレージは、キャプチャーされる時系列の数とともに増加します(より多くのホスト/コンテナがスピンアップしたとき、または新しいサービスが追加されたとき、または既存のサービスがさらにインストルメントされたとき)が、UDPパケットを送信するstatsdクライアントとは異なり、メトリックは常に statsdデーモンに記録され(レポートされるトラフィックと比較してstatsdに送信されるメトリックの数が比例して増加します!)、Prometheusのようなシステムのクライアントライブラリは、その過程の中いて時系列のサンプルを集計し、スクレープに成功したPrometheusサーバーに送信します。(数秒に1回発生し、コンフィギュアすることが可能)。
メトリックは、一度収集されると、サンプリング、集計、要約、相関などの数学的、確率的、統計的な変換により柔軟になり、システムの全体的なヘルスの報告により適したものになります。
また、メトリックはトリガーアラートにも適しています。これは、ELKなどの分散システムに対してクエリを実行し、もしアラートがトリガーされる必要がある場合であれば、結果を集約してから決定するよりも、メモリ内の時系列データベースに対してクエリを実行する方がはるかに効率的であるためです。 もちろん、アラートのためにメモリ内の構造化イベントデータのみを厳密にクエリするシステムがあります。これはELKよりも少し安くなる可能性がありますが、オープンソースであったとしても、大規模な分散メモリ内データベースを実行する運用上のオーバーヘッドはありません。 同等に実行可能なアラートを生成するはるかに簡単な方法がある場合、ほとんどの場合、トラブルに見合う価値があります。 メトリックは、システムのパフォーマンスのブラックボックスフロントエンドに似ているため、この情報を提供するのに最適です。
ログとメトリックの両方の最大の欠点は、システムスコープされていることです。特定のシステム内で発生していること以外を理解するのが難しくなることです。確かに、メトリクスのスコープをリクエストすることもできますが、それに伴ってラベルのファンアウトが増加し、ストレージが増加します。新しいPrometheusストレージエンジンは、時系列の高い解約率向けに最適化されていますが、要求の範囲が非常に細かい情報にはメトリックが最適ではないことも事実です。高度な結合を行わないログでは、単一のログラインまたはメトリックでは、システムのすべてのコンポーネントでリクエストに何が発生したかについて多くの情報を提供しません。ログとメトリックを組み合わせて最適に使用すると、 siloに ついて完全に把握することができますが、それ以上のものはありません。 これらは、(ステートフルおよびステートレスの両方の)個々のシステムのパフォーマンスと動作を理解するには十分かもしれませんが、複数のシステムを通過するリクエストの「ライフタイム」を理解することになると、失敗に終わります。
Traces
トレースは、リクエストが分散システムのさまざまなコンポーネントを通過する際のリクエストのライフタイムをキャプチャーします。 追加のキーと値のペアで伝播されるコンテキストを強化するためのサポートにより、トレース内のアプリケーション固有のメタデータをエンコードすることが可能になり、開発者により強力なのデバッグパワーが与えられます。
分散トレーシングの使用例は無数にあります。 主にサービス間の依存性分析、分散プロファイリング、および安定している状態の問題のデバッグに使用されますが、トレースはチャージバックと容量の計画を立てるときにも役立ちます。
トレーシングが本当に効果的であるためには、要求のパス内のすべてのコンポーネントを変更してトレース情報を伝える必要があるため、トレーイングが既存のインフラストラクチャに後付けすることが本当に困難です。 リクエストのフローのギャップがデメリットを上回らないと思っている人もいるし、これらのギャップがデバッグを難しくする盲点であると考えている人もいます。
「私たちは1年以上リクエストトレーシングサービスを実装してきましたが、まだ完全ではありません。 これらのタイプのツールの課題は、リクエストの存続期間中に何が起こっているかを本当の意味で理解するために、各スパンの周りにコードを追加する必要があることです。コードがインストルメントされていないか、ヘッダーにIDが含まれていない場合、そのコードがオペレーションにおいて危険な盲点になることが懸念されるポイントです。 」
トレーシングインストルメンテーションのもう一つの問題は、開発者がコードをイントルメントするには不十分であるということです。一般的に出回っている数多くのアプリケーションはオープンソースのフレームワークかインストルメントを追加する必要のあるライブラリを使って構築されます。これは、多言語アーキテクチャを使用する場所では、すべての言語、フレームワーク、ワイヤプロトコルが広く異なる並行性パターンと、協力する必要がある保証のため、さらに困難になります。 実際、トレーイングは、企業全体で均一に使用される言語とフレームワークの中核セットがある組織で最もうまくデプロイされています。
トレーシングのコストは、ロギングのように壊滅的なものではありません。これは、主に実行時のオーバーヘッドとストレージコストを削減するためにトレースがほとんど常にサンプリングされるためです。 サンプリングの決定は以下の時に実行されます。
- いかなるトレースが生成される前にリクエストが開始される時点
- リクエストの実行の全体的なコースのためのトレースが記録されているすべての関係するシステムの終了時
- リクエストフローの途中で、ダウンストリームサービスのみがトレースを報告する時
全てのアプローチは一長一短です。
Orangesys.ioでは、kuberneteの運用、DevOps、監視のお手伝いをさせていただいています。ぜひ私たちにおまかせください。