내 클러스터에 문제가 있는건 아닌지 의심된다면?

bulk indexing을 하고 있거나 검색을 heavy 하게 날리고 있을때 클러스터 헬스는 그린으로 멀쩡한거 하지만 뭔가 퍼포먼스가 너무 떨어지는 느낌이 들때가 있습니다.
클러스터 로그를 살펴봐도 별다른점을 못찾겠고 어디서 부터 살펴봐야 할지 난감한데요 이럴 때 참고하면 좋은 몇가지 api들을 소개하겠습니다.

# 1. pending task 확인

1
curl -XGET 'host:port/_cluster/pending_tasks'

공식docs를 보면 일반적인 상황에서는 empty list를 반환 하지만 pending 되어 있는 작업이 있는 경우 그 리스트를 리턴 합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
"tasks": [
{
"insert_order": 101,
"priority": "URGENT",
"source": "create-index [foo_9], cause [api]",
"time_in_queue_millis": 86,
"time_in_queue": "86ms"
},
{
"insert_order": 46,
"priority": "HIGH",
"source": "shard-started ([foo_2][1], node[tMTocMvQQgGCkj7QDHl3OA], [P], s[INITIALIZING]), reason [after recovery from shard_store]",
"time_in_queue_millis": 842,
"time_in_queue": "842ms"
},
{
"insert_order": 45,
"priority": "HIGH",
"source": "shard-started ([foo_2][0], node[tMTocMvQQgGCkj7QDHl3OA], [P], s[INITIALIZING]), reason [after recovery from shard_store]",
"time_in_queue_millis": 858,
"time_in_queue": "858ms"
}
]
}

** pending tasks 가 있는 경우 단순히 작업량이 많아서 밀리고 있는 것 인지 비정상 적인 상황인지 판단해야 합니다 **

# 2. hot threads 확인

hot threads 를 확인하는 일은 elasticsearch cluster 를 운영하다 보면 종종 있는 일 입니다.
특히 GC가 비정상 적이거나, CPU가 높거나, 검색이 밀리거나 하는등 거의 대부분의 문제의 원인을 유추해 볼 수 있는 단서가 될 수 있습니다.

1
curl -XGET 'host:port/_nodes/{nodesIds}/hot_threads?pretty'

공식docs 에 따르면 아래와 같은 파라미터를 같이 던질 수 있습니다. type이 기본적으로 cpu로 되어 있고 threads가 3으로 설정 되어 있기 때문에 CPU 사용률이 높은 세개의 쓰레드가 표시됩니다.

param description
threads number of hot threads to provide, defaults to 3.
interval the interval to do the second sampling of threads. Defaults to 500ms.
type The type to sample, defaults to cpu, but supports wait and block to see hot threads that are in wait or block state.
ignore_idle_threads If true, known idle threads (e.g. waiting in a socket select, or to get a task from an empty queue) are filtered out. Defaults to true.
1
2
3
4
5
6
7
8
9
10
11
12
24.6% (122.8ms out of 500ms) cpu usage by thread 'elasticsearch[cluster][search][T#13]'
10/10 snapshots sharing following 10 elements
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
org.elasticsearch.common.util.concurrent.jsr166y.LinkedTransferQueue.awaitMatch(LinkedTransferQueue.java:706)
org.elasticsearch.common.util.concurrent.jsr166y.LinkedTransferQueue.xfer(LinkedTransferQueue.java:615)
org.elasticsearch.common.util.concurrent.jsr166y.LinkedTransferQueue.take(LinkedTransferQueue.java:1109)
org.elasticsearch.common.util.concurrent.SizeBlockingQueue.take(SizeBlockingQueue.java:162)
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
java.lang.Thread.run(Thread.java:724)

위 output에서는 서치쓰레드의 T#13이 24.6%의 cpu를 사용하는것을 알 수 있습니다.
해당 쓰레드의 스택 트레이스도 같이 나오므로 써드파티 라이브러리나 플러그인을 사용한 경우 해당 쓰레드가 자주 등장한다면 버그가 있는것은 아닌지 찾아봐야 하고, java core 쪽. 특히 cache나 concurrent쪽 쓰레드가 자주 나타난다면 메모리 관련 OS설정들은 잘 적용 되었는지 (Post not found: ElasticSearch_Heap 참조) 등등 문제가 될 만한 부분들을 찾아내는 좋은 단서가 됩니다.

Share