Thread pool (tuning point!)

threadpool1

** 이 포스트에서 수정하는 설정값 들은 elastic에서는 공식적으로 수정하지 말도록 권장하고 있습니다. 꼭 필요한 경우에만 충분한 테스트를 거쳐서 적용하시기 바랍니다. **

ElasticSearch 에 대량의 데이터를 bulk insert 하는 과정에서

  1. 예상했던 값보다 indexing rate가 낮은 경우
  2. 데이터를 밀어넣는 클라이언트에 EsRejectedExecutionException 이 발생 하는 경우

여러가지 튜닝 포인트가 있겠지만 그중에서도 Thread pool 은 매우 중요한 값인것 같습니다.
공식 홈페이지의 문서를 살펴보면

Thread Pool

노드 안에서 효과적으로 쓰레드 메모리를 소비하기 위해서 노드는 여러개의 쓰레드풀을 가지고 있다. 많은 쓰레드 풀들은 큐들을 가지고 있고 그 큐들로 인해 넘치는 요청들이 버려지는 대신 큐에 담겨질 수 있다.

라고 소개되고 있습니다.
여러가지 중요한 Thread pool 들이 소개되어 있지만 개인적으로 특히 더 중요하다고 생각되는 Thread는 아래 세개 입니다.

** index ** : index/delete 연산 용. type은 fixed이고 size는 가용한 프로세서갯수와 동일 합니다. queue_size는 default 200
** search ** : count/search/suggest 연산 용. type은 fixed 이고 size는 ((가용한 프로세서갯수 * 3) / 2) + 1 입니다. queue_size는 default 1000
** bulk ** : bulk 연산 용. size는 가용한 프로세서갯수와 동일 합니다. queue_size는 default 50
여기서 주의 깊게 봐야 할 설정이 바로 queue_size 입니다.

쓰레드풀 자체의 사이즈는 위에서 설명 한것과 같이 가용한 프로세서의 갯수에 의존성이 있기 때문에 튜닝하기 쉽지 않고, queue_size를 늘려줌으로써 EsRejectedExcutionException 이 나는것을 방지 할 수 있습니다.

elasticsearch.yml에 다음과같이 설정해 놓고 사용할 수 있습니다만

1
2
3
threadpool.index.type: fixed
threadpool.index.size: 20
threadpool.index.queue_size: 1000

운영중인 클러스터에 elasticsearch.yml을 변경하고 순차적으로 재시작 하는 작업은 부담이 가는것은 사실 입니다.
** 좋은소식은 ThreadPool 설정은 dynamic setting 이므로 운영중인 클러스터를 재시작 할 필요 없이 api를 날려서 적용 시킬수 있습니다 **

먼저 내 클러스터의 쓰레드풀 설정을 살펴봅시다.

1
2
3
4
5
#내 쓰레드풀에 대한 개요
GET _nodes/thread_pool

#현재 각 쓰레드풀의 상태
GET _nodes/stats/thread_pool

위 명령어는 sense 기준이고 curl로 확인하는 경우 아래와 같이 날려보면 됩니다.

1
curl -XGET 'http://myclusterip:port/_nodes/thread_pool'

이제 다시 맨 처음의 주제로 돌아와서 내 생각보다 bulk insert 되는 속도가 느린것 같거나 자꾸 익셉션이 발생하는 경우
bulk queue가 너무 적은것은 아닌가 의심해 볼 수 있습니다.
쓰레드풀의 상태를 봤을 때 rejected된 건수가 많이 보이면 bulk queue를 늘려보는게 좋습니다.
벌크 인서트할때도 그렇고, 검색할때도 자꾸 밀리는것 같은 느낌이 들어서 다음과 같이 설정을 변경해 봤습니다.
(기존 설정은 default값인 bulk.queue_size는 50, search.queue_size는 1000 이었습니다.)

1
2
3
4
5
6
7
PUT _cluster/settings
{
"transient" : {
"threadpool.bulk.queue_size" : 500,
"threadpool.search.queue_size" : 4000
}
}

좀 더 지켜봐야겠지만 위와 같이 변경 하고 나서 클라이언트에서 EsRejectedExecutionException 도 더이상 보이지 않고 클러스터가 훨씬 안정적이게 됐습니다.

Share