근사 히스토그램 애그리게이터

근사 히스토그램 애그리게이터 (Approximate Histogram aggregators)

근사 히스토그램 애그리게이터와 고정 버킷(fixed buckets) 히스토그램 애그리게이터를 제공하는 확장 기능이에요. 분포를 근사적으로 요약해 분위수, 최소/최대 등을 계산할 수 있어요.

출처: 문서

본문

⚠️ caution

Approximate Histogram 애그리게이터는 더 이상 사용되지 않아요(deprecated). 분포에 무관(distribution-independent)하고 공식적인 오차 보장이 있는 우수한 알고리즘을 제공하는 DataSketches Quantiles를 대신 사용하세요.

이 Apache Druid 확장 기능을 사용하려면 extensions load list에 druid-histogram을 포함하세요.

druid-histogram 확장 기능은 근사 히스토그램 애그리게이터와 고정 버킷 히스토그램 애그리게이터를 제공해요.

근사 히스토그램 애그리게이터 (Approximate Histogram aggregator)

이 애그리게이터는 이 논문을 기반으로 근사 히스토그램을 계산하며, 다음과 같은 수정 사항이 있어요:

  • 정확성을 일부 희생해 속도를 높였어요(아래 참고).
  • 스케치는 고유 데이터 포인트 수가 resolutions(centroids 수)보다 적은 동안 정확한 원본 데이터를 유지해, 데이터 포인트가 적을 때 또는 이산 데이터 포인트를 다룰 때 정확도를 높여요. 자세한 내용은 이 포스트에서 확인할 수 있어요.

근사 히스토그램을 사용하기 전에 알아두어야 할 몇 가지:

  • 원래 논문에서도 언급되듯이 근사에 대한 공식적인 오차 경계는 없어요. 실제로 분포가 왜곡(skewed)되면 근사가 나빠져요.
  • 이 알고리즘은 순서 의존적(order-dependent)이라 결과가 병합되는 순서의 변동으로 인해 동일한 쿼리에서도 결과가 달라질 수 있어요.
  • 일반적으로 이 알고리즘은 오는 데이터가 무작위로 분포된 경우에만 잘 작동해요(예: 데이터 포인트가 컬럼에 정렬되어 끝난다면 근사가 형편없어질 거예요).
  • 우리는 집계 속도를 위해 정확성을 교환했는데, 히스토그램을 합칠 때 몇 가지 지름길을 사용해요. 데이터가 어떤 방식으로든 정렬되어 있거나 분포에 긴 꼬리(long tails)가 있으면 병리적인 경우로 이어질 수 있어요. 필요한 정확도를 얻기 위해 스케치의 resolution을 높이는 것이 더 저렴할 거예요.

그렇긴 해도, 이 스케치는 평균이 충분하지 않을 때 1차 근사(First order approximation)를 얻는 데 유용할 수 있어요. 세그먼트의 대부분 행이 히스토그램 resolution보다 적은 데이터 포인트를 저장한다고 가정하면, 모니터링 목적으로 사용해 수백 개의 centroids로 의미 있는 변동을 감지할 수 있어야 해요. 수백만 행 데이터의 95번째 백분위수에서 정확한 판독값을 얻으려면 특히 긴 꼬리가 있는 경우 수천 개의 centroids를 사용하는 것이 좋아요. 근사가 나빠지는 곳이기 때문이에요.

인제이션 시점에 근사 히스토그램 스케치 생성 (Creating approximate histogram sketches at ingestion time)

이 기능을 사용하려면 인덱싱 시점에 approxHistogram 또는 approxHistogramFold 애그리게이터를 포함해야 해요. 인제이션 애그리게이터는 숫자 값에만 적용할 수 있어요. approxHistogram을 사용하면 값이 없는 입력 행은 값이 0인 것으로 간주되지만, approxHistogramFold를 사용하면 그러한 행은 무시돼요.

결과를 조회하려면 쿼리에 approxHistogramFold 애그리게이터를 포함해야 해요.

{
  "type" : "approxHistogram or approxHistogramFold (at ingestion time), approxHistogramFold (at query time)",
  "name" : <output_name>,
  "fieldName" : <metric_name>,
  "resolution" : <integer>,
  "numBuckets" : <integer>,
  "lowerLimit" : <float>,
  "upperLimit" : <float>
}

| Property | Description | Default | | resolution | Number of centroids (data points) to store. The higher the resolution, the more accurate results are, but the slower the computation will be. | 50 | | numBuckets | Number of output buckets for the resulting histogram. Bucket intervals are dynamic, based on the range of the underlying data. Use a post-aggregator to have finer control over the bucketing scheme | 7 | | lowerLimit / upperLimit | Restrict the approximation to the given range. The values outside this range will be aggregated into two centroids. Counts of values outside this range are still maintained. | -INF/+INF | | finalizeAsBase64Binary | If true, the finalized aggregator value will be a Base64-encoded byte array containing the serialized form of the histogram. If false, the finalized aggregator value will be a JSON representation of the histogram. | false |

고정 버킷 히스토그램 (Fixed Buckets Histogram)

고정 버킷 히스토그램 애그리게이터는 지정된 값 범위에 걸쳐 균등한 크기의 버킷으로 숫자 컬럼에 히스토그램을 만듭니다. 범위 밖의 값은 사용자가 지정한 이상치(outlier) 처리 모드에 따라 처리돼요.

이 히스토그램은 min/max/quantiles post-aggregator를 지원하지만 bucketing post-aggregator는 지원하지 않아요.

사용 시기 (When to use)

고정 버킷 히스토그램의 정확성/유용성은 데이터에 크게 의존해요. 집계되는 데이터에 대해 많은 사전 정보를 가지고 있고 고정 버킷 구현이 적합하다는 것을 아는 특수 사용 사례를 지원하기 위해 제공돼요.

일반적인 히스토그램 및 분위수 사용 사례에는 DataSketches Quantiles Sketch 확장 기능을 권장해요.

속성 (Properties)

| Property | Description | Default | | type | Type of the aggregator. Must fixedBucketsHistogram . | No default, must be specified | | name | Column name for the aggregator. | No default, must be specified | | fieldName | Column name of the input to the aggregator. | No default, must be specified | | lowerLimit | Lower limit of the histogram. | No default, must be specified | | upperLimit | Upper limit of the histogram. | No default, must be specified | | numBuckets | Number of buckets for the histogram. The range [lowerLimit, upperLimit] will be divided into numBuckets intervals of equal size. | 10 | | outlierHandlingMode | Specifies how values outside of [lowerLimit, upperLimit] will be handled. Supported modes are "ignore", "overflow", and "clip". See outlier handling modes for more details. | No default, must be specified | | finalizeAsBase64Binary | If true, the finalized aggregator value will be a Base64-encoded byte array containing the serialized form of the histogram. If false, the finalized aggregator value will be a JSON representation of the histogram. | false |

애그리게이터 스펙 예시는 아래와 같아요:

{
  "type" : "fixedBucketsHistogram",
  "name" : <output_name>,
  "fieldName" : <metric_name>,
  "numBuckets" : <integer>,
  "lowerLimit" : <double>,
  "upperLimit" : <double>,
  "outlierHandlingMode": <mode>
}

이상치 처리 모드 (Outlier handling modes)

이상치 처리 모드는 히스토그램 범위 밖의 값을 어떻게 처리할지 지정해요. 세 가지 지원 모드가 있어요:

  • ignore : 이상치 값을 버린다.
  • overflow : 이상치 값의 개수를 히스토그램이 추적하며, lowerOutlierCount와 upperOutlierCount 필드에서 사용할 수 있다.
  • clip : 이상치 값을 lowerLimit 또는 upperLimit에 클리핑해 히스토그램에 포함한다.

이상치에 상관없다면 ignore가 성능상 가장 저렴한 옵션이에요. 현재 모드 간 저장 크기 차이는 없어요.

출력 필드 (Output fields)

히스토그램 애그리게이터의 출력 객체는 다음 필드를 가져요:

  • lowerLimit : 히스토그램의 하한
  • upperLimit : 히스토그램의 상한
  • numBuckets : 히스토그램 버킷 수
  • outlierHandlingMode : 이상치 처리 모드
  • count : 이상치를 제외한 히스토그램에 포함된 총 값 수
  • lowerOutlierCount : lowerLimit 아래의 이상치 값 수. 이상치 모드가 overflow인 경우에만 사용된다.
  • upperOutlierCount : upperLimit 위의 이상치 값 수. 이상치 모드가 overflow인 경우에만 사용된다.
  • missingValueCount : 히스토그램이 본 null 값 수.
  • max : 히스토그램이 본 최대 값. 이상치 값은 포함하지 않는다.
  • min : 히스토그램이 본 최소 값. 이상치 값은 포함하지 않는다.
  • histogram : numBuckets 크기의 longs 배열로, 버킷 개수를 포함한다.

기존 히스토그램 인제스트 (Ingesting existing histograms)

기존 고정 버킷 히스토그램을 인제스트하는 것도 가능해요. 입력은 직렬화된 히스토그램 객체를 포함한 바이트 배열을 인코딩한 Base64 문자열이어야 해요. "full"과 "sparse" 형식 모두 사용할 수 있어요. 자세한 내용은 아래의 Serialization formats를 참고하세요.

직렬화 형식 (Serialization formats)

전체 직렬화 형식 (Full serialization format)

이 형식은 직렬화 형식에 전체 히스토그램 버킷 개수 배열을 포함해요.

byte: serialization version, must be 0x01
byte: encoding mode, 0x01 for full
double: lowerLimit
double: upperLimit
int: numBuckets
byte: outlier handling mode (0x00 for `ignore`, 0x01 for `overflow`, and 0x02 for `clip`)
long: count, total number of values contained in the histogram, excluding outliers
long: lowerOutlierCount
long: upperOutlierCount
long: missingValueCount
double: max
double: min
array of longs: bucket counts for the histogram
희소 직렬화 형식 (Sparse serialization format)

이 형식은 히스토그램 버킷 개수를 (bucketNum, count) 쌍으로 나타내요. 이 직렬화 형식은 히스토그램 버킷의 절반 미만이 값을 가질 때 사용돼요.

byte: serialization version, must be 0x01
byte: encoding mode, 0x02 for sparse
double: lowerLimit
double: upperLimit
int: numBuckets
byte: outlier handling mode (0x00 for `ignore`, 0x01 for `overflow`, and 0x02 for `clip`)
long: count, total number of values contained in the histogram, excluding outliers
long: lowerOutlierCount
long: upperOutlierCount
long: missingValueCount
double: max
double: min
int: number of following (bucketNum, count) pairs
sequence of (int, long) pairs:
  int: bucket number
  count: bucket count

다른 버킷 구성 체계를 가진 히스토그램 결합 (Combining histograms with different bucketing schemes)

버킷 구성 체계(lowerLimit, upperLimit, numBuckets)가 서로 다른 두 히스토그램을 결합할 수 있어요.

"왼쪽(left hand)" 히스토그램의 버킷 구성 체계가 보존돼요(즉, 쿼리를 실행할 때 쿼리의 히스토그램 애그리게이터에 지정된 버킷 구성 체계가 보존돼요).

병합 시 우리는 "오른쪽(right hand)" 히스토그램의 버킷 안에 값들이 균등하게 분포된다고 가정해요.

오른쪽 히스토그램이 이상치를 포함할 때(overflow 모드 사용 시), 우리는 오른쪽 히스토그램에서 개수 세어진 모든 이상치가 왼쪽 히스토그램에서도 이상치일 것이라고 가정해요.

성능과 정확성 이유로, 가능하면 서로 다른 버킷 구성 체계를 가진 히스토그램의 집계는 피하는 것을 권장해요.

null 처리 (Null handling)

Druid는 히스토그램의 missingValueCount 필드에 null 값을 추적해요.

히스토그램 post-aggregator (Histogram post-aggregators)

Post-aggregator는 불투명한 근사 히스토그램 스케치를 버킷화된 히스토그램 표현으로 변환하고, 분위수, min, max와 같은 다양한 분포 메트릭을 계산하는 데 사용돼요.

동일 버킷 post-aggregator (Equal buckets post-aggregator)

주어진 수의 동일 크기 빈(bins)으로 근사 히스토그램의 시각적 표현을 계산해요. 버킷 간격은 기본 데이터의 범위를 기반으로 해요. 이 aggregator는 고정 버킷 히스토그램에서는 지원되지 않아요.

{
  "type": "equalBuckets",
  "name": "<output_name>",
  "fieldName": "<aggregator_name>",
  "numBuckets": <count>
}

Buckets post-aggregator

주어진 초기 중단점(breakpoint), 오프셋(offset), 버킷 크기로 시각적 표현을 계산해요.

  • 버킷 크기(bucketSize)는 빈(binning) 간격의 너비를 결정해요.
  • 오프셋(offset)은 해당 간격 빈들이 정렬되는 값을 결정해요.

이 aggregator는 고정 버킷 히스토그램에서는 지원되지 않아요.

{
  "type": "buckets",
  "name": "<output_name>",
  "fieldName": "<aggregator_name>",
  "bucketSize": <bucket_size>,
  "offset": <offset>
}

사용자 정의 버킷 post-aggregator (Custom buckets post-aggregator)

주어진 breaks에 따라 배치된 빈으로 근사 히스토그램의 시각적 표현을 계산해요.

이 aggregator는 고정 버킷 히스토그램에서는 지원되지 않아요.

{ "type" : "customBuckets", "name" : <output_name>, "fieldName" : <aggregator_name>,
  "breaks" : [ <value>, <value>, ... ] }

min post-aggregator

기반이 되는 근사 또는 고정 버킷 히스토그램 aggregator의 최소값을 반환해요.

{ "type" : "min", "name" : <output_name>, "fieldName" : <aggregator_name> }

max post-aggregator

기반이 되는 근사 또는 고정 버킷 히스토그램 aggregator의 최대값을 반환해요.

{ "type" : "max", "name" : <output_name>, "fieldName" : <aggregator_name> }
quantile post-aggregator

기반이 되는 근사 또는 고정 버킷 히스토그램 aggregator를 기반으로 단일 분위수를 계산해요.

{ "type" : "quantile", "name" : <output_name>, "fieldName" : <aggregator_name>,
  "probability" : <quantile> }
quantiles post-aggregator

기반이 되는 근사 또는 고정 버킷 히스토그램 aggregator를 기반으로 분위수 배열을 계산해요.

{ "type" : "quantiles", "name" : <output_name>, "fieldName" : <aggregator_name>,
  "probabilities" : [ <quantile>, <quantile>, ... ] }

더 알아보기 (Learn more)