Elasticsearch의 성능을 위해 데이터를 한 건 한 건 처리하는 것이 아닌 bulk를 이용하여 한 번에 처리하는 경우가 많습니다.
bulk를 사용하여 많은 양의 데이터를 Elasticsearch에 저장할 경우 분명 HTTP 요청은 정상적으로 끝이 났는데 데이터가 저장이 안 되는 경우가 발생할 수 있습니다. 여기서 중요한 것은 Elasticsearch로 보낸 HTTP의 Response는 200이라는 정상적인 값을 리턴을 하기 때문에 문제를 찾기가 어려운데요. 이럴 때는 Response의 state code를 보는 것이 아라 Response의 body의 내용을 볼 필요가 있습니다.

문제 해결방법

해당 문제를 해결하는 방법은 2가지 방법이 있습니다.

  1. 한번에 요청하는 bulk의 사이즈를 줄인다 : 만약 자원의 부족으로 thread 설정이 불가능한 경우 한번에 처리하는 bulk의 개수를 줄여서 해당 문제를 해결할 수 있습니다.
  2. thread_pool의 wrtie queue size를 늘린다 : http request connect를 통한 부하를 줄이는 것이 더 중요한 경우 1번 방법을 사용할 수 없습니다. 그런 경우 thread가 처리할 수 있는 자원이 있을 때 2번 방법을 통하여 한번에 처리할 수 있는 bulk의 양을 늘려서 문제를 해결할 수 있습니다.

모든 상황에 만족하는 문제 해결은 없습니다. 본인의 환경에 맞는 문제 해결 방법을 찾고 해당 방법을 적용하는 것을 추천드립니다.

아래는 2번 방법을 통해 한번에 처리할 수 있는 bulk의 양을 늘리는 방법에 대해 정리하였습니다.

설정 변경하기

Elasticsearch 디렉토리 위치에 config/elasticsearch.yml파일에 다음과 같은 설정 값을 추가하고 Elasticsearch를 재시작합니다.

thread_pool.write.queue_size: 2000
thread_pool.write.size: 16

설정을 진행하자가 문제가 발생한 경우

만약 다음과 같은 메시지가 발생한 다면 thread_pool.write.size의 값을 13보다 작은 값으로 설정하세요.

java.lang.IllegalArgumentException: Failed to parse value [16] for setting [thread_pool.write.size] must be <= 13

설정값의 의미

  • thread_pool.write.size : write를 수행하는 스레드 풀의 스레드 수
  • thread_pool.write.queue_size : write를 할 때 사용되는 스레드 풀의 큐 크기
  • thread_pool.search.size : search를 수행하는 스레드 풀의 스레드 수
  • thread_pool.search.queue_size : earch를 할 때 사용되는 스레드 풀의 큐 크기

마지막으로

thread에 대한 설정은 노드의 리소스 스펙에 한계가 있기 때문에 어느 정도 설정 값 튜닝을 했음에도 불구하고 더 이상의 성능 향상이 없을 경우 노드의 Scale up을 고려하는 것을 추천드립니다.

 

 

bulk란

Elasticsearch를 사용하면서 여러개의 데이터를 넣을때 매번 하나씩 데이터를 넣는 일은 네트워크의 잦은 IO의 발생으로 성능을 저하 시킬 수 있는 요인입니다. 이러한 문제를 해결하는 것이 bulk입니다. bulk는 여러개의 처리를 모아 두었다가 한번에 처리하는 batch 처리 기능입니다.

 

bulk를 통해 데이터 넣기

bulk를 사용하여 여러개의 데이터를 한번의 요청으로 넣을 수 있습니다.

api POST http://localhost:9200/my-log-index-2021-08-25/_bulk
header Content-type: Application/json
body {"index": {"_index": "my-log-index-2021-08-25", "_id": 1}}
{"user_id":1, "level":"info", "timestamp": 1629893888, "action": "open_file", "message": "user1 file open"}
{"index": {"_index": "my-log-index-2021-08-25", "_id": 2}}
{"user_id":2, "level":"info", "timestamp": 1629893890, "action": "open_file", "message": "user2 file open"}
{"index": {"_index": "my-log-index-2021-08-25", "_id": 3}}
{"user_id":3, "level":"info", "timestamp": 1629893891, "action": "open_socket", "message": "user3 socket open"}
{"index": {"_index": "my-log-index-2021-08-25", "_id": 4}}
{"user_id":4, "level":"info", "timestamp": 1629893892, "action": "open_socket", "message": "user4 socket open"}
{"index": {"_index": "my-log-index-2021-08-25", "_id": 5}}
{"user_id":5, "level":"info", "timestamp": 1629893893, "action": "open_file", "message": "user5 file open"}
{"index": {"_index": "my-log-index-2021-08-25", "_id": 6}}
{"user_id":6, "level":"info", "timestamp": 1629893893, "action": "close_file", "message": "user6 close open"}
{"index": {"_index": "my-log-index-2021-08-25", "_id": 7}}
{"user_id":7, "level":"info", "timestamp": 1629893895, "action": "close_socket", "message": "user7 close socket"}

중요 ) 여기서 만약에 Postman, 크롬에 ARS와 같이 http요청을 보내는 RestClient 프로그램을 사용하신다면 body 마지막에 개행(\n) 즉 enter키를 한번 더 입력해야 됩니다.

 

데이터가 잘 들어갔는지 확인하기

api GET http://localhost:9200/my-log-index-2021-08-25/_search

 

bulk를 이용하여 데이터 입력, 수정, 삭제 한번에 하기

데이터 입력 뿐만 아니라 데이터 수정, 삭제를 한번의 bulk를 통하여 수행할 수 있습니다.

 

bulk로 입력, 수정, 삭제

api POST http://localhost:9200/my-log-index-2021-08-25/_bulk
header Content-type: Application/json
body {"index": {"_index": "my-log-index-2021-08-25", "_id": 8}}
{"user_id":8, "level":"debuf", "timestamp": 1629893993, "action": "close_file", "message": "user8 close open"}
{"index": {"_index": "my-log-index-2021-08-25", "_id": 9}}
{"user_id":9, "level":"warn", "timestamp": 1629893995, "action": "error", "message": "failed user9 connection"}
{"update": {"_index": "my-log-index-2021-08-25", "_id": 1}}
{"doc": {"level": "debug"}}
{"update": {"_index": "my-log-index-2021-08-25", "_id": 2}}
{"doc": {"level": "debug"}}
{"delete": {"_index": "my-log-index-2021-08-25", "_id": 6}}

중요 ) 여기서 만약에 Postman, 크롬에 ARS와 같이 http요청을 보내는 RestClient 프로그램을 사용하신다면 body 마지막에 개행(\n) 즉 enter키를 한번 더 입력해야 됩니다.

벌크의 내용

8번, 9번 유저의 데이터를 추가하고

1번, 2번 유저의 level필드의 값을 debug로 수정하고

6번 유저의 데이터를 삭제합니다.

 

결과 확인

크롬의 "Elasticsearch Head"라는 확장 프로그램을 사용하여 결과를 확인하겠습니다.

"Elasticsearch Head"의 설치 방법은 링크과 같습니다.

https://stdhsw.tistory.com/entry/Elasticsearch-%EC%9C%88%EB%8F%84%EC%9A%B010-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0

 

Elasticsearch 윈도우10에 설치하기

Elasticsearch 다운로드 https://www.elastic.co/kr/downloads/elasticsearch 해당 주소에서 elasticsearch를 다운로드합니다. Elasticsearch 실행하기 압축을 푼 폴더 위치에서 bin/elasticsearch.bat파일을 실..

stdhsw.tistory.com

 

+ Recent posts