뒤로가기

Elastic

reindex 성능 및 속도 최적화 방법

반윤성 2022.07.22.

Elasticsearch Reindex ?

엘라스틱서치에서 안정적으로 인덱스를 운영하는 도중에 사전이나, 샤드 및 매핑 변경과 같은 작업이 필요할 땐 어떻게 해야할까요?

다시 문서를 읽어 들여 새로 색인을 하는 방법이 있긴 하지만 상품 데이터처럼 문서 크기가 매우 크고, 수정이 빈번한 대상엔 적용이 어려울 것입니다.

엘라스틱서치에서는 이러한 문제를 해결하기 위한 방법으로 reindex(재색인) 기능을 제공하고 있습니다.

엘라스틱서치 Reindex의 성능 및 속도 최적화 방법

1. 샤드 수가 많아질수록 속도와 부하가 증가한다.

주로 reindex를 하기 위해 다음과 같이 API를 호출합니다.

POST _reindex?wait_for_completion=false&slices=auto
{
  "source": {
    "index": "old-index",
    "size": 10000
  },
  "dest": {
    "index": "new-index"
  }
}

wait_for_completion은 작업 완료까지 기다리지 않고, 비동기로 작업하겠다는 의미입니다.

source는 대상이 되는 소스 인덱스를 의미합니다.

dest는 대상이 되는 타겟 인덱스를 의미합니다. 작업이 시작할 때 이 이름으로 인덱스를 만들어 색인을 진행합니다.

slices는 병렬로 작업할 수를 결정합니다. 샤드 갯수와 같을 때 성능이 가장 높으며, 이는 auto로 설정하는 것과 같습니다.

이를 바탕으로 성능 테스트를 진행합니다.

테스트 케이스 노드 수 인덱스 용량 처리 속도 실 소요시간
shard 15 8 1.1T 35,164/s 10시간 1분
shard 20 8 1.1T 41,572/s 7시간 36분
- 서버 스펙 : Intel(R) Xeon(R) Gold 6244 CPU @ 3.60GHz , 32 코어, 메모리 약 263GB

샤드 수가 reindex의 속도에 미치는 영향이 생각보다 강했습니다. 진행 상황을 다시 kibana stack mornitoring을 통해 확인해보면 I/O Operation Rates, CPU나 LOAD등 속도와 부하가 증가한 것을 알 수 있었습니다. 정리해보면 샤드 수가 늘어날수록 속도가 증가하다고 볼 수 있습니다.

/images/2022-07-22-Reindex-Elasticsearch/image1.png

2. reindex 시 레플리카는 제외하는 것이 좋다

replica는 엘라스틱서치에서 샤드의 고가용성 및 장애 시 복원을 위해 활용하는 수단이지만 reindex시에는 속도 지연과 추가적인 시스템 부하를 야기할 수 있습니다.

레플리카 테스트 케이스 노드 수 인덱스 용량 처리 속도 실 소요시간
X shard 20 8 1.1T + 레플리카 생성 시 2.1T 41,572/s 7시간 51분 (작업시간 7시간 36분 + 레플리카 생성 15분)
O shard 20 8 2.1T 23,329/s 12시간 30분

해당 내용으로 테스트를 진행해보면 다음과 같이 레플리카를 포함해서 reindex한 것만으로도 시간이 크게(약 5시간) 증가했다는 것을 알 수 있습니다.

만약 레플리카를 reindex후에 생성했다면 5시간을 절약할 수 있는 효과가 생기는 셈입니다.

아무래도 reindex 시 replica를 포함하여 진행하기 때문에 2.1T 크기의 인덱스를 색인하는 만큼의 시간이 소요됩니다.

따라서 replica를 포함하여 색인하는 것은 권장되지 않습니다.

3. 최적의 속도는 어떻게 정할까?

앞서 진행했던 내용으로 reindex 정책을 규정해본다면, 다음과 같습니다.

  • 1) 샤드 수는 많을수록 빠르다. 하지만 그만큼 부하가 커진다.
  • 2) 시작 레플리카는 0으로 셋팅한다.

속도를 빠르게 올리는 방법은 알았는데, 얼만큼의 속도가 적정할까요? 여기에선 azure에서 다음과 같이 테스트한 내용을 참고했습니다. (Tuning data ingestion performance for Elasticsearch on Azure)

  • 테스트 기준은 bulk_insert의 처리량
  • 요청 처리량은 4n+1/-1(n은 노드 수)에서 성능이 좋음
  • 짝수보단 홀수개의 샤드에서 더 좋음

/images/2022-07-22-Reindex-Elasticsearch/image2.png

이를 바탕으로 적합한 샤드 수를 산정해봅니다. 현재 운영 서비스에서 사용하고 있는 노드 갯수는 10개 입니다. 결과표를 바탕으로 하면 39, 41이 좋겠지만 현재 다른 시스템에서 들어오는 부하도 존재했기에 주기적으로 reindex를 발생시키기엔 적합하지 않았습니다.

따라서 기존 10개에서 15개로 샤드를 추가해서 reindex를 진행합니다.

레플리카 테스트 케이스 노드 수 인덱스 용량 처리 속도 실 소요시간
X shard 10 10 1.1T 23,329/s 12시간 30분
X shard 15 10 1.1T 41,572/s 7시간 36분

원하는 시간이 12시간 정도 였기때문에 15개의 샤드로 진행했고 적절한 속도를 얻을 수 있었습니다.

4. 부하를 낮추는 방법

reindex 시, 속도와 부하에 영향을 주는 방법으로 샤드 외에 다른 방법을 생각해볼 수 있습니다. 바로 slices 수를 조절하는 방법이 있는데 만약 slice와 샤드 수와 비대칭적으로 부하를 경감시킬 수 있을까요?

이번엔 다음과 같이 케이스를 상정해서 테스트를 진행해봤습니다.

슬라이스 수가 40%로 낮아지면 속도와 부하도 40% 감소할까?

슬라이스 수 테스트 케이스 노드 수 인덱스 용량 처리 속도 실 소요시간
15 shard 15 10 1.1T 33,447/s 10시간 48분
6 (-60%) shard 15 10 1.1T 25,014/s 11시간 54분

결과를 확인해보니 속도가 감소하긴 했지만 60%가 감소한 것이 아닌, 약 25% 감소한 것으로 확인됩니다.

부하를 감소시키기 위해 슬라이스 수를 낮추는 것이 유효하지만 정확한 비율만큼 감소하는 것이 아님을 확인했습니다. 오히려 샤드 수를 낮추는 것이 더욱 효율적인 방법으로 생각되기도 합니다.

정리

엘라스틱서치의 reindex 기능에 대해 알아보았습니다. 서비스에 따라 다르겠지만 인덱스의 재색인은 주요한 기능이며 운영시에도 편리하게 사용할 수 있는 기능으로 보입니다. 공식 문서에 성능이나 최적화 방법이 상세하게 기술되어 있지 않아서 테스트의 결과를 통해 유추하는 방식으로 서비스 운영에 적합한 설정을 파악하게 되었습니다. reindex 도입 시 참고할만한 내용으로 상세하게 소개드립니다.

참고 자료

  • https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-reindex.html
  • https://github.com/uglide/azure-content/blob/master/articles/guidance/guidance-elasticsearch-tuning-data-ingestion-performance.md