特に根強い誤解についてお話しましょう。監視システムと Prometheus のプルベースのメトリクス収集アプローチに関する議論になると、必ず誰かがプルベースのアプローチは「根本的にスケールしない」と口にします。その理由は曖昧であったり、Prometheusとは根本的に異なるシステムにのみ当てはまることが多いです。実際、最大規模でプルベースの監視に取り組んできた経験からすると、この主張は私たちの実際の運用経験とは矛盾します。
すでにPrometheusがプッシュではなくプルを選択する理由についてのFAQエントリがありますが、特にスケーリングの側面には焦点を当てていません。この主張に関する通常の誤解を詳しく見て、それらがPrometheusに当てはまるかどうかを分析してみましょう。
PrometheusはNagiosではない
人々がアクティブにプルする監視システムを思い浮かべる時、しばしばNagiosを考えます。Nagiosは、特定のホストまたはサービスの健全性を判断するために、Nagiosホスト上で任意の処理を実行できるアクティブチェックのためにサブプロセスを生成するため、スケーリングがうまくいかないという評判があります。この種のチェックアーキテクチャは、中央のNagiosホストがすぐに過負荷になるため、確かにうまくスケールしません。その結果、人々は通常、チェックを数分おきにしか実行しないように設定するか、より深刻な問題に直面します。
しかし、Prometheusはまったく異なるアプローチを採用しています。チェックスクリプトを実行する代わりに、ネットワーク上の計測されたターゲットのセットから時系列データのみを収集します。ターゲットごとに、Prometheusサーバーは(ゴルーチンを使用して高度に並列的に)HTTPを介してそのターゲットのすべてのメトリクスの現在の状態をフェッチするだけで、プル関連のその他の実行オーバーヘッドはありません。これにより、次のポイントに進みます。
接続を確立する側は重要ではない
スケーリングの目的では、メトリクスが転送されるTCP接続を確立する側は重要ではありません。どちらの方法でも、接続を確立するための労力は、メトリクスのペイロードやその他の必要な作業と比較してわずかです。
しかし、プッシュベースのアプローチではUDPを使用して、接続確立を完全に回避できる可能性があります!確かにそうですが、PrometheusのTCP/HTTPオーバーヘッドは、Prometheusサーバーがデータを(特に時系列データをディスクに永続化するために)取り込むために行う必要がある他の作業と比較すると、無視できる程度です。これを数値で示すと、単一の大規模なPrometheusサーバーは、毎秒800,000個の受信サンプル(SoundCloudでの実際の運用メトリクスデータで測定)を記録し、数百万の時系列を簡単に保存できます。10秒のスクレイプ間隔とホストあたり700の時系列を考えると、これにより、単一のPrometheusサーバーから10,000台以上のマシンを監視できます。ここでのスケーリングのボトルネックは、メトリクスのプルに関連したものではなく、通常はPrometheusサーバーがデータをメモリに取り込み、ディスク/SSD上のデータを永続的に保存および期限切れにする速度に関連しています。
また、最近ではネットワークは非常に信頼性が高くなっていますが、TCPベースのプルアプローチを使用すると、メトリクスデータが確実に到着することが保証されるか、少なくともネットワークの破損によりメトリクスの転送が失敗した場合に監視システムがすぐにそれを把握できます。
Prometheusはイベントベースのシステムではない
一部の監視システムはイベントベースです。つまり、個々のイベント(HTTPリクエスト、例外など)が発生するたびに、すぐに中央の監視システムに報告します。この中央システムは、イベントをメトリクスに集計するか(StatsDがこれの代表的な例です)、後で処理するために個別にイベントを保存します(ELKスタックがその例です)。このようなシステムでは、プルは確かに問題になります。計測されたサービスは、プルの間にイベントをバッファリングする必要があり、プッシュベースのアプローチと同じ「ライブ性」をシミュレートし、イベントバッファを圧倒しないように、プルを非常に頻繁に行う必要があります。
しかし、ここでも、Prometheusはイベントベースの監視システムではありません。生のイベントをPrometheusに送信することも、保存することもできません。Prometheusは、集計された時系列データを収集することに重点を置いています。つまり、メトリクスの生成につながった基礎となるイベントではなく、特定のメトリクスのセットの現在の状態を定期的に収集することに関心があるだけです。たとえば、計測されたサービスは、処理されるたびに各HTTPリクエストに関するメッセージをPrometheusに送信するのではなく、メモリ内のそれらのリクエストをカウントアップするだけです。これは、監視トラフィックを引き起こすことなく、毎秒数十万回発生する可能性があります。Prometheusは、現在のカウンターの値について、15秒または30秒ごと(または構成した間隔)にサービスインスタンスに問い合わせ、その値をスクレイプのタイムスタンプとともにサンプルとして保存します。ゲージ、ヒストグラム、サマリーなどの他のメトリックタイプも同様に処理されます。結果として生じる監視トラフィックは少なく、プルベースのアプローチでもこの場合は問題が発生しません。
しかし、監視はサービスインスタンスについて知る必要がある!
プルベースのアプローチでは、監視システムはどのサービスインスタンスが存在し、それらにどのように接続するかを知る必要があります。一部の人は、監視システム側でこれに必要な追加設定を懸念しており、これを運用上のスケーラビリティの問題と見なしています。
いずれにせよ、深刻な監視セットアップではこの設定の労力は避けられないと私たちは主張します。監視システムが世界のあるべき姿、および監視対象のサービスインスタンスがそこにあるべき姿を知らない場合、インスタンスがまったく報告しない場合や、停止してダウンしている場合、または本当に存在しないことをどのようにして判断できるでしょうか?これは、十分な数のエフェメラルワーカーが何らかの結果を報告する場合のように、個々のインスタンスの健全性をまったく気にしない場合にのみ許容されます。ほとんどの環境は排他的にそのようなものではありません。
監視システムがとにかく世界の望ましい状態を知る必要がある場合、プッシュベースのアプローチでは、実際には合計でより多くの構成が必要です。監視システムはどのサービスインスタンスが存在する必要があるかを知る必要があるだけでなく、サービスインスタンスも監視システムに到達する方法を知る必要があります。プルアプローチは構成が少なくて済むだけでなく、監視セットアップをより柔軟にします。プルを使用すると、本番環境の監視コピーをノートパソコンで実行して試してみることができます。また、他のツールでメトリクスをフェッチしたり、メトリクスエンドポイントを手動で検査したりすることもできます。高可用性を実現するために、プルでは、同じ構成のPrometheusサーバーを2つ並行して実行することができます。最後に、監視が到達可能なエンドポイントを移動する必要がある場合、プルアプローチでは、すべてのメトリクスソースを再構成する必要はありません。
実際的な面では、Prometheusは、クラウドプロバイダーおよびコンテナスケジューリングシステム向けの幅広いサービス検出メカニズムに対する組み込みのサポート(Consul、Marathon、Kubernetes、EC2、DNSベースのSD、Azure、Zookeeper Serversetsなど)により、世界の望ましい状態を簡単に構成できます。Prometheusでは、必要に応じて独自のカスタムメカニズムをプラグインすることもできます。マイクロサービスの世界または多層アーキテクチャでは、監視システムが、サービスインスタンスがバックエンドを検出するために使用するのと同じ方法を使用して、監視対象のターゲットを検出する場合にも、根本的に有利です。このようにして、本番トラフィックを処理しているのと同じターゲットを監視していることを確認でき、保守する必要がある検出メカニズムは1つだけになります。
監視システムを誤ってDDoS攻撃する
プルするかプッシュするかに関係なく、処理できるよりも多くのサンプルを送信すると、任意の時系列データベースが停止します。ただし、私たちの経験では、プッシュベースのアプローチでは、監視システムが誤ってダウンする可能性がわずかに高いです。どのインスタンスからどのメトリクスを取り込むかを制御する機能が(監視システムで)集中化されていない場合、実験的または不正なジョブが突然大量のガベージデータを本番監視にプッシュして、監視システムをダウンさせる危険性があります。プルベースのアプローチでもこのようなことが起こる可能性は十分にありますが(どこからメトリクスをプルするかを制御するだけで、メトリクスのペイロードのサイズと性質は制御しません)、リスクは低くなります。さらに重要なことに、このようなインシデントは中央で軽減できます。
実際の証明
Prometheusがすでに現実世界で非常に大規模なセットアップの監視に使用されているという事実(たとえば、DigitalOceanで数百万台のマシンを監視するために使用されているなど)に加えて、可能な限り最大の環境でプルベースの監視が正常に使用されている他の著名な例があります。Prometheusは、GoogleのBorgmonに触発されました。Borgmonは、プルベースのアプローチを使用して、Google内でそのすべての重要な本番サービスを監視するために(現在も部分的に)使用されていました。GoogleでBorgmonで発生したスケーリングの問題も、そのプルアプローチが原因ではありませんでした。プルベースのアプローチが、多数のデータセンターと数百万台のマシンを備えたグローバル環境にスケールする場合、「プルはスケールしない」とは言えません。
しかし、プルには他にも問題がある!
プルベースのアプローチでは監視が困難なセットアップも確かにあります。代表的な例は、ファイアウォールや複雑なネットワーク設定により直接到達できない、世界中に散在する多くのエンドポイントがあり、各ネットワークセグメントでPrometheusサーバーを直接実行することが実現不可能である場合です。これは、Prometheusが構築された環境ではありませんが、多くの場合、回避策は可能です(Pushgatewayを使用したり、セットアップを再構築したりすることで)。いずれにせよ、プルベースの監視に関するこれらの残りの懸念は、通常、スケーリングに関連するものではなく、TCP接続を開く際のネットワーク運用上の困難が原因です。
では、すべて順調ですか?
この記事では、プルベースの監視アプローチに関する最も一般的なスケーラビリティの懸念事項に対処します。Prometheusやその他のプルベースのシステムが非常に大規模な環境で正常に使用されており、プルという側面が実際にはボトルネックになっていないことから、結果は明らかです。「プルはスケールしない」という議論は現実的な懸念事項ではありません。今後の議論が、このまぎらわしい問題よりも重要な側面に焦点を当てることを願っています。