데이터베이스/Elasticsearch

Bulk Index 진행 시 search api 느려지는 현상 해결 방법 리서치

반응형

현재 회사에서 하고있는 프로젝트에 경우 Elasticsearch를 사용해서 데이터를 제공하고 있다.

 

서비스 특성상 초당 받는 데이터 업데이트 요청이 많고 real time engine이 아닌 elasticsearch에 거의 리얼타임 수준의 데이터 변경을 보여줘야한다.

그러다보니 들어오는 요청을 별도의 buffer를 많이 주어 업데이트 할 수 없기 때문에 들어오는 요청을 document id 기준으로 묶어서 bulk 업데이트 될 수있도록 기능을 개발했었다. 

 

회사 블로그에 관련된 내용을 썼었는데 참고

https://techblog.woowahan.com/2718/

 

검색을 위한 데이터 다루기 | 우아한형제들 기술블로그

{{item.name}} 안녕하세요. 우아한형제들 검색개발팀 정철입니다. 배달의민족 검색시스템에서 검색에 사용되는 데이터를 적재하면서 경험했던 어려움과 해결했던 방법을 공유하고자 합니다. 검색

techblog.woowahan.com

 

1차적으로 그렇게 해결이 되었고 현재도 서비스에 이상이 있지는 않지만 가끔 변경 요청이 많이오는 가게 오픈, 종료시간에 search latency가 튀어 client에 499에러를 뱉어내는 경우가 몇건씩 발견되고 있다. 

 

문제를 파악하는 과정에서 여러가지 경우의 수를 생각했었다.

- client node가 용도에 따라 indexer, searcher로 구분하지않아서 요청이 밀려서 thread 할당을 늦게 받아서 늦어지나라고 생각했다. 하지만 client node를 증설해도 큰 지표상 변화를 보지 못했다.

 

그럼 client node에서는 병목이 없는데 api에서 받지를 못하나 생각해서 api도 증설을 해봤지만 동일했다.

 

그러던 중 499에러가 발생하는 지표와 이벤트가 들어오는 지표가 거의 동일시하게 보였다. 현재는 lucene기반에 elasticsearch에 segment가 immutable한 속성 때문에 업데이트 후 기존 segment가 지워지고 새로운 segment가 merge되는 현상을 하는 과정에서 지연이 발생할 가능성이 있고 데이터를 읽어서 보여줘야하는 search api에서 값에 대한 접근이 늦어져서 발생되는게 아닐까 하고 의심하고 있다.

 

내가 생각하고 있는 내용과 비슷한 답변을 하는 elasticsearch discuss를 봤다. 하지만 뾰족한 해결법은 index를 분리하라는건데 현재 우리는 인덱스 분리를 하고 있지 않기 때문에 그부분은 조금더 고려를 해봐야겠다.

- https://discuss.elastic.co/t/huge-performance-degradation-during-bulk-indexing/175924/3

 

Huge performance degradation during bulk indexing

Thanks for the reply! I have a couple follow up questions if you don't mind: What sort of things affect the disk I/O usage? Number of shards you're indexing on, total size of those shards, number of documents being indexed? Intuitively I would guess that e

discuss.elastic.co

 

그리고 또다른 해결법으로 Aws managed Elasticsearch 사용 시 성능을 높일 수 있는 방법에 대한 글을 보았는데 replica를 0으로 두거나  ebs 대신 ssd 사용하라고 하는 것은 이미 하고있고 큰 의미가 없을 것 같고 translog의 flush interval을 늘리라고 하는데 이건 위에 언급했듯이 실시간성이 거의 보장이 되어야하는 서비스상 어려울 것 같다.

 

마지막으로 희망은 bulk api에 response를 filter_path 파라미터를 통해 줄여보라고하는데 현재 사용하고 있는 Java High Level REST Client의 경우 transport layer를 사용하기 때문에 rest layer에서 사용하려면 low level client를 사용해야한다. 

 

조금 커스텀을 해줘야 하지만 그래도 도전해볼만 할 것 같다.

 

뾰족한 수가 당장 보이지는 않는데 여러가지 경우의 수를 보고 더 고민해봐야겠다.

 


[참고]
https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-indexing.html#es-indexing-size

https://aws.amazon.com/ko/premiumsupport/knowledge-center/elasticsearch-indexing-performance/

https://discuss.elastic.co/t/use-filter-path-in-high-level-rest-api/102657/3

https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#common-options-response-filtering

반응형