ELK & Elastic Cloud

Aggregation과 클러스터

meellon 2026. 7. 8. 10:10

학습 목표

aggregation검색 hits와 어떻게 다른지, bucket·metric 집계를 구분할 수 있다.

terms·date_histogram으로 로그 건수·시계열 집계 쿼리를 작성할 수 있다.

query + aggs 조합과 keyword·date mapping 요구를 설명할 수 있다.

node·primary shard·replica·routing으로 document가 어느 shard에 가는지 설명할 수 있다.

샤드 수·replica 설계가 용량·가용성·집계 비용에 미치는 영향을 개요 수준에서 설명할 수 있다.

문제 상황

  • 4편 size: 0 없이 ERROR 로그 10만 건을 Kibana에 뿌렸더니 브라우저 멈춤 — 집계가 필요
  • message 필드로 terms 집계했더니 Text fields are not optimisedkeyword 필드만
  • service별 top 10만 보고 싶은데 수백 개 bucket — size·order 미설정
  • 1분 단위 그래프가 필요한데 terms만 씀 — date_histogram on @timestamp
  • index primary 1인데 노드 3대 — shard가 1개라 CPU 한 코어에 몰림
  • replica 없이 노드 1대 장애 — index red, 검색 불가
  • document _id만 알고 어느 shard인지 모름 — routing·_shard 디버깅 필요

앞 편에서 Query DSL로 document를 골랐다. 이번 편은 요약·시계열(aggregation)분산 저장 구조(cluster·shard). Beats 수집은 6편, ILM·샤드 사이징 심화는 13·22편이다.

1. Aggregation이란?

aggregation(집계) — 조건에 맞는 document들을 그룹하거나 통계를 낸다.

  query aggregation
반환 hits (document 목록) buckets·metrics
용도 tail·상세 조회 건수·분포·시계열
Kibana Discover 행 목록 Lens 막대·시간 차트
POST /app-logs/_search
{
  "size": 0,
  "query": { "bool": { "filter": [ ... ] } },
  "aggs": { ... }
}
  • size: 0 — hits 생략, aggs 결과만 (대시보드·알림에 흔함)
  • size: 10 + aggs — 상위 10건 집계 동시 가능
  • 집계는 보통 filter context와 같이 — query로 범위 좁힌 뒤 aggs

Bucket vs Metric

유형 결과
Bucket terms, date_histogram, filters 그룹 (key + doc_count)
Metric avg, sum, max, cardinality 숫자 하나
Pipeline derivative, moving_avg 다른 agg 계산
  • sub-aggregation — bucket 안에 metric·bucket 중첩
  • 3편 — 집계·정렬은 keyword·date·numeric (doc values)

2. terms 집계

keyword 필드 값별 건수.

// code/log-aggregations.json (발췌)
{
  "size": 0,
  "query": {
    "bool": {
      "filter": [
        { "range": { "@timestamp": { "gte": "now-24h" } } }
      ]
    }
  },
  "aggs": {
    "by_level": {
      "terms": {
        "field": "level",
        "size": 10,
        "order": { "_count": "desc" }
      }
    },
    "by_service": {
      "terms": {
        "field": "service",
        "size": 20
      }
    }
  }
}
옵션 역할
field keyword (또는 keyword 서브필드)
size 반환 bucket 상한 (기본 10)
order _count·_key 정렬
min_doc_count 0건 bucket 제외
  • level·service — 3편 mapping keyword
  • message terms — 불가 (text) — message.keyword도 보통 비권장 (카디널리티 폭발)
  • cardinality agg — 고유 trace_id 수 (근사 HLL)

sub-aggregation 예

"aggs": {
  "by_service": {
    "terms": { "field": "service", "size": 10 },
    "aggs": {
      "error_count": {
        "filter": { "term": { "level": "ERROR" } }
      }
    }
  }
}
  • 서비스별 전체 + ERROR만 doc_count

3. date_histogram

시간 축 버킷 — 로그 시계열의 기본.

"aggs": {
  "errors_over_time": {
    "date_histogram": {
      "field": "@timestamp",
      "fixed_interval": "1m",
      "min_doc_count": 0
    },
    "aggs": {
      "by_level": {
        "terms": { "field": "level", "size": 5 }
      }
    }
  }
}
옵션 설명
fixed_interval 1m, 1h, 1d고정 간격
calendar_interval 1M, 1w달력 (월·주)
field date mapping (@timestamp)
extended_bounds 빈 구간도 bucket 유지 (차트 끊김 방지)
  • Kibana 시간 차트 — 내부적으로 date_histogram
  • timezonetime_zone 옵션 (Kibana는 사용자 TZ)
  • interval 너무 촘촘 — bucket 수 폭증·메모리 — 범위에 맞게 조정

4. query와 aggs 함께 쓰기

{
  "size": 0,
  "query": {
    "bool": {
      "filter": [
        { "term": { "level": "ERROR" } },
        { "range": { "@timestamp": { "gte": "now-1h" } } }
      ]
    }
  },
  "aggs": {
    "top_services": {
      "terms": { "field": "service", "size": 5 }
    },
    "per_minute": {
      "date_histogram": {
        "field": "@timestamp",
        "fixed_interval": "1m"
      }
    }
  }
}
  • query — 집계 대상 document 필터 (4편 bool filter 패턴)
  • aggs — 필터된 집합에만 적용
  • post_filter — hits만 추가 필터, aggs에는 미적용 (드물게 사용 — 혼동 주의)
실수 결과
text 필드 terms 실패 또는 fielddata 경고
size 기본 10만 상위 10 서비스 누락
query 없이 전체 agg 전 index 스캔 — 시간 filter 권장

5. 클러스터 구조

cluster — 하나 이상 node마스터 선출·메타데이터·검색 조율로 묶인 단위.

구성 역할
Cluster 전체 ES 배포 단위
Node JVM 프로세스 1개 (서버·Pod)
Index 논리적 document 집합 (app-logs)
Shard index의 물리 분할 (Lucene index)
Primary shard 쓰기 대상 원본
Replica shard primary 복사본 — 읽기·장애 대응
Index app-logs  →  3 primary + 1 replica each  →  6 shard copies
Node A: P0, R1
Node B: P1, R2
Node C: P2, R0
  • primary 수 — index 생성 시 정함 — 줄이기 어려움 (reindex) — 22편 사이징
  • replicanumber_of_replicas런타임 증감 가능 (0 = 복제 없음)
  • green — primary+replica 할당 완료; yellow — replica 미할당; red — primary 일부 없음

노드 역할 (개요)

역할 하는 일
master-eligible 클러스터 상태·index 생성·shard 할당
data shard 보유·쿼리·인덱싱 실행
ingest ingest pipeline (8편)
coordinating 클라이언트 요청 fan-out·결과 병합 (모든 node가 가능)
  • 소규모 — data + master 겸용 node
  • Elastic Cloud — 역할·용량 프리셋 (16편)

6. Routing

document가 어느 primary shard에 들어가는지 결정.

shard_num = hash(routing) % number_of_primary_shards
routing 값 기본
명시 _routing 지정 값
생략 _id
# 같은 order_id는 같은 shard (커스텀 routing)
PUT /app-logs/_doc/1?routing=9001
{ "order_id": 9001, "message": "..." }

GET /app-logs/_search?routing=9001
  • 같은 routing — 한 shard에 모임 — 조회 지역성 (해당 shard만 검색)
  • routing 남용 — shard 불균형 (hot shard)
  • _search 응답 hits.hits[]._shard어느 shard에서 왔는지

집계와 shard

  • coordinating node가 각 shard에 요청 → partial agg → 병합
  • shard 많을수록 — 병렬·오버헤드 트레이드오프
  • too many shards — 클러스터 메타·메모리 부담 — 22편

7. 실무 체크리스트

항목 습관
대시보드 수치 aggs + size: 0
그룹 필드 keyword mapping (3편)
시계열 date_histogram on @timestamp
시간 범위 query filter로 먼저 좁히기
primary shard 생성 전 용량·노드 수 계획
replica prod ≥ 1 (가용성)
routing 필요할 때만 — 균형 모니터링
  • shard 사이징·ILM rollover — 13·22편
  • 6편 — Filebeat가 index에 document 어떻게 넣는지

정리

  • aggregation — hits 대신 bucket·metric; 로그 운영은 terms·date_histogram
  • keyword·date mapping과 — text로 terms 불가
  • cluster — node·primary/replica shard로 분산
  • routing — primary shard 선택; 기본 _id
  • query(4편) + agg(5편) + cluster — Kibana·용량 설계의 기반

다음에 다룰 것

  • Beats
  • Filebeat·Metricbeat, module, output to ES/Logstash

해당 내용은 Elasticsearch Guide (Aggregations, Size your shards, Cluster APIs) 를 기반으로 합니다.

'ELK & Elastic Cloud' 카테고리의 다른 글

Logstash  (0) 2026.07.14
Beats  (0) 2026.07.11
Query DSL  (0) 2026.07.05
Mapping과 Analyzer  (0) 2026.07.03
Elasticsearch란  (0) 2026.07.02