[Grafana Loki] 쿼리 엔진 aggregator의 자료구조를 개선하여 38% 성능 향상
PR 링크: grafana/loki#20934 상태: Merged | 변경: +45 / -62
들어가며
Grafana Loki의 쿼리 엔진에서 aggregator는 벡터 집계와 범위 집계 모두에 사용되는 핵심 컴포넌트입니다. 이 PR은 세 가지 자료구조 최적화로 메트릭 쿼리 전체 테스트 스위트 실행 시간을 1분 1초에서 38초로 38% 단축했습니다.
핵심 코드 분석
Before: groupState에 라벨 데이터 포함 + 리스트 기반 라벨 관리
type groupState struct {
value float64
count int64
labels []arrow.Field // 매 그룹마다 라벨 필드 복사
labelValues []string // 매 그룹마다 라벨 값 복사
}
type aggregator struct {
labels []arrow.Field // 리스트 기반
uniqueSeries map[uint64]struct{} // 키만 저장
}
// AddLabels: O(n*m) 중복 검사
func (a *aggregator) AddLabels(labels []arrow.Field) {
for _, label := range labels {
if !slices.ContainsFunc(a.labels, func(l arrow.Field) bool {
return label.Equal(l)
}) {
a.labels = append(a.labels, label)
}
}
}
// BuildRecord: O(labels * groups) 선형 탐색
for i, label := range a.labels {
j := slices.IndexFunc(entry.labels, func(l arrow.Field) bool {
return l.Name == label.Name
})
// ...
}
After: 라벨 데이터 분리 + 맵 기반 관리
type groupState struct {
value float64 // 집계 값만 보유
count int64
}
type aggregator struct {
labels map[string]arrow.Field // 맵 기반 O(1) 조회
uniqueSeries map[uint64]map[string]string // 시리즈별 라벨 값 저장
}
// AddLabels: O(1) 중복 검사
func (a *aggregator) AddLabels(labels []arrow.Field) {
for _, label := range labels {
if _, ok := a.labels[label.Name]; !ok {
a.labels[label.Name] = label
}
}
}
// BuildRecord: O(1) 맵 조회
series := a.uniqueSeries[key]
for i := 2; i < len(fields); i++ {
if v, ok := series[fields[i].Name]; ok {
builder.(*array.StringBuilder).Append(v)
} else {
builder.(*array.StringBuilder).AppendNull()
}
}
왜 이게 좋은가
- 38% 성능 향상: 메트릭 쿼리 전체 테스트 실행 시간이 1분 1초에서 38초로 단축됩니다.
- O(n*m) -> O(1):
BuildRecord에서 라벨 이름별 선형 탐색이 맵 조회로 대체됩니다. - 메모리 효율: 매
groupState마다 라벨 필드와 값을 복사하지 않고, 시리즈 단위로 한 번만 저장합니다. - 중복 저장 제거: 같은 시리즈의 서로 다른 타임스탬프에 대해 라벨 값이 한 번만 저장됩니다.
- 실행 시간 측정 수정: 범위/벡터 집계에서
BuildRecord시간이cap측정에 포함되지 않던 버그도 함께 수정되었습니다.
참고 자료
관련 포스트
PR Analysis 의 다른글
- 이전글 [triton] AMD Batched WMMA Scaled에서 스케일 레이아웃 수정
- 현재글 : [Grafana Loki] 쿼리 엔진 aggregator의 자료구조를 개선하여 38% 성능 향상
- 다음글 [pytorch] MPS: 2-pass SDPA의 메모리 손상을 float accumulator 강제로 수정
댓글