[Kibana] kibana 를 이용한 모니터링 대쉬보드 사용시 주의 할 점 - Search Thread.
Elastic/Kibana 2015. 10. 1. 13:56ELK를 이용해서 매트릭 수집이나 시스템 모니터링 등을 하고 계신 분들이 많은 걸로 압니다.
이미 경험해 보신 분들이 많을 것 같기는 하지만 그래도 공유 차원에서 글 작성해 보겠습니다.
보통 ELK 를 이용해서 데이터를 수집 후 kibana 로 dashboard 구성을 해서 지표를 보게 됩니다.
잘 아시겠지만 kibana의 기본 설정은 logstash-* 로 모든 index를 대상으로 질의를 하게 됩니다.
이와 같은 이유로 시간이 지날 수록 성능이 떨어지고 에러가 발생하게 되는데요.
잘 아시겠지만 elasticsearch 에서의 모든 action 은 thread 단위로 동작 하게 됩니다.
그렇기 때문에 kibana를 이용한 dashboard 를 계속 띄워 놓고 auto refresh 를 사용하게 되면 해당 주기 동안 계속 search request 가 실행 됩니다.
하나의 예를 들어 보면 index 당 shard 크기를 5개로 했다고 가정 하겠습니다. (replica 0)
현재까지 생성된 index 는 30일치 30개 입니다.
그렇다면 총 shard 수는 5 x 30 = 150개가 됩니다.
kibana 를 이용해서 한 화면에 8개의 지표를 볼 수 있는 dashboard를 구성했다고 가정 하겠습니다.
이와 같이 했을 경우 dashboard 에서 실행 되는 질의는 총 8개 입니다.
이 8개의 질의에 대한 elasticsearch에서의 실행 되는 search thread 수는 얼마나 될까요?
8 x 5 x 30 = 1200 개의 search thread 가 실행 되게 됩니다.
이게 무슨 문제를 일으킬 수 있을까요?
elasticsearch에서는 threadpool 설정을 통해서 search thread 크기를 조정 할 수 있습니다.
아래는 ThreadPool.java 의 code snippet 입니다.
defaultExecutorTypeSettings = ImmutableMap.<String, Settings>builder()
....
.put(Names.SEARCH, settingsBuilder().put("type", "fixed").put("size", ((availableProcessors * 3) / 2) + 1).put("queue_size", 1000).build())
....
위에서 보시는 것 처럼 기본 runnable size 는 (availableProcessors * 3) / 2) + 1 입니다.
그리고 queue_size 는 1000 개로 정해져 있습니다.
CPU가 4 core 라고 가정하면,
runnable thread size = ( ( 4 x 3 ) / 2 ) + 1 = 7
queue thread size = 1000
이와 같습니다.
8개의 지표로 구성된 dashboard를 한번 호출 할 때마다 1200 개의 search request 가 발생을 하게 되고 이 시점에 일부 시스템 리소스가 부족하게 된다면 해당 elasticsearch 로 다른 applicaiton 에서 aggregation과 같은 질의를 실행 했을 때 잘 못된 정보가 return 될 수도 있습니다.
실제 이런 경우 elasticsearch의 error log 를 보면 아래와 같은 메시지를 보실 수 있습니다.
[2015-09-29 00:08:40,896][DEBUG][action.search.type ] [Madame Masque] [....][7], node[zXJSZ4IYS2KwPhj190hhEQ], [P], s[STARTED]: Failed
to execute [org.elasticsearch.action.search.SearchRequest@542e2e00] lastShard [true]
org.elasticsearch.common.util.concurrent.EsRejectedExecutionException: rejected execution (queue capacity 1000) on org.elasticsearch.search.action.SearchServiceTransp
ortAction$23@76a71853
at org.elasticsearch.common.util.concurrent.EsAbortPolicy.rejectedExecution(EsAbortPolicy.java:62)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:821)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1372)
at org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor.execute(EsThreadPoolExecutor.java:79)
......중략.....
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
에러 메시지는 queue capacity 1000 을 넘었기 때문에 reject 했다는 내용입니다.
해결 방법은 간단 합니다.
- kibana의 dashboard 화면을 단순화 하고 필요한 시점에만 띄워 놓고 봅니다.
- kibana의 auto-refresh 를 off 하거나 주기를 길게 줍니다.
- threadpool.search.queue_size 를 늘려 줍니다.
경험 할 수도 있고 안할 수도 있지만 운영하면서 알고 있으면 그래도 도움은 되지 않을까 싶어서 공유 합니다.