DevOpsは、アプリケーションを開発して公開し、サポートからのフィードバックを反映していく方法として主流になりつつあります。しかし、DevOpsを成功に導くには、組織面での複雑さやマシンデータの収集といった課題を克服する必要があります。
分散トレーシング(Distributed Tracing:分散リクエストトレーシング)とは、マイクロサービスアーキテクチャで構築されたアプリケーションを監視する仕組みです。
分散トレーシングを使用することで、監視中のアプリケーションを通過するリクエストやトランザクションの経過を観察して、アプリケーションのパフォーマンスに影響するボトルネックやバグなどの問題を正確に特定できます。つまり、分散トレーシングはマイクロサービスアーキテクチャの問題である障害発生時の原因究明の複雑化やシステム全体でのパフォーマンスの把握が難しいといったことに対応できる仕組みなのです。
プログラマーは、ソフトウェアエンジニアリングの基本的なプロセスであるトレーシングにその他の形式のログを組み合わせて、アプリケーションの動作に関する情報を収集します。しかし、従来のトレーシング方法を使用して分散ソフトウェアアーキテクチャで構築されたアプリケーションをトラブルシューティングしようとすると、問題にぶつかります。マイクロサービスは個別に拡張できるため、1つのサービスがいくつも反復されて、さまざまなサーバー、場所、環境で同時に実行されることは珍しくなく、リクエストはそうして生じた複雑な「クモの巣」を通過しなければなりません。1つのサービスで構成されるアプリケーション向けに設計された従来の方法では、こうしたリクエストを追跡することはほぼ不可能です。
分散トレーシングソリューションは、各サービスやモジュールを通過するリクエストを追跡して、そのリクエストがたどったすべての軌跡をエンドツーエンドで明らかにし、追跡の問題を解決するだけでなく、数えきれないほどのパフォーマンスの問題を解決できるメリットがあります。機能の反復を一つひとつ観察できるため、アナリストやSRE、開発者は、機能のどのインスタンスがアプリケーションの遅延や失敗を招いているのかを特定すること、その解決方法を確認して、パフォーマンスを監視できます。
以下では、分散トレーシングの具体的な仕組みやメリット、分散トレーシングを企業に導入するためのテクノロジーについて詳しく見ていきます。
分散トレーシングの仕組みをすばやく理解するには、分散トレーシングがリクエストを処理する方法を見るのが一番です。トレーシングは、エンドユーザーがアプリケーションを操作した瞬間に始まります。ユーザーが最初のリクエストを送信すると、そのリクエストには一意のトレースIDが割り当てられます。ここでは、一般的なHTTPリクエストを例に説明を進めましょう。リクエストがホストシステムを移動すると、リクエストに対して実行されるすべての操作(「スパン」または「子スパン」)には、最初のリクエストのトレースIDと固有のID、さらには現在のリクエストを生成した操作(「親スパン」)のIDがタグ付けされます。
それぞれのスパンは、リクエストがたどる旅の中の1つのステップであり、その操作を実行しているマイクロサービスプロセスに関連する重要な情報でエンコードされます。各スパンには、次のような情報が含まれます。
- リクエストを処理しているプロセスのサービス名とアドレス
- プロセスのアクティビティについてのコンテキストを提供するログとイベント
- セッションID、データベースホスト、HTTPメソッドなどの識別子によってリクエストにクエリやフィルタリングを行うためのタグ
- 詳細なスタックトレースとエラーメッセージ(障害が発生した場合)
ZipkinやJaegerのような分散トレーシングツールは、すべてのスパンのデータを相関付け、視覚的な情報にまとめて、Webインターフェイスからの要求に応じて表示できるようにします(ZipkinとJaegerについては、あとでもう少し詳しく触れます)。
では今度は、数百万のユーザーがいる人気のオンラインビデオゲームを思い浮かべてみましょう。オンラインビデオゲームは、マイクロサービスをベースとした最新のアプリケーションの典型です。オンラインビデオゲームでは、各エンドユーザーの場所、他のプレイヤーや環境とのやり取り、プレイヤーが獲得する各アイテム、終了時間をはじめとするゲーム内データを多数追跡しなければなりません。従来のトレーシング方法では、ゲームをスムーズに実行し続けることなど、想像すらできません。しかし、分散リクエストトレーシングであれば可能です。
分散トレーシングの一番のメリットは分散システムに統一性をもたらすことです。しかし、これ以外にも多くのメリットが生み出されます。たとえば、以下のようなメリットを得られます。
- 生産性の向上:マイクロサービスアーキテクチャにはそもそも相互のまとまりがないため、モノリシックアプリケーションと比較して問題の追跡や解決といったパフォーマンス監視に時間もコストもかかります。また、マイクロサービス内での障害データの配信方法も複雑であるため、開発者がエラーメッセージや難解なステータスコードから問題を読み解かなければならないことも少なくありません。このようなマイクロサービスのデメリットである部分を分散トレーシングは、分散システムを包括的に把握できるようにし、リクエストの障害の診断やデバッグにかかる時間を短縮します。また、エラーの原因を特定して解決する作業の効率を向上させます。
- チーム間の連携の改善:マイクロサービス環境内の各プロセスは、そのサービスで使用するテクノロジーを専門とするチームによって開発されるため、エラーの発生場所や修正の担当者の特定が容易ではありません。分散トレーシングは、このようなデータサイロや生産性のボトルネック、そこから派生するパフォーマンス上の問題を解消し、対応にかかる時間を短縮するとともに、チームどうしが効率的に連携できるようにするメリットがあります。
- 実装の柔軟性:分散トレーシングツールは、さまざまなアプリケーションやプログラミング言語に対応するため、ほぼあらゆるマイクロサービスシステムに組み込むことができます。また、開発者が単一のトレーシングアプリケーションでデータを把握できるようになるメリットがあります。
Splunkの分散トレーシングツール:Splunk APMについてはこちらからご覧ください
- コードトレーシング:コードトレーシングとは、アプリケーション内の各コード行の結果を解釈し、その影響を記録するプロセスを(自動で実行するデバッガではなく)プログラマーが手作業で行って、プログラムの実行をトレースすることを言います。トレーシングするのが小さなコードブロックの場合は、わずかな編集の影響を特定するためにプログラム全体を実行しなくて済むため、手作業の方が効率的なことがあります。
- データトレーシング:データトレーシングは、重要なデータ要素(CDE:Critical Data Elements)の正確さやデータ品質を確認したり、ソースシステムに遡ってトレースしたり、統計的手法を使って監視や管理を行うのに役立ちます。一般に、正確さを確認するには、操作を開始時点までトレースしてソースデータとの検証を行うのが最善です。しかし、大規模な操作プロセスの場合、この方法はコスト面で見合いません。その場合は、統計的プロセス制御(SPC)を代わりに使用して、CDEの優先順位付けやトレース、監視、制御を行うことができます。
- プログラムトレース(ptrace):プログラムトレースとは、アプリケーションの実行中に実行される命令と参照されるデータのインデックスです。プログラムトレースには、プログラムの名前、言語、実行されたソースステートメントなどの情報がその他のデータとともに表示され、アプリケーションのデバッグプロセスで使用することができます。
分散トレーシングの世界では、集中ロギングとは、各マイクロサービスからのデータを1カ所に集約して、アクセスや分析をしやすくすることを言います。
アプリケーションのログファイルを隅々まで探して問題の原因または一因となっているエラーを見つけることは、開発者にとって非常に面倒であっても重要な作業の1つです。マイクロサービス環境では、この作業にはとりわけ多大な労力がかかりがちです。
前述したように、従来の監視方法は、追跡するコードベースが1つしかないモノリシックアプリケーションでは問題なく機能します。仮に各マイクロサービスを小さなモノリシック(一枚岩)として扱い、そのアプリケーションログデータとシステムログデータで問題を診断するのであれば、同じ方法をマイクロサービスアーキテクチャに適用できます。しかし、このアプローチには問題があります。なぜなら、個々のサービスのデータのみを取り込んで、特定のプロセスの問題のみを修正することになるため、対応に時間がかかるからです。
集中ロギングは、さまざまなサービスからログを収集して1カ所に集約し 、データベース内でインデックス化します。それらのログデータは、ログ管理ソフトウェア内でステータス、ホスト、重大度、発生元、タイムスタンプなどのフィールドを使って検索、フィルタリング、グループ化することができます。
分散システムでの集中ロギングには、いくつものメリットがあります。まず、関連するすべてのログが1カ所に集約されているため、アプリケーションの問題の根本原因を突き止めるために開発者がかけなければならない時間と労力が大幅に軽減されます。また、ログが単なるテキストではなく意味のあるデータに整理されるため、洗練された高度なクエリを実行でき、システム全体のパフォーマンスを明確に把握できるようになります。
分散ロギングとは、ログファイルを分散したままにする手法です。分散ロギングが集中ロギングよりも望ましい可能性があるケースもいくつかあります。
まず、ネットワーク中でログを1カ所に集めようとすると、帯域幅が大量に消費されることがあります。ネットワークの状況と、ログの数や生成頻度によっては、重要度の高いアプリケーションやプロセスとログの一元化が競合することもありえます。また、ログのストレージシステムによっては、ログファイルを生成するデバイスの近くにある方が、信頼性が高まるものもあります。
大規模システムも、分散ロギングの方が望ましい可能性があるケースです。多数のマイクロサービスで構成されるアプリケーションは、その性質上、大量のログメッセージを生成するため、集中ロギングは手間がかかりすぎ、コスト効率も下がります。
マイクロサービスのロギングには、緩やかに結合されたモジュールからなるマイクロサービスアーキテクチャの性質を考慮した、一連のベストプラクティス(仕組み)があります。システムに統一性をもたらし、トラブルシューティングやデバッグの効率と精度を高めることが、マイクロサービスのロギングの目的です。
マイクロサービスのロギングには、一般に次のベストプラクティスが取り入れられています。
- リクエストの相関付け:マイクロサービスシステム内の各サービスは、他のサービスとやりとりしてリクエストを遂行します。最初のリクエストに一意のIDでタグ付けすると、システム内での追跡が容易になり、潜在的なエラーを特定できるほか、前のサービスリクエストと次のリクエストのどちらにエラーの原因があるのかを明らかにすることができます。開発者は、ログ集約ツールの検索エンジンに一意のIDを入力することで、すべてのサービスからログを引き出して分析できます。
- ロギングする情報:ログ情報が多いほど、問題を理解するためのコンテキストが増えます。ログに含めることを検討すべきデータポイントには、ログメッセージを生成したサービスの名前、相関ID、リクエストを行っているサーバーとクライアントのIPアドレス、メッセージの送信日時や受信日時など、さまざまなものがあります。
- ログデータの構造化:多様なテクノロジースタックを使用できることは、マイクロサービスアーキテクチャのメリットの1つです。しかし、結果として異なるログ形式が混在することになり、分析の大きな妨げとなることが少なくありません。JavaScript Object Notation (JSON)などの標準形式にデータを構造化すると、解析しやすくなり、1カ所からさまざまなフィールドで検索できるようになります。
- ログの集約:個々のサーバーにアクセスしてログを相関付ける作業は、貴重な時間とエネルギーを奪う上、マイクロシステムの数が増えるにつれて負担が膨れ上がります。集中ロギングは、この問題を解決します。また、サーバーやコンテナが突然終了すると、ログは消えてしまいますが、集中ロギングならログは数分ごとに一元化されたリポジトリに送られるため、取り返しのつかない消失が起こりにくくなります。
OpenTracingとOpenCensusは、オープンソースの分散トレーシングプロジェクトとして競合関係にありましたが、先頃OpenTelemetryと呼ばれる1つのツールに統合されました。
Cloud Native Computing Foundation (CNCF)がまとめ役となってきたOpenTracingは、トレーシング用の標準化されたAPIを提供することで、開発者が一般的なライブラリや独自のカスタムコードにインストルメンテーションを組み込めるようにし、ベンダーロックインを解消することを目指してきました。OpenTracingは強く望まれてきた柔軟性を備えていたものの、APIがトレーシングのみにフォーカスしていたため、単独では用途が限られ、開発者やベンダーによって実装にばらつきが生じていました。
OpenCensusは、Googleで開発され、Google社内のトレーシングプラットフォームをベースとしていました。かつてはオープンソースであったOpenCensusですが、Microsoftをはじめとするベンダーやコントリビュータが主導するスタンダードへと変わって行きました。OpenCensusは、アプリケーションの動作についてのメトリクスを収集する多言語ライブラリのセットで、開発者は、収集されたメトリクスデータを任意のバックエンド分析プラットフォームに転送できます。また、メッセージ、リクエスト、サービスを発生元から送信先までトレースすることができます。OpenCensusをコードに組み込むためのAPIが提供されていないため、開発者はコミュニティで開発された自動インストルメンテーションエージェントを使用していました。
CNCFが管理するOpenTelemetryは、OpenTracingとOpenCensusのコードベースを統合したもので、両方の強みが活かされています。現在ベータ版であるOpenTelemetryは、アプリケーションから分散トレースやメトリクスを取得する「API、ライブラリ、エージェント、コレクターサービスの単一セット」を提供します。取得された分散トレースやメトリクスは、一般的なオブザーバビリティツールを使用して分析できます。近い将来、OpenTelemetryはデータ取得機能にロギング機能を追加する見込みです。
JaegerとZipkinは、どちらも人気のあるオープンソースのリクエストトレーシングツールで、コンポーネント(コレクター、データストア、クエリAPI、Webユーザーインターフェイス)にあまり違いはありません。アプリケーションと連動して送信リクエストをトレースし、続いてコレクターがさまざまなトレースのデータを記録して相関付け、データベースに送信します。データベースに送信されたデータは、UIを介してクエリや分析を行えます。
JaegerとZipkinは、アーキテクチャとサポートするプログラミング言語が違います。JaegerはGoで、ZipkinはJavaで実装されています。Zipkinは、ほぼあらゆるプログラミング言語をサポートし、Java、Javascript、C、C++、C#、Python、Go、Scalaやその他の言語向けの専用ライブラリがあります。Jaegerは、サポートする言語がZipkinよりも少なく、C#、Java、Node.js、Python、Goをサポートしています。
AWS X-Rayは、アマゾン ウェブ サービス (AWS)向けのネイティブな分散トレーシングツールです。世界最大級のクラウドサービスプロバイダーであるAmazonは、モノリシックベースからマイクロサービスベースのアプリケーションへの移行の最先端を走り、独自のトレーシングツールを開発してきました。
他の同種のツールと同じように、AWS X-Rayはアプリケーション全体のユーザーリクエストをトレースして、レイテンシーの問題やエラーなどの原因を調べるのに役立つデータを収集します。このトレースデータはサービスマップにフォーマットされ、開発者はこのマップを解析して問題を特定することができます。
AWS X-Rayが、AWS Lambda、Amazon EC2 (Elastic Compute Cloud)、Amazon EC2 Container Service (Amazon ECS)、AWS Elastic BeanstalkなどのAmazonのその他のサービスと相性が良いのは言うまでもありません。アプリケーションのビルドステージとテストステージのいずれでも使用でき、アプリケーションが本番稼働するようになった後もメンテナンスに使用できます。
Kafkaは、リアルタイムのデータフィードを処理する、高スループットかつ低レイテンシーな分散ストリーミングプラットフォームで、特にマイクロサービスアーキテクチャで多用されています。Kafkaを使用すると、レコードのストリームをリアルタイムで処理し、メッセージキューと同様の方法でこうしたレコードストリームのパブリッシュやサブスクライブを行い、「耐久性の高いフォールトトレラントな方法」で格納できます。
Kafkaは、「トピック(レコードがパブリッシュされる先のカテゴリ(フィード名))」を使用してレコードのストリームを抽象化します。またKafkaは、トピックごとにパーティション分割されたログを維持しています。パーティションは、継続的に追加されるレコードのシーケンスで、順番が付けられており、分散システムの外部コミットログとして機能します。
現在、市場には優れたログ集約監視ツールがいくつかありますが、中でも人気の高いものを以下に紹介します。
Elastic (旧称ELK):最も人気のある分散システム向けスタックの1つであるElasticは、ElasticSearch、Logstash、Kibanaという3つの基本ツールで構成されています。Logstashはログファイルの集約、ElasticSearchはデータのインデックス化と検索に使用でき、Kibanaはデータを視覚化するダッシュボードです。オープンソースで無償のElasticは、スタック全体を実装することも、各ツールを個別に使用することもできます。
Loggly:Logglyは、クラウドベースのログ管理分析サービスで、DevOpsのユーザーによってDevOpsユーザーのために作られています。操作しやすいインターフェイスを使って大量のログデータを処理できるように設計されており、主にトラブルシューティングや顧客サポートに使用されています。RESTful APIも用意されており、他のツールに統合することもできます。
PaperTrail:PaperTrailは、すでに収集しているログを隅々まで簡単にチェックできるエンドユーザー向けのサービスです(ログの集約はできません)。インストールが容易で、インターフェイスもわかりやすく、ブラウザー、コマンドライン、APIのデータが1カ所に表示されます。
Graylog:Graylogもオープンソースのログ分析ツールです。Graylogは、開発者がアプリケーション内のエラーを見つけて修正できるように特に作成されました。すばやく使えるよう、UIはシンプルに作られており、さまざまなデータ形式を管理できます。
DevOps 5つのプラクティス
DevOpsチームの明暗を分ける5つのプラクティスについてご紹介します。