パフォーマンスの最適化:Pyroscopeを採用する理由
統合オブザーバビリティの追求において、私たちはオープンソースのプロファイリングソリューションであるPyroscopeを採用し、製品のパフォーマンスを継続的に分析しています。このブログ記事では、まず、すべてのクライアントインスタンスからのプロファイル収集からGrafanaでの可視化まで、一元化されたデータフローをどのように構築したかを説明します。次に、このツールによって製品のパフォーマンスをどのように最適化できたかを解説します。
TL;DR
- すべての製品インスタンスにわたる継続的プロファイリングのためにPyroscopeを実装しました。
- 一元化されたオブザーバビリティクラスターが、分散Kubernetes環境からプロファイル、ログ、メトリクスを収集します。
- Grafana統合により、フレームグラフの可視化と経時的なパフォーマンス傾向の分析が可能になります。
- プロファイリングはボトルネックの検出、コードの最適化に役立ち、高いシステムパフォーマンスを保証します。
- 実例:Pyroscopeの洞察を活用して、OpenCTIのCPU負荷の高い関数を特定し、解決しました。
プロファイリングとは?
プロファイリングとは、プログラムが時間経過とともにリソース(CPU、メモリ、I/Oなど)をどのように消費するかについて、詳細な情報を収集・分析するプロセスです。集約されたインサイトを提供する従来のメトリクスとは異なり、プロファイリングはシステム動作のきめ細かなコードレベルの視点を提供します。これにより、チームは他の方法では検出が困難な非効率性、ボトルネック、リグレッションを特定できます。
一元化されたオブザーバビリティプラットフォーム
私たちの製品(OpenCTI、OpenBAS)は異なる地域に分散されたKubernetesクラスター上で動作していますが、すべてのログ、メトリクス、プロファイリングデータの収集と処理に専念する単一の一元化されたオブザーバビリティクラスターを確立しました。この一元化されたアプローチにより、エントリーポイントを増やしたりメンテナンスの複雑さを増大させることなく、システムヘルスの一貫したグローバルビューが保証されます。
各プラットフォームコンポーネントにはPyroscope Node.jsプロファイリングパッケージが組み込まれており、定期的にプロファイルを生成し、統合コレクターであるAlloyにプッシュします。各本番クラスターにデプロイされたAlloyは、プロファイリングデータを受信し、適切なラベル付けを適用し、オブザーバビリティクラスターにホストされているPyroscopeサーバーに(HTTPSと認証を介して)安全に送信します。プロファイルは、自動的にパージされる前に、永続ボリュームに7日間保持されます。

アーキテクチャ概要
Grafanaでの可視化と分析
この情報を実行可能にするために、PyroscopeプラグインをGrafanaに統合しました。私たちのチームは、フレームグラフにアクセスし、サービス間でパフォーマンスの進化を比較し、ボトルネックを迅速に特定できます。このシームレスな統合により、プロファイリングの異常が検出されたらすぐに最適化を導き、優先順位を付けることができます。
インスタンスでのプロファイリング
本番環境または開発環境のOpenCTIインスタンスをお持ちの場合、プロファイリングを有効にできます。次の設定を追加するだけです:
- compose デプロイメントにPyroscopeサービスを追加:
Copied!
1pyroscope:2 image: grafana/pyroscope3 restart: unless-stopped4 ports:5 - "4040:4040"
- OpenCTIプロセスの環境変数:
Copied!
1APP__TELEMETRY__PYROSCOPE__IDENTIFIER=opencti2APP__TELEMETRY__PYROSCOPE__ENABLED=true3APP__TELEMETRY__PYROSCOPE__EXPORTER="http://docker-pyroscope-1:4040"
localhost:4040にアクセスすると、フレームグラフが表示されるはずです:

フレームグラフとは何か、どのように使用するか?
フレームグラフは、関数呼び出しとそのリソース消費(主にCPU時間)の直感的で階層的な表現を提供します。フレームグラフの各バーの幅は、その関数で費やされた時間の割合を示します。
Pyroscopeが生成するこのフレームグラフを次のように使用しています:
- CPUパフォーマンスのボトルネックを特定:最もリソースを消費しているコードの正確な行を特定します。
- 経時的なアプリケーション動作の理解:継続的プロファイリングはパフォーマンスの履歴ビューを提供し、リグレッションの検出とコード変更の影響の理解に役立ちます。
- 異常なメモリ消費を特定:アプリケーションが使用するメモリを最も保持しているコードの正確な行を特定します。
実際の事例
すべてのデプロイメントにPyroscopeを実装して以来、製品のパフォーマンスを大幅に改善できました。では、最近の使用方法をより具体的にイメージしていただくため、実際の事例を見てみましょう。
OpenCTIでの背景
OpenCTIはインジェストの負荷を処理するためにnodejsをバックエンドとして使用しており、nodejsはマルチスレッド技術ではなく、イベントループに基づいています。詳細はこちらをご覧ください:https://nodejs.org/en/learn/asynchronous-work/event-loop-timers-and-nexttick。
このアーキテクチャのため、非常に重要なルールを守る必要があります:イベントループを40ms以上ブロックしないこと😇。
これは非常に重要なルールです。なぜなら、イベントループをブロックすると、nodejsが重要なチャンクを正しく実行したり、複数の操作を同時に実行しているように「シミュレート」したりすることができなくなるためです。
Pyroscopeが救世主に
OpenCTIで新機能を開発しながら同時にこのルールを遵守することは、時として難しい場合があります。製品は、同じ処理関数内で非常に大量のデータを処理する必要がある場合があります。データの検証、一部のエントリの変換、複数レベルでの情報操作を行うために処理する必要がある50,000以上の要素を含むレポートを想像してみてください。いずれかの時点で、イベントループをブロックし、プラットフォーム全体のパフォーマンスを乱す関数を作成するリスクがあります。
テスト手順でこのような大量のデータを考慮せずに本番環境にアップデートをデプロイした場合、Pyroscopeは特定の時間範囲でCPUを消費するコールスタックとコード行の魔法のような概要を提供します。
残念ながら、特定の問題が見える最後の調査のスクリーンショットは保持していないため、健全なプラットフォームでの例を説明します。
以下は、OpenCTIの1分間の監視の抜粋です。

ここから多くのことを学べます。
- 1分間のCPU監視で、使用したコンピューティング時間はわずか1.13秒です。つまり、インスタンスは現在リラックスしています😉
- この期間中に最も使用された関数はelDataConverterで、これはデータベースから取得したデータの結果を解析するために使用されるOpenCTIの内部関数です。
この関数をクリックすると、グラフ内のコールスタックの位置と、原因となっているコード行が表示されます。この場合、内部のすべてが同期的に処理されるため、関数定義そのものです。

では、Pyroscopeが「elDataConverter」関数が直近1分間のうち55秒のCPUを消費していると表示していると想像してみてください。この情報により、何を探すべきか、コード内のどこに位置しているかを正確に知ることができます。本番環境を直接監視するこの機能により、どれだけ時間を節約できるかお分かりいただけると思います。😉
まとめ
結論として、プロファイリングソリューションとしてのPyroscopeは、Filigran製品のパフォーマンスを監視・最適化する方法において画期的な変化をもたらしました。Pyroscopeを一元化されたオブザーバビリティプラットフォームに活用し、Grafanaを通じてデータを可視化することで、リソース消費に関する詳細な洞察を得るだけでなく、潜在的なボトルネックを積極的に特定し、対処することができます。
このアプローチにより、高いパフォーマンス基準を維持し、製品改善に関して情報に基づいた意思決定を行うことができました。その結果、クライアントとコミュニティに堅牢で効率的なソリューションを提供し続けています。
ご質問、リクエスト、コメント、フィードバックがございましたら、お気軽にSlackでご参加ください!
続きを読む
関連トピックとインサイトをご覧ください

