elasticsearch / / 2022. 12. 22. 20:35

[번역] 엘라스틱 서치 인덱싱 속도 향상을 위한 튜닝

이 글은 아래 원문을 번역한 자료입니다. 번역 내용이 좀 부족할 수 있지만 이해해 주세요~

원문: https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-indexing-speed.html

bulk requests를 사용해라

Bulk requests는 단일 문서 인덱싱 요청보다 훨씬 더 좋은 성능을 보인다. bulk request의 최적의 크기를 알기 위해서는 단일 샤드를 가진 단일 노드로 벤치마킹을 해봐야 한다. 우선 한번에 100개의 문서, 그리고 나서 200개, 400개 순으로 인덱싱해봐야 한다. 매번 벤치마킹을 실행할 때 bulk request 문서를 배수로 늘려가면서 해본다. 인덱싱 속도가 안정적으로 유지될 때 bulk request를 하기에 최적의 크기가 되었음을 알 수 있다. 비슷한 경우에는 너무 많은 양의 문서보다는 적은 양의 문서가 에러에 대처하기가 더 좋다. 너무 많은 양의 bulk request는 동시에 전송되었을 때 클러스터의 메모리 부족현상을 유발할 수 있어서 성능상 이점이 있더라도 한번의 요청에 수십메가 이상은 피하는 것을 권장한다.

엘라스틱서치에 데이타 전송 시 다중 worker와 thread를 사용해라.

bulk request를 단일 thread로 사용하면 Elasticsearch 클리스터의 인덱싱 효과를 극대화할 수 없다. 클러스터의 모든 리소스를 사용하기 위해서는, 다중 thread 혹은 프로세스로 데이터를 전송해야 한다. 클러스터의 자원을 보다 잘 사용하기 위해서, 각각의fsync 비용을 줄이는 것이 도움이 될 것이다.

TOO_MANY_REQUESTS(429) 응답코드를 잘 확인해라(Java client에서는 EsRejectedExecutionException). 이것은 Elasticsearch가 현재 인덱싱 속도를 맞출 수 없다는 뜻이다. 이런 일이 발생한다면 재요청하기 전에 잠시 인덱싱을 중지해야 한다. 이상적으로 지수 백오프로 실행하는 것이다.

bulk request의 크기와 관련해서, 오직 테스트를 통해서만 최적의 worker개수가 몇개인지 알 수 있다. I/O 혹은 CPU가 클러스터 임계치에 도달할 때까지 worker의 수를 증가하면서 테스트할 수 있다.

refresh 간격을 설정하지 않거나 증가시켜라

refresh라고 불리는 검색 가능한 상태로 만드는 이 오퍼레이션은 비용이 비싼 작업이며, 빈번한 호출이 인덱스 속도에 영향을 줄 수 있다.

기본값으로, 엘라스틱서치는 매초마다 주기적으로 인덱스를 refresh한다. 하지만 검색 요청을 받았거나 30초 이내에 요청을 받은 인덱스에 대해서만 한다.

만일 검색부하가 거의 없거나(예: 5분 동안 1회 이하의 검색) 인덱싱 속도를 최적화하고 싶다면 최적의 설정이다. 이런 동작은 검색되지 않는 경우 기본 동작으로 bulk 인덱싱을 자동으로 최적화하는데 목적이 있다. 이런 방식을 사용하지 않으려면 명시적으로 refresh를 설정해라.

반면에, 인덱스에 기본적인 검색 요청이 있다면, 기본 동작은 Elasticsearch가 1초마다 인덱스를 refresh할 것이다. 문서가 인덱스되고 검색이 가능하게 될 때까지의 시간을 증가해도 된다면 좀 더 큰 값으로 증가하면 인덱싱 속도에 도움이 될 것이다. (index.refresh_interval)

초기 부하를 위해 replica를 비활성화해라

Elasticsearch에 한번에 로드할 많은 양의 문서가 있다면 index.number_of_replicas를 0으로 설정하는게 도움이 될 수 있다. 복제본이 없다는 것은 단일 노드가 실패하는 경우 데이터 유실이 발생할 수 있으므로 초기 데이터에 문제가 발생하는 경우에는 재요청될 수 있도록 하는 것은 중요하다. 초기 데이터가 완료된 이후 index.number_of_replicas를 원래값으로 되돌릴수 있다.

인덱스 index.refresh_interval이 설정되어 있다면, 초기 로딩동안 해제하고 완료된 이후 원래 값으로 되돌리는 것이 도움이 될것이다.

swapping을 비활성화해라

swapping을 비활성화함으로써 운영체제가 java 프로세스를 swapping되지 않는지 확인해야 한다.

파일 시스템 캐쉬에 메모리를 할당해라

파일시스템 캐시가 I/O 오퍼레이션를 버퍼링하기 위해 사용될 수 있다. 적어도 시스템 메모리의 절반 정도를 파일시스템 캐쉬에 할당하도록 해야 한다.

자동 생성 id를 사용해라

특정 ID를 가진 문서를 인덱싱할 때, Elasticsearch는 동일 ID가 동일 샤드에 존재하는지 체크하기 때문에 인덱스 크기가 커짐에 따라 비용이 비싸진다. 자동생성 ID를 사용함으로써 엘라스틱서치가 이런 확인단계를 건너뛸수 있고 더 빠르게 인덱싱을 할 수 있다.

더 빠른 하드웨어를 사용해라

인덱싱이 I/O가 많은 작업이라면, 파일시스템 캐시 크기를 늘리거나 보다 빠른 스토리지 사용을 고려하라. Elasticsearch는 개발 파일을 순차적으로 쓰기를 한다. 하지만 인덱싱은 다중파일을 동시에 쓰기를 하고, 또한 랜덤과 순차적인 읽기를 포함하기 때문에 SSD 드라이브에서 더 나은 성능을 보인다.

RAID0로 구성함으로서 다중 SSD로 인덱스를 스트라이핑을 해라. 하나의 SSD에서 인덱스 작업이 실패하면 오류의 위험이 커진다는 것을 기억하라. 하지만 일반적으로는 트레이드오프가 있다. 최대의 성능을 위해서 단일 샤드로 최적화하고 나서 다은 로드에 복제본을 추가해라. 또한 스냅샷을 사용하고 나중의 복구를 위해 백업본을 복구할 수도 있다.

로컬 스토리지로 직접 연결하는 방식이 구성하기 쉽고 통신 오버헤드가 없기 때문에 원격 스토리지보다 더 나은 성능을 보인다. 더 세심하게 튜닝함으로써 원격 스토리지를 사용하는 방식도 적절한 성능이 나오게 할 수도 있다. 튜닝 파라미터를 정하기 위해 실제 부하로 시스템을 벤치마킹해라. 기대하는 성능이 나오지 않는다면 문제를 확인하기 위해 스토리지 벤더와 협의해보자.

인덱싱 버퍼 사이즈

노드가 무거운 인덱싱 작업을 한다면 인덱싱 하는데 indices.memory.index_buffer_size값이 샤드당 512MB 버퍼를 할당하는게 충분한 크기인지 확인하라. (그 이상은 보통 인덱싱 성능이 좋아지지 않는다). 엘라스틱서치는 그 설정을 가지고 모든 활성 샤드에 공용 버퍼로 사용한다. 매우 활성화된 샤드는 가벼운 인덱싱을 수행하는 샤드보다 이 버퍼를 더 많이 사용한다.

기본값은 10%이다: 예를 들어 JVM에 10GB메모리를 할당한다면 인덱스 버트에 1GB를 할당하게 될 것이고 무거운 인덱싱 작업을 하는 2개의 샤드를 운영하기 충분하다.

리소스 경합을 방지하기 위해 클러스터간 복제를 사용해라

단일 클러스터 내에서, 인덱싱과 검색은 리소스 경합이 발생할 수 있다. 클러스터 간 복제를 구성하고 모든 검색이 클러스터로 라우팅하게 하는 2개의 클러스터를 구성함으로써 검색은 더 이상이 리소스 경합이 발생하지 않는다.

Additional optimizations

디스크 사용량을 튜닝하는 전략도 인덱싱 속도를 향상시킬 수 있다.

반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유