[Elasticsearch] 효과적인 ES대량 색인: 성능 향상을 위한 테크닉

2023. 12. 10. 17:16· Elasticsearch
목차
  1. 머리말
  2. bulk Request 사용하기
  3. replica 0개로 줄이기 
  4. refresh_interval 비활성화
  5. reindex 슬라이싱
  6. indices_breaker.request.limit 수정
  7. task API 이용해 보기

 

머리말

 

검색 서비스를 운영하다 보면 대량 데이터를 색인해야 할 일이 잦습니다. 저희 팀에서도 대량의 데이터를 매일 새벽에 인덱싱을 하는 작업(팀 내에서는 풀인덱싱이라고 함)을 진행하며, 가끔 데이터를 옮기기 위해서 리인덱싱 작업도 진행하죠.

대량의 데이터를 색인하는 일은 매우 무겁고, 오래 걸리는 작업입니다. 그렇기에 작업을 하다 보면 성능, 효율성 등에 대한 고민들이 생기는데요. 오늘은 대량 데이터를 색인할 때 사용할 수 있는 몇 가지 테크닉들을 소개해보려고 합니다.

 


bulk Request 사용하기

성능을 위해 작은 여러 연산을 처리하기 보다 하나의 큰 연산으로 만들어 처리하는 테크닉은 서버 개발 여러 곳에서 자주 활용되는 테크닉이죠. ES에서도 이런 기능을 제공하는데요, 바로 Bulk API 입니다.

Bulk API는 여러 개의 단건 문서 API 요청을 하나의 요청으로 묶어서 날리는 API입니다. ES에서도 해당 API를 활용해서 대량 데이터를 색인한다면 성능에 향상을 볼 수 있습니다.

 

bulk API를 사용할 때 고려할 점은 적절한 벌크 사이즈를 설정해야 한다는 것입니다. 벌크 사이즈가 크면 클수록 처리량을 향상될 수 있지만 더 많은 메모리를 소비하고 오히려 요청 시간이 초과가 돼버리는 상황도 올 수 있습니다. 그렇기에 적절한 벌크 사이즈를 찾기 위해서는 테스트를 해보는 것이 적절합니다.

 

벌크 리퀘스트 관련해서는 해당 글을 참고해도 좋을 것 같네요 :) 
https://techblog.woowahan.com/2718/

replica 0개로 줄이기 

보통 ES를 관리할 때 데이터를 안정적으로 관리하기 위해 또 검색 성능을 위해서 레플리카 샤드를 설정합니다. 몇 개의 노드가 내려가더라도 원본의 데이터를 복제해 놓은 녀석이 있다면 데이터의 손실을 최소화할 수 있죠. 하지만 참 좋아 보이는 요 녀석도 대용량 데이터를 색인할 때는 성능을 떨어뜨리는 녀석이기도 합니다. 원본 데이터를 색인할 뿐만 아니라 레플리카 샤드 수만큼 복제 작업도 해야 되기 때문이죠.

만일, 색인 성능을 높이는 것이 목적이라면 레플리카 샤드 수를 줄이는 것도 효과적입니다.

PUT /my-index-000001/_settings
{
  "index" : {
    "number_of_replicas" : 0
  }
}

 

가용성이 중요한 인덱스라면 인덱스 생성 이후에도 레플리카 샤드는 동적으로 변경 가능하기 때문에 대용량 색인을 해야 하는 0으로 바꿔서 색인한 뒤에 색인을 마치고 다시 원상 복구하여 가용성을 다시 확보하는 것이 좋습니다.

주로 새로운 인덱스를 세팅하고 원천 데이터를 마이그레이션 할 때 유용하게 사용될 수 있는 테크닉입니다.

refresh_interval 비활성화

ES에서 검색 코어로 사용하는 루씬에서는 파일로 색인한 정보를 관리합니다. 그렇기에 색인한 정보를 검색 가능한 상태로 만들기 위해서는 색인된 파일을 매번 새로 열어주어야 하는데 이런 작업을 refresh라고 합니다.

 

refresh_interval 은 refresh 작업의 간격을 설정합니다. 명시적으로 설정하지 않으면 1초로 설정되는데요, 이는 ES가 1초마다 refresh 작업을 주기적으로 실시한다는 뜻입니다.

대용량 데이터를 색인하는 인덱스는 보통 검색이 실시간으로 진행되어야 하는 인덱스에 바로 실시하지는 않습니다. 그렇기에 이런 인덱스에서는 매 초마다 일어나는 refresh 작업은 불필요한 작업이 됩니다.

 

따라서 대용량 색인 시에는 refresh_interval을 비활성화해 주는 것이 효과적인데요, 설정하기 위해서는 아래와 같은 요청을 ES 클러스터에 보내면 됩니다.

PUT my_index/_settings
{
  "index.refresh_interval": -1
}

( null로 지정하는 것이 아닙니다! null로 하면 설정값을 기본값으로 되돌린답니다 😋 )

 

위와 마찬가지로, refresh_interval을 비활성화한 채로 유지한다면 데이터가 색인되더라도 검색이 불가능하기 때문에 색인 작업이 끝난다면 다시 refresh_interval을 설정해 주는 것이 좋습니다.

reindex 슬라이싱

이번에는 리인덱스 작업에 좀 더 특화된 테크닉인데요. 리인덱싱 할 때는 슬라이싱을 이용해 업데이트 성능을 최대로 끌어내 빠른 시간 안에 끝낼 수도 있습니다. 요청을 보낼 때 파라미터로 slices를 지정하면 작업을 병렬로 쪼개서 진행하게 됩니다. 따로 지정하지 않고 요청할 경우에는 기본값은 1로 설정되고요. 기본값인 1로 설정을 한 경우에는 작업을 병렬로 쪼개지 않습니다.

POST _reindex?slices=auto
{
  "source": {
    "index": "my-index-000001"
  },
  "dest": {
    "index": "my-new-index-000001"
  }
}

 

slices를 auto로 지정한 경우에는 엘라스틱서치 내부에서 적절한 개수를 지정하여 작업을 병렬로 수행하게 됩니다. (보통 프라이머리 샤드 수가 슬라이스 수로 설정됨) 체감이 될 만큼의 성능 향상이 있기 때문에 리소스가 여유 있고, 리인덱싱 속도가 너무 느리다면 사용해 볼 수 있습니다.

indices_breaker.request.limit 수정

너무 많은 데이터에 대한 리인덱싱을 하다 보면 많은 인덱싱 요청에 의해 설정한 메모리 점유율을 넘겼을 경우 서킷이 열리는 경우가 생기는 일도 있는데요, 이럴 때는 리인덱싱이 끊기기 때문에 다시 해야 하는 아주 골치 아프죠. 이럴 때는 값을 적절하게 조절하여 대용량 데이터 색인 중간에 서킷이 열려 요청을 막아버리지 않도록 설정하는 것이 필요합니다.

이 작업 또한 서킷 브레이커의 임계치를 건드는 일이기 때문에 만일 다른 작업과 병행하고 있다면 클러스터의 리소스를 잘 살펴야 합니다.

task API 이용해 보기

너무 많은 데이터를 reindex, 혹은 update by query 작업을 실시할 때면 HTTP 단에서 타임아웃이 나서 미리 종료가 되는 경우가 있습니다. ES의 대부분의 요청은 작업을 종료해서 결과를 받을 때까지 대기하기 때문에 대용량 데이터를 다뤄야 할 때면 타임아웃이 나는 경우가 잦죠. 그럴 때는 wait_for_completion 파라미터를 지정하여 요청을 보내 task라는 작업 단위로 보내면 됩니다.

POST _reindex?wait_for_completion=false
{
  "source": {
    "index": "my-index-000001"
  },
  "dest": {
    "index": "my-new-index-000001"
  }
}

 

위와 같이 요청을 보내면 응답으로 task id를 바로 받는데요, 마치 백그라운드로 실행하는 것과 같이 진행되고 있는 것이라고 보면 됩니다. 해당 응답에 포함된 task id를 조회해서 리인덱스 작업이 어떻게 진행되는지 확인할 수 있게 됩니다.

 

GET _tasks/[task id]

 

만일, 문제가 발생해 task 작업을 취소하고 싶다면 어떻게 해야 할까요?? 그렇다면 아래와 같이 명령을 보내면 됩니다.

POST _tasks/[task id]/_cancel

 


 

 

오늘은 대용량 색인 시 성능 향상을 위해 해볼 수 있는 여러 테크닉에 대해서 알아보았습니다.

대부분 검색쟁이라면 알고 계실 것 같은 내용들이네요. 혹시 이외에도 여러 가지 팁이 있다면 공유해 주시면 감사하겠습니다 :) 

혹시 더 많은 정보를 아시고 싶으시다면 엘라스틱서치 공식 문서에서 제공하는 글을 참고해 보시면 아주 좋습니다.

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

 

다음 글로 찾아뵙겠습니다. 감사합니다. 😊


참조

- 엘라스틱서치 바이블

- 엘라스틱서치 실무 가이드

- ES 공식문서 다수

- 우아한형제들 기술블로그

- 다나와 기술블로그

  1. 머리말
  2. bulk Request 사용하기
  3. replica 0개로 줄이기 
  4. refresh_interval 비활성화
  5. reindex 슬라이싱
  6. indices_breaker.request.limit 수정
  7. task API 이용해 보기
DEV로마
DEV로마
DEV로마
검색쟁이 개발로마
DEV로마
  • 분류 전체보기 (10)
    • Elasticsearch (1)
    • Life (3)
    • Book (2)
    • Web (0)
    • Java (4)
    • CS (0)

태그

  • elasticsearch
  • 자료구조
  • enummap
  • Java
  • 엘라스틱서치
전체
오늘
어제
hELLO · Designed By 정상우.v4.2.1
DEV로마
[Elasticsearch] 효과적인 ES대량 색인: 성능 향상을 위한 테크닉
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.