중복 제거 후 숫자 계산
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 로 복사
|
|
이 예제는 필드의 고유 값이 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 로 복사
|
다중 값 필드의 유형은 |
이제 집계를 수행 할 때 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
하면 사전에 해시를 계산해야하는지 여부에 따라 사전 계산 사용의 중요성을 평가할 수 있습니다. 그러면 쿼리에서 더 나은 성능을 얻기 위해 몇 가지 성능 테스트를 수행하여 사전 계산 된 해시가 응용 프로그램 시나리오에 적합한 지 확인합니다. .