ディメンション、プロパティ、タグ
メトリクスにコンテキストを与える
ディメンションとプロパティの違いや、どちらを使うべきかというのは、よく話題にされます。それぞれの説明から始めるのではなく、私たちがどのように使い、どのように似ているのかを理解してから、それぞれの違いや、なぜどちらかを使うのかの例を見ていくことにしましょう。
ディメンションとプロパティの類似点
最も単純な答えは、ディメンションとプロパティはともに、メトリクスにコンテキスト(状況)を追加するメタデータの key:value ペアであるということです。メトリクス自体は、cpu.utilization のような標準的なインフラストラクチャメトリクスであろうと、API呼び出しの回数のようなカスタムメトリクスであろうと、実際に測定しているものなら全てに当てはまります。
cpu.utilization メトリクスの値が50%であっても、それがどこから来たのかなどのコンテキストを知らなければ、それは単なる数字であり、私たちにとって有用ではありません。少なくとも、どのホストから来たのかを知る必要があります。
現在では、個々のホストのパフォーマンスや利用率よりも、クラスターやデータセンター全体のパフォーマンスや利用率をより気にすることが多く、ホストのクラスター全体の平均 cpu.utilization、あるホストの cpu.utilization が同じサービスを実行する他のホストと比べて外れ値である場合、あるいは環境間での平均 cpu.utilization を比較することに興味を持っています。
このように cpu.utilization メトリクスをスライス、集約、またはグループ化するためには、受け取る cpu.utilization メトリクスのメタデータに、ホストが属するクラスター、ホスト上で実行されているサービス、およびそれが属する環境などの情報が必要です。このメタデータは、ディメンションまたはプロパティの key:value ペアの形で存在することができます。
例えば、ダッシュボードでフィルターを適用したり、分析関数を実行する際にグループ化機能を使用したりするとき、プロパティまたはディメンションを使用することができます。
では、ディメンションとプロパティはどう違うの?
ディメンションはメトリクスと共に取り込み時に送信されるのに対し、プロパティは取り込み後にメトリクスやディメンションに適用されます。これは、`cpu.utilization`` の値がどのホストから来ているかのような、データポイント(メトリクスの単一の報告値)をユニークにするために必要なメタデータはディメンションでなければならないことを意味します。メトリクス名 + ディメンションはMTS(メトリクスの時間系列)をユニークに定義します。
例:特定のホスト(server1)によって送信される cpu.utilization メトリクスで、ディメンション host:server1 があれば、それはユニークな時間系列と見なされます。もし10台のサーバーがそのメトリクスを送信していれば、メトリクス名 cpu.utilization を共有し、ディメンションのキー値ペア(host:server1, host:server2…host:server10)でユニークに識別される10の時間系列があります。
しかし、サーバー名がデータセンター内でのみユニークである場合、データセンターの場所を示す2番目のディメンションdcを追加する必要があります。これにより、可能なMTSの数は倍になります。受信された cpu.utilization メトリクスは、2組のディメンションのキー値ペアによってユニークに識別されます。
cpu.utilization に dc:east と host:server1 を加えたものは、cpu.utilization に dc:west と host:server1 を加えたものとは異なる時間系列を作り出します。
ディメンションは不変だが、プロパティは可変である
上記で述べたように、メトリクス名 + ディメンションの組み合わせで、ユニークなMTSを作ります。したがって、ディメンションの値が変わると、メトリクス名 + ディメンション値の新しいユニークな組み合わせが生まれ、新しいMTSが作成されます。
一方、プロパティはメトリクス(またはディメンション)が取り込まれた後に適用されます。メトリクスにプロパティを適用すると、そのメトリクスが属するすべてのMTSに伝播して適用されます。または、ディメンションにプロパティを適用する場合、例えば host:server1 とすると、そのホストからのすべてのメトリクスにそのプロパティが添付されます。プロパティの値を変更すると、そのプロパティが添付されているすべてのMTSのプロパティ値が更新されます。これが重要な理由は何でしょうか? プロパティの歴史的な値にこだわる場合、それをディメンションにする必要があることを意味しています。
例:私たちはアプリケーションに関するカスタムメトリクスを収集しています。1つのメトリクスは latency で、アプリケーションへのリクエストのレイテンシーをカウントします。顧客ごとにレイテンシーを分類して比較できるように customer ディメンションを持っています。私たちは、顧客が使用しているバージョン別にアプリケーションの latency を分類して比較したいと考え、プロパティ version を customer ディメンションに添付しました。最初はすべての顧客がアプリケーションバージョン1を使用しているので、version:1 です。
現在、いくつかの顧客がアプリケーションのバージョン2を使用しているため、それらの顧客に対してプロパティを version:2 に更新します。これらの顧客の version プロパティの値を更新すると、その顧客に関連するすべてのMTSに伝播します。これにより、これらの顧客が以前に version:1 を使用していたという歴史が失われるため、歴史的な期間にわたって version:1 と version:2 の latency を比較する場合、正確なデータを得ることはできません。この場合、メトリクスの時間系列をユニークにするためにアプリケーションの version が必要ではないかもしれませんが、歴史的な値にこだわるために version をディメンションにする必要があります。
結局、いつ、ディメンションじゃなくてプロパティを使うの?
メトリクスに添付したいメタデータがあるが、取り込み時にはそれを知らない場合が第一の理由です。第二の理由は、ベストプラクティスとして、ディメンションである必要がなければ、それをプロパティにすることです。なぜでしょうか?
一つの理由は、現在、分析ジョブやチャートレンダリングあたりのMTSの上限が5Kであり、ディメンションが多いほど多くのMTSを生成することです。プロパティは完全に自由形式であり、MTSの数を増やすことなく、メトリクスやディメンションに必要な情報を追加することができます。
ディメンションは各データポイントと共に送信されるため、ディメンションが多いほど、より多くのデータを送信することになります。これは、クラウドプロバイダーがデータ転送に料金を請求する場合、コストが高くなる可能性があります。
プロパティを使う良い例としては、ホスト情報の追加などがあります。 machine_type, processor, os などの情報を確認することが重要ですが、これらをディメンションとして設定し、各ホストからのすべてのメトリクスと共に送信するのではなく、プロパティとして設定し、ホストディメンションに添付することができます。
例えば host:server1 では、プロパティ machine_type:ucs, processor:xeon-5560, os:rhel71 を設定します。host:server1 というディメンションを持つメトリクスが入ってくるたびに、上記のすべてのプロパティが自動的に適用されます。
プロパティの使用例としては、各サービスのエスカレーション連絡先や、各顧客のSLAレベルを知りたい場合があります。これらの項目は、メトリクスをユニークに識別するために必要ではなく、歴史的な値にも関心がないため、プロパティにすることができます。プロパティはサービスディメンションや顧客ディメンションに追加され、これらのディメンションを持つすべてのメトリクスやMTSに適用されます。
タグについてはどうですか?
タグは、メトリクスにコンテキストを与えたり整理するのに使われる、メタデータの3番目のタイプです。ディメンションやプロパティとは異なり、タグは key:value ペアではありません。タグはラベルやキーワードとして考えることができます。プロパティと同様に、タグは取り込み後にUIのCatalogやAPIを通じてプログラム的にデータに適用されます。タグはメトリクス、ディメンション、ディテクターなどの他のオブジェクトに適用することができます。
タグを使う場面はどこですか?
タグが必要とされるのは、タグとオブジェクトの間に多対一の関係がある場合や、タグとそれに適用されるオブジェクト間に一対多の関係がある場合です。本質的に関連していないメトリクスをまとめるのに役立ちます。
例として、複数のアプリケーションを実行しているホストがある場合です。各アプリケーションに対してタグ(ラベル)を作成し、それぞれのホストに複数のタグを適用して、その上で実行されているアプリケーションをラベル付けします。
例:Server1は3つのアプリケーションを実行しています。タグ app1, app2, app3 を作成し、ディメンション host:server1 にこれら3つのタグをすべて適用します。
上記の例を拡張すると、アプリケーションからのメトリクスも収集しているとします。作成したタグを、アプリケーション自体から来るメトリクスに適用することができます。タグに基づいてフィルタリングすることで、アプリケーションに基づいてフィルタリングしながら、アプリケーションと関連するホストメトリクスの全体像を得ることができます。
例:App1は service:application1 というディメンションでメトリクスを送信します。service:application1 のディメンションにタグ app1 を適用します。その後、チャートやダッシュボードでタグ app1 でフィルタリングすることができます。
タグの他の使用例には、単一の可能な値を持つ二進状態があります。例として、カナリアテストを行い、カナリアデプロイを行った際に新しいコードを受け取ったホストをマークして、新しいコードを受け取らなかったホストとのパフォーマンスを比較しやすくすることがあります。単一の値 canary しかないため、key:value ペアは必要ありません。
ただし、タグでフィルタリングはできますが、groupBy関数では使用できないことに注意してください。groupBy関数は key:value ペアのキー部分を指定して実行され、そのキーの値に基づいて結果がグループ化されます。
さらなる情報
カスタムメトリクスのディメンションを送信する方法に関する情報については、お使いのライブラリに関するクライアントライブラリのドキュメントをご覧ください。
APIを通じてメトリクスやディメンションにプロパティやタグを適用する方法については、 /metric/:name、/dimension/:key/:value に関するAPIドキュメントを参照してください。
UIのメタデータカタログでプロパティやタグを追加または編集する方法については、Search the Metric Finder and Metadata catalogで、Add or edit metadata セクションをご覧ください。