• ログイン今すぐ開始

本書は、お客様のご参考のために原文の英語版を機械翻訳したものです。

英語版と齟齬がある場合、英語版の定めが優先するものとします。より詳しい情報については、本リンクをご参照ください。

問題を作成する

NRQL percentile()の改善

テレメトリでは、パーセンタイルは多くのアプリケーションで使用される重要な統計的測定です。しかし、大規模なデータセットを扱う人にとっては難題でもあります。" というのも、パーセンタイルを計算する標準的な方法は、データをソートする必要があるため、技術的にも"高価なものとなっています。

新しい percentile() 関数は、最小限のコストで、任意の大規模なデータセットに対応します。また、長尾分布にも優れています。0%から100%までのパーセンタイルに対して、その相対的な誤差の一貫性が保証されています。

ユーザーとしては、新しいアルゴリズムを手に入れるために何もする必要はありません。 percentile() の呼び出しはすべて、このアルゴリズムを使って自動的に実行されます。しかし、新しい percentile() 関数がどのように開発されたのか、また以前に使用されていた方法と比べてどのように優れているのかについて詳しく知りたい方は、New Relic の変更点とその根拠についての深読みをしてください。

エラーの種類と報告データへの影響

最近まで、New Relic は Quantiles over Data Streams で説明されている方法に頼っていました。An Experimental Study で説明されている方法を採用していました。この方法は順位誤差を利用しており、New Relic のパラメータを適用した場合、順位誤差は 0.3% となります。しかし、順位誤差は相対誤差や絶対誤差とは異なる方法で計算されているため、実際の値と報告された値の間には、望ましいものよりもはるかに大きなばらつきがある可能性があります。

さまざまなエラータイプの影響をよりよく理解するために、パーセンタイル計算の文脈でエラータイプを詳しく見てみましょう。 percentile(p) = x.この表は、エラータイプが報告値の下限値と上限値にどのような影響を与えるかを示しています。

エラーの種類

reported_xの下界

reported_xの上界

絶対誤差

actual_x - absolute_error

actual_x + absolute_error

相対誤差

actual_x * (1 - relative_error)

actual_x * (1 + relative_error)

ランクエラー

パーセンタイル * (p - 順位誤差)

パーセンタイル * (p + 順位誤差)

表からわかるように、絶対誤差では、報告値が実際の値の±範囲内にあり、相対誤差では、報告値が実際の値の±パーセント内にあります。

ランクエラーの仕組みは少し異なりますので、具体的な例を挙げて説明します。あるデータセットの99パーセンタイルを要求し、報告された値が500で0.3%のランクエラーだった場合、報告された値がそのデータセットの98.7パーセンタイルと99.3パーセンタイルの範囲内にあることを意味します。

なぜこれが重要なのでしょうか。なぜなら、ランクエラーは、値 x ではなく、パーセンタイル p に対して計算されるため、報告された値が実際の値に特に近いという保証はないからです。ロングテールのテレメトリ分布では、実際の値と報告された値の差が実際には非常に大きくなることがあります。例えば、98.7パーセンタイルに対応する値が1000で、99.3パーセンタイルに対応する値が2000の場合、1000と2000の間で報告された値は、0.3%のランクエラーの仕様を満たしており、かなり大きな誤差が生じています。

この例からわかるように、旧来の方法の精度は、値がパーセンタイル内でどれだけ変化するかに依存します。この方法は、中央値(50%)と90%までは通常適切ですが、99%以上のロングテール分布ではしばしば不足します。

パーセンタイル計算をより正確に

2020年7月、New Relicは、対数スケールの等幅ヒストグラムファミリーとして知られる独自のアルゴリズムを使用する、 percentile() の新しい計算方法をロールアウトしました。このファミリーの他の方法と同様に、相対的なエラー保証を提供します。

つまり、パーセンタイルが1%、99%、99.99%のいずれであっても、報告される値は実際の値の3%以内であることが保証されているのです。これは特にロングテールのトラッキングに適しています。どのようなパーセンタイルを求めても、同じ3%の相対誤差が保たれます。

コントラスト比と相対誤差

コントラスト比は、入力データセット中の最大の数値を、入力データセット中のゼロではない最小の数値で割って算出します。入力に負の数がある場合、コントラスト比は正の数の集合と負の数の集合の絶対値に対して別々に計算されます。最終的なコントラスト比は、正の数と負の数のコントラスト比の大きい方となる。データセットのコントラストが高ければ、相対誤差も大きくなる。

データ処理の観点から"のコストがかかる" の計算を抑制するために、新しいアルゴリズムではヒストグラムのバケット数を制限しています。コントラスト比が1,000~100万のバケット内のデータセットでは、相対誤差が約3%となっています。これでほとんどのお客様のユースケースをカバーできるはずです。下の表は、コントラスト比が1,000以下と100万以上の範囲で、相対誤差にどのような影響があるかを示したもので、スケールとしては、コントラスト比が表現できる時間の長さを示しています。

コントラスト比

相対誤差

持続時間範囲の例

32~1K

1.5635%

1ミリ秒~1秒

1K~1M

3.125%

1ミリ秒~16分

1M~1T(2^40、約10^12)

6.25%

1ミリ秒~31年

1T~2^80(約10^24)

12.5%

1ナノ秒~3,100万年

負の数とゼロ

新しい手法は、正の数、ゼロ、負の数が混在していても対象となります。負の数の相対誤差は、絶対値に基づいて定義されます。コントラストの計算にゼロは含まれません。

安定した測定

新方式では、安定した測定結果が得られます。測定されたデータセットの変化が誤差の範囲内であれば、このメソッドは同じ数値を返します。これは、ユーザーに明確なシグナルを提供します。数値が変化しなければ、測定可能な変化はありません。数値が変化すれば、測定可能な変化があることになります。

一方、従来の方法では、データセットに統計的に有意な変化がない場合でも、異なる数値が返されることがありました。返された数字の違いが測定可能な変化であるかどうかを判断するのは、ユーザーの責任です。その差が誤差よりも大きい場合にのみ、変化は重大なものとなります。

相対誤差の表示

percentile() 呼び出しの相対的なエラーは、NRQL クエリの JSON 結果に relativeError フィールドを介して返されます。グラフィック UI を使用している場合は、結果のメタデータを表示するために JSON 形式に切り替える必要があります。

以下は、3.125%の相対誤差を示す結果メタデータの例です。

"contents": [
{
"function": "percentile",
"attribute": "wallClockTime",
"relativeError": 0.03125,
"thresholds": [
50,
99
]
}

結果検証

新しい手法の精度を確認するために、 histogram() NRQL関数を実行すると、分布の全体像を把握することができます。ヒストグラムを見ることで、報告されたパーセンタイルが意味を持つかどうかを判断することができます。例えば、報告された99%以上のパーセンタイルが期待される1%に近いかどうかを視覚的に推定することができます。 NULL 属性を持つデータセットに対してパーセンタイル・クエリーを実行する場合は注意が必要です。これらの NULL の行はパーセンタイル関数では無視されますが、パーセント関数では総人口にカウントされます。パーセンタイル・クエリ内の where フィルタは、検証クエリにもコピーする必要があります。

パーセンタイルの値とその相対的な誤差を正確に確認するには、以下の方法があります(正の数を想定)。

報告された値を r とし、真の値を t とします。すると、相対誤差 e は次のように定義できます。

e = absolute(r - t) / t

上の式を使って、 r の範囲を t で表し、次に t の範囲を r で表すと以下のようになります。

r > t * (1 - e) => t < r / (1 - e)
r < t * (1 + e) => t > r / (1 + e)

percentile クエリから報告された re を使用して、 t の下限値と上限値を計算するには、以下のような percentage() クエリを使用します。これが可能なのは、 percentage() 関数が近似を使用していないためです。常に正確な結果を返します。

from myEventType SELECT percentage(count(*), where wallClockTime < 188 / (1 + 0.03125)) as 'lower', percentage(count(*), where wallClockTime < 188 / (1 - .03125)) as 'upper' where wallClockTime is not null

この例では、188 は wallClockTime の報告されたパーセンタイルで、90% です。相対誤差は 0.03125 です。返されたクエリ結果は次のとおりです。

lower: 89.54, upper: 90.23

その結果、確かに90%が範囲内に収まっていることがわかりました。言い換えれば、要求された90%パーセンタイルは誤差の範囲内です。これにより、報告された値の正確性が確認されました。

ヒント

events to metrics service のディストリビューション・メトリクス・タイプにも同じアルゴリズムが使用されています。そのため、イベントを直接照会しても、ディストリビューション・メトリクスを介して照会しても、結果は同じように正確になります。

Copyright © 2022 New Relic株式会社。