高いカーディナリティがどのように機能するかを理解することは、データの制限に達するまでの時間に影響を与えるため、重要です。
カーディナリティとは何か、なぜそれが重要なのか?
カーディナリティは、通常、セット内の一意の要素の数として定義されます。ディメンション メトリックの場合、問題のセットは、特定のメトリックについて 1 日の期間に観測された属性の一意のマップのコレクションです。次の NRQL 形式を使用して、New Relic でメトリクスのカーディナリティをクエリできます。
FROM Metric SELECT cardinality(metric.name) SINCE today RAW
たとえば、メトリクスmemory.heap
のカーディナリティをクエリし、このメトリクスに存在する一意のキーと値のペアの数を調べるには、次のクエリを実行します。
FROM Metric SELECT cardinality(memory.heap) SINCE today RAW
ヒント
FROM Metric
を使用するカーディナリティ クエリにRAW
句を含めることをお勧めします。これは、カーディナリティが制限されている場合、 SINCE today
のようなクエリはレポートを作成していないロールアップをクエリするため、必要な分析を実行するために生データ ポイントを調べる必要があるためです。
長い時間範囲にわたる生データ ポイントのクエリは遅くなる可能性があるため、2 日を超えるデータにまたがるRAW
クエリは許可されないことに注意してください。
カーディナリティとは何かという基本的なことは簡単ですが、カーディナリティの高さに対処し管理する方法を学ぶのは少し複雑になります。
カーディナリティの制限と強制
New Relic では、メトリックのカーディナリティの制限をメトリックごとのレベルとアカウントレベルの両方で実施しています。カーディナリティの評価は、UTC の 1 日 (00:00:00 UTC から 23:59:59 UTC) をかけて行われます。
データの制限と関連するポリシーについては、 New Relic data usage limits and policies をご覧ください。
カーディナリティと次元測定法
あるメトリックのカーディナリティとは、1日の間にそのメトリックについて観測された属性のユニークなマップの集合の大きさである。そのマップのキーや値が時間の経過とともに変化すれば、そのメトリックの新たなカーディナリティが追加される。例を見てみましょう。
4 つのホストのネットワークを想像してください。それぞれで 2 つのコンテナーが実行されており、各コンテナーはホスト名とコンテナー ID が属性として追加されたゲージ メトリックmemory.heap
を定期的に報告します。
Metric APIに送信すると、これらのメトリクスの1つは以下のようになります。
{ "metrics": [ { "name": "memory.heap", "type": "gauge", "value": 5514, "timestamp": 1234567890, "attributes": { "host": "W", "container": "1" } } ]}
このメトリクスは、 host
とcontainer
の一意のマッピングが可能な数として 8 のカーディナリティを持ちます。このメトリックの新しい測定値が、以前に報告されたものと同じ属性で取得された場合、新しいカーディナリティはカウントされません。
カーディナリティの影響
上記のように、キーや値に変更があれば、新しいカーディナリティを表すことになりますが、それらの変更が全体のカーディナリティにどのような影響を与えるかを予測するのは、少し難しいことです。メトリックのカーディナリティは、可能性のある各キーに対するすべての可能性のある値の数の積であると仮定したくなるが、あるキーの値が他のキーの値に依存したり決定したりすることが多いため、実際にはほとんどない。
前の例を使用すると、 container
の値が1
になると、コンテナ ID がグローバルに一意であると仮定して、 host
の値が W
に固定されました。したがって、4 つのホストに 8 つのコンテナーがありますが、カーディナリティは 4 * 8 = 32 ではなく 8 のままです。これは、単純な乗算方法でカウントされるほとんどの組み合わせが不可能であり、そのメトリックのカーディナリティに寄与しないためです。たとえば、 host = 'X', container = 1
の組み合わせは見られません。
これはまた、属性マップにキーを追加しても、必ずしも総カーディナリティが増加するわけではないことを意味します。新しいキーの値が既存のキーの値によって一意に決定される場合、長期的に新しいカーディナリティが追加されることはありません。たとえば、例のマップにregion
のようなものを追加すると、 container
の値も特定の地域の値に固定され、カーディナリティが 8 に保たれる可能性があります。
ここでの重要な注意点は、 region
を追加してもカーディナリティは増加しませんが、最初に追加したときに新しいカーディナリティが導入されることです。これは、キーを追加すると、それらの属性マップがそれより前の属性マップと区別され、その日の合計カーディナリティが一時的に増加するためです。
ワークフローの例とサンプル
カーディナリティの上限に達した場合、状況を改善するために使用できるオプションがいくつかあります。しかし、そうしたくない場合は、どのディメンションがカーディナリティに最も貢献しているかを調べ、価値を提供していないディメンションを削除することを検討するのが良い方法です。これにより、ストレージと帯域幅のコストを削減し、制限値を上げる必要がなくなる可能性があります。
カーディナリティ・コントリビューターの検索:メトリクス
特定のメトリックのカーディナリティを取得する方法を思い出してください。
FROM Metric SELECT cardinality(memory.heap) SINCE today RAW
アカウントの合計カーディナリティについては、同じ基本的なクエリ構造を使用し、単にメトリック名を省略することができます。
FROM Metric SELECT cardinality() SINCE today RAW
アカウントのカーディナリティは基本的に各指標のカーディナリティの合計であるため、単純な FACET
クエリを追加すると、最高のカーディナリティ メトリックを見つけるのに役立ちます。
FROM Metric SELECT cardinality() SINCE today RAW FACET metricName
最後に、カーディナリティ制限の 1 つに達したと思われる場合は、関連するNrIntegrationError
をチェックすることでこれを確認できます。
FROM NrIntegrationError SELECT count(*) WHERE name = 'CardinalityViolationException' AND newRelicFeature = 'Metrics' FACET cardinalityLimitType, metricName, message SINCE today
カーディナリティ貢献者の発見:ディメンション
調査したいメトリックを決定したら、次のステップは、あるメトリックのどのディメンションがそのカーディナリティに最も貢献しているかを決定することです。ディメンションの値に慣れていない場合は、次のようにして見ることができます。
FROM Metric SELECT dimensions() WHERE metricName = 'memory.heap' SINCE today RAW
ここでは、JSON 結果ビューを使用することをお勧めします。これらに目を通すと、ユニークなIDやその他の高度に可変な値を含むディメンションが見つかり、削除する価値があるかもしれません。
属性が取り得る値にすでに精通している場合は、 keySet()
の結果を簡単に調べることができます。
FROM Metric SELECT keySet() WHERE metricName = 'memory.heap' SINCE today RAW
カーディナリティの合計に最も影響を与えるディメンションを理解するには、各キーの値が互いにどのように相関しているかを理解する必要があります。あるディメンションを除外リストに追加するだけで、そのディメンションがない場合のカーディナリティを試すことができます。
FROM Metric SELECT cardinality(memory.heap, exclude: {'container.id'}) SINCE today RAW
同様に、クエリのコンテキストに合わせて、インクルードリストも用意されています。
FROM Metric SELECT cardinality(memory.heap, include: {'host.name', 'region'}) SINCE today RAW
カーディナリティを管理することは、概念的には難しいことですが、上記の方法は、"どのメトリックが最もカーディナリティに寄与しているか?" や"ある属性がそのカーディナリティの合計に対してどのような影響を与えているか?" といった質問に対する答えを得るのに役立ちます。
カーディナリティは最もユニークな値を追跡する場合が多く、その値は他の属性が取り得る値を特定することができるからです。しかし、一握りの属性の可能な組み合わせが爆発的に増えることで、カーディナリティの合計が大きくなるケースも多々あります。一般的には、一意の識別子のようなものから始めるのが良いでしょうが、単一のキーではなく、2つ以上のキーの組み合わせである場合もあります。データとそれを生成するシステムに精通していればいるほど、どの属性を含めるべきか、あるいは除外すべきかを簡単に把握することができます。
カーディナリティ制限の調整
メトリクスが高いカーディナリティで識別され、そのカーディナリティの有効な使用法であると判断されると、発生する可能性のある制限を緩和するためにいくつかの調整が可能になります。 特定のメトリクス名のカーディナリティを増やすには、 NerdGraph APIを使用できます。 以下に、NerdGraph リクエストの例をいくつか示します。
API を使用してカーディナリティ制限を調整する前に、カーディナリティに影響を与える要因を確認してください。
ヒント
Metric APIの制限やトラブルシューティングについて詳しく知りたい方は、こちらの2つの資料をご参照ください。
- メトリックAPIの制限と制限された属性
- Troubleshoot Metric API with NRIntegrationError events は、どちらも素晴らしい資料ですので、ぜひご覧ください。