これは、なにをしたくて書いたもの?
ちょっとOpenTelemetryに興味を持っていまして、トレーシングについてはJaegerを見ていこうと思っているのですが。
とりあえず使ってみる時に、
$ ./jaeger-all-in-one
としか実行したことがなく、そもそも「all-in-one」ってなに?状態だったのでここを少し紐解きたいなと思いまして。
Jaeger
Jaegerは、Uberが開発したオープンソースの分散トレーシングプラットフォームです。
Jaeger: open source, distributed tracing platform
Jaeger is a distributed tracing platform released as open source by Uber Technologies.
Goで実装されており、以下を特徴としています。
- OpenTracingにインスパイアされたデータモデル
- OpenTelemetry互換
- 複数のストレージバックエンド(Cassandra、Elasticsearch、Kafka、インメモリー)
- コミュニティによってサポートされている、gRPC経由の外部ストレージバックエンド
- システムトポロジーグラフ
- 適応サンプリング
- サービスパフォーマンスモニタリング(APM)
- データ収集後の処理
今回は、このJaegerの構成をドキュメントから見ていきます。
Jaegerディストリビューション
ところで、Jaegerをダウンロードして展開してみましょう。
$ curl -LO https://github.com/jaegertracing/jaeger/releases/download/v1.49.0/jaeger-1.49.0-linux-amd64.tar.gz $ tar xf jaeger-1.49.0-linux-amd64.tar.gz $ cd jaeger-1.49.0-linux-amd64
こういった感じになっています。
$ ll 合計 230948 drwxr-xr-x 2 xxxxx xxxxx 4096 9月 7 23:35 ./ drwxrwxr-x 3 xxxxx xxxxx 4096 9月 10 19:53 ../ -rwxr-xr-x 1 xxxxx xxxxx 21266513 9月 7 23:35 example-hotrod* -rwxr-xr-x 1 xxxxx xxxxx 24992961 9月 7 23:35 jaeger-agent* -rwxr-xr-x 1 xxxxx xxxxx 53441192 9月 7 23:35 jaeger-all-in-one* -rwxr-xr-x 1 xxxxx xxxxx 47551050 9月 7 23:35 jaeger-collector* -rwxr-xr-x 1 xxxxx xxxxx 41323351 9月 7 23:35 jaeger-ingester* -rwxr-xr-x 1 xxxxx xxxxx 47876295 9月 7 23:35 jaeger-query*
分散トレーシングで使われる時は「とりあえずjaeger-all-in-oneを起動」みたいな感じになっているのであまり気にしていなかったの
ですが、これだけ含まれていたんですね。
今回はこれらを見ていくことになります。Jaegerのバージョンは1.49.0です。
なお、example-hotrod
というのはサンプル用のアプリケーションみたいです。
Jaegerを構成するコンポーネント
Jaegerのアーキテクチャーはこちらに書かれています。
Architecture — Jaeger documentation
まず、スパンやトレースといった用語はこちらを見ておきましょう。
スパンはオペレーション名、オペレーションの開始時間および期間を持つ論理的な作業単位です。スパンはネストすることができ、
順序付けできます。
トレースはシステム内のデータや実行パスを表したものです。これはスパンのDAG(有向非巡回グラフ)と捉えることができます。
そしてアーキテクチャー。これはデプロイ時の構成パターンですね。
その前に、Jaegerを構成するコンポーネントの種類と名前を明らかにした方が良さそうです。
Tracing SDKs
Jaegerが提供していたトレース用のSDKですが、現在はOpenTelemetry SDKを使うため廃止されるようです。
Agent
コンポーネントとしてはjaeger-agent
です。
UDP経由で送信されてくるスパンを受信するデーモンで、スパンをバッチ化してjaeger-collector
に送信します。Jaeger Agentは必須の
コンポーネントではなく、かつ現在はOpenTelemetry SDKから直接jaeger-collector
送信、またはOpenTelemetry Collactorを介することに
なるため非推奨です。
Collector
コンポーネントとしてはjaeger-collector
です。
トレースを受信し、バリデーションやクリーンアップ、エンリッチメントのためのパイプラインを経由してストレージバックエンドに
保存します。
いくつかのストレージが使用可能で、カスタムストレージプラグインを実装可能な拡張プラグインフレームワークを備えています。
Query
コンポーネントとしてはjaeger-query
です。
ストレージからトレースを取得するためのAPIを公開し、トレースを検索や分析のためのWeb UIを提供するサービスです。Reactが
使われているようですね。
APIはこちら。
Ingester
コンポーネントとしてはjaeger-ingester
です。
Kafkaからトレースを読み取り、ストレージバックエンドに書き込むサービスです。入力はKafkaのみとなった、Collectorの簡素版という
扱いのようです。
ここまでで、Jaegerのディストリビューションに含まれる個々の実行ファイルの意味がわかってきました。
デプロイパターン
ここからは、デプロイパターンになります。
ストレージへ直接保存
Collectorがトレースデータをアプリケーションから受信し、ストレージに直接書き込むように構成したパターンです。保存されたデータの
参照にはQueryを使います。
Architecture / Architecture / Direct to storage
Collectorは短期間であればトラフィックのピークを平滑化するためにインメモリーキューを使用できますが、ストレージが書き込みに
追いつかない場合は高いトラフィックが続くとデータがドロップされる可能性があります。
Kafkaをキューとして配置する
Collectorとストレージの間にKafkaを挟み、ストレージに保存するまでの間にデータが損失するのを防ぐためにKafkaを中間の永続キュー
として使用します。
Collectorからのデータの送信先はKafkaとなり、Kafkaに保存されたデータはIngesterが読み出してストレージに保存します。Ingesterは
複数デプロイしてスケールアウトが可能です。
Architecture / Architecture / Via Kafka
データの参照にQueryを使うのはストレージに直接保存する場合と同じです。
OpenTelemetry Collector
他のテレメトリーデータやトレースデータの収集、処理のためにOpenTelemetry Collectorを配置している場合などは、SDKとCollectorの
間にOpehTelemetry Collectorを配置できます。
OpenTelemetry CollectorはJaegerのCollectorのプロキシとして機能します。
Architecture / Architecture / With OpenTelemetry Collector
OpenTelemetry Collectorのデプロイパターンはいくつかあり、アプリケーションサイドカー、ホストエージェント/デーモン、
中央集権的なクラスターとして実行できます。
なお、JaegerのCollectorはOpenTelemetry SDKからOpenTelemetryデータを直接受信して処理できるため、OpenTelemetry Collectorを
使用する必要はないとされています。特にOpenTelemetryに関するコンポーネントがシステム内にJaegerしかない場合は、わざわざ
OpenTelemetry Collectorを導入する理由が薄い感じになりますね。
all in oneは?
ここまで見ていて、all in oneについての説明が薄いことに気づくわけですが。
アーキテクチャーに少し出てきます。Jaegerの提供するすべてのバックエンドコンポーネントを単一プロセスで実行できるオールインワン
バイナリのことを指しています。
Jaeger can be deployed either as an all-in-one binary, where all Jaeger backend components run in a single process, or as a scalable distributed system.
また、デプロイメントのページにも少し書かれています。
Jaeger all-in-one is a special distribution that combines three Jaeger components, agent, collector, and query service/UI, in a single binary or container image. It is useful for single-node deployments where your trace volume is light enough to be handled by a single instance. By default, all-in-one starts with memory storage, meaning it will lose all data upon restart.
ざっと以下の感じですね。
- Agent、Collector、Queryを単一のバイナリまたはコンテナイメージにまとめた特殊なディストリビューション
- トレースデータが単一のインスタンスで処理できるほど軽量な場合に便利
- デフォルトのストレージはメモリーなので、再起動するとデータは失われる
- すべてのスパンストレージバックエンドも利用可能だが、All-in-oneインスタンス間でメモリーやバッジのデータは共有できない
およそJaegerの構成要素はわかったのではないかなと思います。
おわりに
Jaegerを構成するコンポーネントを見てみました。
今まで何気なく「all-in-one」を使っていましたが、それぞれの位置づけがわかったのでそのうちコンポーネントごとにプロセスを立てて
試してみたいですね。
それから、Jaegerを使ってOpenTelemetryデータを受信する際には、OpenTelemetry Collectorはなくても構わないということもわかりました。
これからは構成を簡略化して試してみようかなと思います。