Elasticsearch는 중복 제거 후 수를 계산합니다.

중복 제거 후 숫자 계산

Elasticsearch에서 제공하는 첫 번째 대략적인 집계는  cardinality (참고 : 카디널리티) 메트릭입니다. 필드의 카디널리티, 즉 필드의 고유  하거나  고유 한  값의 수를 제공합니다  . SQL 형식에 익숙 할 수 있습니다.


자동차에서 COUNT (DISTINCT 색상) 선택

중복 제거는 많은 기본적인 비즈니스 질문에 답할 수있는 매우 일반적인 작업입니다.

  • 웹 사이트의 순 방문자 수는 몇 명입니까?
  • 몇 대의 자동차가 판매됩니까?
  • 매월 몇 명의 순 사용자가 상품을 구매합니까?

cardinality 메트릭을 사용하여 딜러가 판매 하는 자동차 색상 수를 결정할 수 있습니다  .

GET / cars / transactions / _search 
{ 
    "size": 0, 
    "aggs": { 
        "distinct_colors": { 
            "cardinality": { 
              "field": "color" 
            } 
        } 
    } 
}

Sense에서 보려면 cURL 복사 

반환 된 결과는 세 가지 색상의 자동차가 판매되었음을 나타냅니다.

... 
"집계": { 
  "distinct_colors": { 
     "값": 3 
  } 
} 
...

우리의 예를 더 유용하게 만들 수 있습니다. 매달 얼마나 많은 컬러 자동차가 판매됩니까? 이 측정 항목을 얻으 cardinality 려면 하나의 측정 항목 삽입  하면됩니다  date_histogram .

GET / cars / transactions / _search 
{ 
  "size": 0, 
  "aggs": { 
      "months": { 
        "date_histogram": { 
          "field": "sold", 
          "interval": "month" 
        }, 
        "aggs": { 
          "distinct_colors": { 
              "카디널리티": { 
                "field": "color" 
              } 
          } 
        } 
      } 
  } 
}

Sense에서 보려면 cURL 복사 

무게를 배워라

이 장의 시작 부분에서 언급했듯이  cardinality 메트릭은 대략적인 알고리즘입니다.  HLL ( HyperLogLog ++ ) 알고리즘을 기반으로합니다  . HLL은 먼저 입력을 해시 한 다음 해시 연산 결과의 비트를 기반으로 확률을 추정하여 기준을 얻습니다.

기술적 인 세부 사항을 이해할 필요는 없지만 (정말 관심이 있다면이 문서를 읽을 수 있습니다),이 알고리즘의 특성에 더주의를 기울여야합니다   .

  • 메모리 사용량을 제어하는 ​​데 사용되는 구성 가능한 정밀도 (더 많은 정밀도 = 더 많은 메모리).
  • 작은 데이터 세트의 정확도는 매우 높습니다.
  • 구성 매개 변수를 통해 중복 제거에 필요한 고정 메모리 사용량을 설정할 수 있습니다. 수천 또는 수십억의 고유 한 값에 관계없이 메모리 사용량은 구성의 정확성과 만 관련이 있습니다.

정밀도를 구성하려면 precision_threshold 매개 변수 값을 지정해야합니다  . 이 임계 값은 거의 정확한 결과를 얻기를 원하는 기본 수준을 정의합니다. 다음 예를 고려하십시오.

GET / cars / transactions / _search 
{ 
    "size": 0, 
    "aggs": { 
        "distinct_colors": { 
            "cardinality": { 
              "field": "color", 
              "precision_threshold": 100 
            } 
        } 
    } 
}

Sense에서 보려면 cURL 복사 

 

precision_threshold 0에서 40,000 사이의 숫자를 허용하면 더 큰 값은 여전히 ​​40,000으로 처리됩니다.

이 예제는 필드의 고유 값이 100 이내 일 때 매우 정확한 결과를 얻을 수 있도록합니다. 알고리즘이이를 보장 할 수는 없지만 카디널리티가 임계 값 미만이면 거의 항상 100 % 정확합니다. 임계 값을 초과하는 기본 숫자는 정확도를 희생하면서 메모리를 절약하기 시작하고 측정 결과에 오류를 유발합니다.

지정된 임계 값에 대해 HLL 데이터 구조는 아마도  precision_threshold * 8 바이트의 메모리를 사용하므로 메모리 희생의 균형을 맞추고 추가 정확도를 얻는 것이 필요합니다.

실제 애플리케이션  100 에서 임계 값은 고유 값이 100 만인 경우에도 오류를 5 % 이내로 유지할 수 있습니다.

속도 최적화

고유 한 값의 수를 얻으려면  일반적으로  전체 데이터 세트 (또는 거의 모든 데이터)를 쿼리해야합니다. 모든 데이터를 기반으로 한 모든 작업은 빨라야하며 그 이유는 분명합니다. HyperLogLog의 속도는 이미 매우 빠르며 단순히 데이터를 해시하고 일부 비트 작업을 수행합니다.

하지만 속도가 중요하다면 추가 최적화를 할 수 있습니다. HLL은 필드 콘텐츠의 해시 값만 필요하므로 인덱싱 할 때 미리 계산할 수 있습니다. 쿼리 중에 해시 계산을 건너 뛰고 필드 데이터에서 직접 해시 값을로드 할 수 있습니다.

해시 값을 미리 계산하는 것은 내용이 매우 길거나 카디널리티가 높은 필드에만 유용합니다. 이러한 필드의 해시 값 계산 비용은 쿼리 중에 무시할 수 없습니다.

숫자 필드의 해시 계산은 매우 빠르지 만 원래 값을 저장하려면 일반적으로 동일하거나 더 적은 메모리 공간이 필요합니다. 카디널리티가 낮은 문자열 필드에도 적용 할 수 있습니다 .Elasticsearch의 내부 최적화를 통해 각 고유 값이 한 번만 해시되도록 할 수 있습니다.

기본적으로 사전 계산은 모든 필드가 더 빠르다고 보장하지 않으며 카디널리티가 높거나 콘텐츠가 매우 긴 문자열 필드에서만 작동합니다. 기억해야 할 것은 사전 계산은 단순히 질의에 소요되는 시간을 사전에 인덱스로 전송한다는 것입니다. 비용이 들지 않는 것은 아닙니다. 차이점은  인덱싱 중 또는 질의 중에 언제 수행 할지 선택할 수 있다는 것  입니다.

이렇게하려면 데이터에 새 다중 값 필드를 추가해야합니다. 먼저 인덱스를 삭제하고 해시 값 필드를 포함하는 매핑을 추가 한 다음 다시 인덱싱합니다.

DELETE / cars / 

PUT / cars / 
{ 
  "mappings": { 
    "transactions": { 
      "properties": { 
        "color": { 
          "type": "string", 
          "fields": { 
            "hash": { 
              "type" : "murmur3" 
            } 
          } 
        } 
      } 
    } 
  } 
} 

POST / cars / transactions / _bulk 
{ "index": {}} 
{ "price": 10000, "color": "red", "make": "honda", " sold ":"2014-10-28 "} 
{"색인 ":{}} 
{ "가격": 20000, "color": "red", "make": "honda", "sold": "2014-11-05"} 
{ "index": {}}
{ "price": 30000, "color": "green", "make": "ford", "sold": "2014-05-18"} 
{ "index": {}} 
{ "price": 15000, "color": "blue", "make": "toyota", "sold": "2014-07-02"} 
{ "index": {}} 
{ "price": 12000, "color": "green" , "make": "toyota", "sold": "2014-08-19"} 
{ "index": {}} 
{ "price": 20000, "color": "red", "make": "honda ","sold ":"2014-11-05 "} 
{"index ": {}} 
{"price ": 80000,"color ":"red ","make": "bmw", "sold": "2014-01-01"} 
{ "index": {}} 
{ "price": 25000, "color": "blue", "make": "ford" , "sold": "2014-02-12"}

Sense에서 보려면 cURL 복사 

 

다중 값 필드의 유형은  murmur3 이것이 해시 함수라는 것입니다.

이제 집계를 수행 할 때 color.hash 필드 대신 필드를  사용  color 합니다.

GET / cars / transactions / _search 
{ 
    "size": 0, 
    "aggs": { 
        "distinct_colors": { 
            "cardinality": { 
              "field": "color.hash" 
            } 
        } 
    } 
}

Sense에서 보려면 cURL 복사 

 

원래 필드가 아닌 해시 된 다중 값 필드를 지정합니다.

이제  cardinality 메트릭은 "color.hash" 원래 값의 해시를 동적으로 계산하는 대신 (미리 계산 된 해시 값)의 값을 읽습니다  .

단일 문서로 절약되는 시간은 매우 적지 만 1 억 개의 데이터를 집계하고 각 필드에 10 나노초가 추가로 걸리면 각 쿼리에 1 초가 추가됩니다. 매우 많은 양의 데이터를 사용하려는 경우 을 사용  cardinality 하면 사전에 해시를 계산해야하는지 여부에 따라 사전 계산 사용의 중요성을 평가할 수 있습니다. 그러면 쿼리에서 더 나은 성능을 얻기 위해 몇 가지 성능 테스트를 수행하여 사전 계산 된 해시가 응용 프로그램 시나리오에 적합한 지 확인합니다. .

추천

출처blog.csdn.net/allway2/article/details/109182858