Developer's_til/그외 개발 공부

[ELK] 클러스터 성능, 모니터링과 최적화

Heon_9u 2025. 12. 30. 17:22
728x90
반응형

클러스터의 자원 상황, 요청 빈도, 처리 상태 등의 지표를 수집하고 모니터링하는 것은 ElasticSearch를 운영하는데 필수 업무 중 하나이다. 이번 포스팅에서는 지표를 수집하고 해석하는 방법을 다룰 것이다.

 

 

 📗 ElasticSearch 상태 확인하기

cat API를 통한 클러스터, 노드, 샤드의 상태 등 다양한 정보를 확인할 수 있다.

 

[ 클러스터의 상태와 정보 ]

_cat/health API

[
  {
    "epoch": "1735564800",
    "timestamp": "12:00:00",
    "cluster": "es-prod-cluster",
    "status": "green",
    "node.total": "3",
    "node.data": "3",
    "shards": "12",
    "pri": "6",
    "relo": "0",
    "init": "0",
    "unassign": "0",
    "pending_tasks": "0",
    "max_task_wait_time": "-",
    "active_shards_percent": "100.0%"
  }
]

 

필드명 설명
status* 클러스터 상태
- green: 모든 샤드가 정상 동작
- yellow: 일부 혹은 모든 레플리캬 샤드가 정상적으로 동작하지 않음
- red: 일부 혹은 모든 프라이머리/레플리카 샤드가 정상적으로 동작하지 않음
node.total 전체 노드 수
node.data 전체 데이터 노드 수
shards* 전체 샤드 수 (primary + replica)
너무 많은 샤드가 있다면 성능 저하를 초래
pri* primary 샤드 수
relo* 재배치 중인 샤드
(이 값이 0이 아니라면 샤드들이 재배치되고 있다는 의미)
재배치가 지나치게 많을 경우, 인덱싱 성능이나 검색 성능이 떨어질 수 있으니 반드시 원인을 파악해야 한다.
init* 초기화 중인 샤드
(이 값이 0이 아니라면 샤드들이 초기화되고 있다는 의미)
unassign 할당되지 않은 샤드
샤드가 어느 노드에도 배치되지 않은 상태로 안정성에 문제가 발생할 수 있다.
pending_tasks 대기 중인 클러스터 작업
클러스터가 부하 상황이거나 특정 노드가 서비스 불능 상태일 가능성이 있다.
active_shards_percent 활성 샤드 비율

 

 

[ 노드의 상태와 정보 ]

_cat/nodes API

ip            heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
192.168.1.10           42          78   15    0.32    0.40     0.45 dim       *      es-node-1
192.168.1.11           35          74   10    0.28    0.35     0.38 dim       -      es-node-2
192.168.1.12           30          70    8    0.20    0.25     0.30 dim       -      es-node-3
필드명 설명
ip 노드 IP
heap.percent JVM 힙 사용률 (%)
- 만약 이 값이 낮아지지 않고 85% 이상을 계속 유지한다면 OOM이 발생할 가능성이 크기 때문에 원인을 파악해야 한다.
ram.percent 시스템 메모리 사용률 (%)
- 노드가 사용할 수 있는 전체 메모리에서 사용 중인 메모리의 사용률이다. OS에서 I/O 부하를 줄이기 위한 페이지 캐시로 사용하기 때문에 수치가 높다.
cpu CPU 사용률
load_1m 최근 1분 load average
node.role 노드 역할
- d: 데이터 노드
- m: 마스터 노드
- i: 인제스트 노드
ex) mi: 마스터 + 인제스트 노드
master * = 현재 master
name 노드 이름

 

 

[ 인덱스의 상태와 정보 ]

_cat/indices API

health status index              uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   logs-2025.01.01    X1a2B3cD4E5F6G7H8I9    3   1    1254300      1200         8.5gb      4.2gb
green  open   logs-2025.01.02    J9I8H7G6F5E4D3C2B1A    3   1    1432200      980          9.7gb      4.8gb
yellow open   metrics-2025.01    M1N2B3V4C5X6Z7A8S9    1   1     230450      0            1.2gb      1.2gb
red    open   orders             Q9W8E7R6T5Y4U3I2O1    5   1          -      -            -          -
필드명 설명
health 인덱스 상태 (green / yellow / red)
- 여기서 하나라도 yellow 또는 red면 클러스터의 상태도 동일한 상태가 된다.
status 인덱스 열림 여부 (open / close)
- close 상태라면 읽기/쓰기가 불가능하지만, 데이터 노드에서 용량은 차지한다.
index 인덱스 이름
pri primary 샤드 수
rep replica 샤드 수
docs.count 문서 수
docs.deleted 삭제된 문서 수
store.size 전체 인덱스 크기
pri.store.size primary 샤드만의 크기

 

 

[ 샤드의 상태 확인하기 ]

index              shard prirep state      docs   store  ip            node
logs-2025.01.01    0     p      STARTED    420000  1.4gb  192.168.1.10  es-node-1
logs-2025.01.01    0     r      STARTED    420000  1.4gb  192.168.1.11  es-node-2
logs-2025.01.01    1     p      STARTED    415000  1.3gb  192.168.1.11  es-node-2
logs-2025.01.01    1     r      STARTED    415000  1.3gb  192.168.1.12  es-node-3
logs-2025.01.01    2     p      STARTED    419300  1.4gb  192.168.1.12  es-node-3
logs-2025.01.01    2     r      STARTED    419300  1.4gb  192.168.1.10  es-node-1
metrics-2025.01    0     p      STARTED    230450  1.2gb  192.168.1.10  es-node-1
metrics-2025.01    0     r      UNASSIGNED
필드명 설명
index 인덱스 이름
shard 샤드 번호 (0번부터 시작)
prirep p = primary / r = replica
state 샤드 상태
- STARTED: 정상
- INITIALIZING: 초기화하는 상태 혹은 샤드에 문제가 발생하여 새롭게 배치할 때의 상태
- RELOCATING: 샤드가 현재의 노드에서 다른 노드로 이동하고 있는 상태
- UNASSIGNED: 샤드가 배치되지 않은 상태
docs 문서 수
store 샤드 크기
ip 샤드가 올라간 데이터 노드의 ip
node 노드 이름

 

💡 샤드가 배치되지 않은 대표적인 원인

INDEX_CREATED:
인덱스가 생성된 후, 샤드가 배치되지 않았음을 의미하는데, 샤드를 특정 노드에만 배치되도록 강제하거나 특정 노드에 배치되지 않도록 강제했을 때 발생.

NODE_LEFT:
샤드가 배치된 데이터 노드에 문제가 생겨서 클러스터에서 제외될 경우 발생하며 가장 흔한 코드.

 

📌 클러스터의 상태가 red일 때 _cat/shards API는 매우 중요한 지표

클러스터가 red 상태라면 가장 먼저 _cat/indices를 통해서 어떤 인덱스가 red 상태인지 확인.
이를 통해 문서의 유실이 발생했는지 여부를 확인할 수 있다.
만약, red상태의 인덱스가 현재 색인이 일어나고 있다면 _cat/shards를 통해 어느 정도의 비율로 문서 유실이 발생하는지 알 수 있다.

 

📘 status API로 성능 지표 확인

지표 의미
색인 성능 초당 몇 개의 문서를 색인할 수 있는지
검색 성능 초당 몇 개의 쿼리를 처리할 수 있는지
GC 성능 Stop-The_World가 얼마나 자주, 오래 발생하는지
rejected 클러스터가 요청을 거절한 횟수

 

 

[ 색인 성능 ]

_status/indexing API의 색인 성능만 수집

{
  "_all": {
    "indexing": {
      "index_total": 152340,
      "index_time_in_millis": 9876,
      "index_current": 12,
      ....
    }
  }
}
필드명 설명
index_total 전체 인덱스된 문서 수 (누적)
index_time_in_millis 색인에 소요된 총 시간
index_current 현재 진행 중인 색인 작업 수

 

 index_total은 누적값이기 때문에 특정 시간을 기준으로 조회한 결과와 비교해서 색인 성능을 확인할 수 있다.

 

📃 예시1) 초당 색인한 문서 수

10초 전 index_total = 150,000
현재 index_total   = 152,340

2,340 docs / 10s
= 234 docs/sec

 

📃 예시2) 문서 하나당 색인하는데 걸리는 시간

10초 전 index_time_in_millis = 3,500
현재 index_time_in_millis = 9,876

10초동안 색인하는 데에 6376ms 소요
2,340docs / 6,376ms
= 0.36ms

 

즉, 이 클러스터의 프라이머리 샤드는 초당 234개의 문서를 색인할 수 있고, 문서 하나당 색인 성능은 0.36ms가 된다.

 

검색 성능도 이와 유사하게 확인할 수 있다. 다만, 검색은 query + fetch 과정이 일어나기 때문에 두 과정에 대한 지표를 토대로 성능을 계산해야 한다.

 

 

[ rejected 살펴보기 ]

rejected는 ElasticSearch 클러스터 레벨에서 현재 처리량이 부족하다는 것을 알 수 있는 지표 중 하나이다. 현재 처리할 수 있는 양보다 많은 요청이 들어오면 큐에 쌓아 놓는다. 하지만, 큐도 가득찬 경우, rejected 에러를 발생시키며 요청을 처리하지 못한다.

 

 nodes/status API를 통해 확인할 수 있고 스레드별로 rejected 지표를 확인할 수 있다.

{
  "nodes": {
    "node-1": {
      "thread_pool": {
        "search": {
          "threads": 13,
          "queue": 1000,
          "active": 13,
          "rejected": 245
        },
        "write": {
          "threads": 8,
          "queue": 200,
          "active": 8,
          "rejected": 1021
        },
        "bulk": {
          "threads": 4,
          "queue": 200,
          "active": 4,
          "rejected": 356
        }
      }
    }
  }
}

 

 

스레드명 설명
search 동시 검색 과다, slow query
write refresh 과다, 디스크 병목
bulk bulk 사이즈 과대, ingest 병목

 

❓ rejected가 발생하는 원인

초기에 구성한 클러스터의 처리량이 부족한 경우
> 데이터 노드를 증설하는 것 외에는 특별한 방법이 없다.

요청이 순간적으로 늘어나서 순간 요청을 처리하지 못하는 경우:
> 큐를 늘리는게 도움이 될 수 있다.

 

📚 정리

 클러스터/노드 등의 상태를 확인하면서 ElasticSearch 운영 업무에 필요한 API들을 알 수 있었다.

각 지표들을 통해 문제의 원인을 파악해나가는 것이 해당 챕터의 핵심으로 보였고 본문에는 작성하지 않았지만, 힙 메모리와 관련된 GC 성능에서도 Stop-The-World 혹은 OOM이 발생하지 않도록 모니터링하는 것이 중요하다는 것을 알았다.

728x90
반응형