Elasticsearch cardinalityメトリック誤差実測

2376 ワード

cardinalityメトリックは近似アルゴリズムである.HyperLogLog++(HLL)アルゴリズムに基づいています.HLLは、まず私たちの入力をハッシュ演算し、ハッシュ演算の結果のbitsに基づいて確率推定を行い、基数を得る.技術の詳細を理解する必要はありません(確かに興味があれば、この論文を読むことができます).しかし、メモリの使用を制御するために構成可能な精度(より正確な=より多くのメモリ)というアルゴリズムの特性に注目したほうがいいです.小さなデータセットの精度は非常に高い.パラメータを構成することで、必要な固定メモリの使用量を設定できます.数千億ドルまたは数十億ドルの一意の値にかかわらず、メモリの使用量は構成の精度にのみ関連しています.精度を構成するにはprecision_を指定する必要があります.thresholdパラメータの値.このしきい値は,どの基数レベルでほぼ正確な結果を得ることを望んでいるかを定義する.次の例を参照してください:precision_thresholdは0-40000の間の数字を受け入れ、より大きな値は40000として処理されます.例では、フィールドの一意の値が100以内であることを確認します.アルゴリズムはこの点を保証できないが,基数がしきい値以下であれば,ほぼ常に100%正しい.しきい値より高い基数は、メモリの節約を開始し、精度を犠牲にし、メトリック結果に誤差をもたらします.指定したしきい値の場合、HLLのデータ構造はprecision_を使用します.threshold*8バイトのメモリなので、メモリの犠牲と追加の精度のバランスをとる必要があります.実際の応用では、100のしきい値は、一意の値が百万の場合でも誤差を5%以内に維持することができる.
公式ドキュメントの説明です
実際、私のリクエストテストでは、ドキュメントが多い場合、この誤差はかなり大きいです:Req
POST /xxx/_search
{
    "size" : 0,
    "aggs" : {
        "distinc_count" : {
            "cardinality" : {
                "field" : "xx.keyword",
                "precision_threshold": 100
            }
        }
    }
}

Resp
{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 2,
    "successful": 2,
    "failed": 0
  },
  "hits": {
    "total": 570470,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "distinc_count": {
      "value": 11158
    }
  }
}

Req
POST /xxx/_search
{
    "size" : 0,
    "aggs" : {
        "distinc_count" : {
            "cardinality" : {
                "field" : "xx.keyword",
                "precision_threshold": 10000
            }
        }
    }
}

Resp
{
  "took": 3,
  "timed_out": false,
  "_shards": {
    "total": 2,
    "successful": 2,
    "failed": 0
  },
  "hits": {
    "total": 570470,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "distinc_count": {
      "value": 10736
    }
  }
}

precisionの向上thresholdは、高い精度推定精度が得られ、時間がかかるのは当然点も向上した(以前に要求されたので、キャッシュがあり、こんなに低い遅延は、正常に数十ミリ秒であるはずだ).精度が10000になると、ほとんど誤差がありません.