기록하는 습관

Elasticsearch (3) - reindex 본문

개발/Elasticsearch

Elasticsearch (3) - reindex

로그뉴 2022. 3. 12. 17:03

** Elasticsearch를 공부하며 정리한 글입니다.

 

 

Elasticsearch에서는 인덱스 매핑 정보가 바뀌면 업데이트 하는 과정이 어렵다.

reindex를 통해 다시 인덱스 생성을 한 후 reindex api 호출을 통해 기존 인덱스를 지우고 다시 만들었다.

하지만 이 과정은 document 수가 10만가지만 넘어가도 서비스 흐름이 끊어지게 된다. 따라서 alias를 이용해reindex를 무중단하게 진행해보려고 한다. 

# reindex 시 알고 있어야 하는 사항

1. _source  enabled 상태인 index reindex가 가능하다.

2. reindex는 복사가 아니다.

 reindex를 하려는 index mapping정보도 똑같이 카피되는 것이 아니라. 데이터만 넣기 때문에 이때 디폴트 매핑으로 인덱스가 생성되기 때문에 반드시 reindex 할 곳에 mapping작업도 원본과 동일하게 해주어야 한다.이를 해결하기 위해 index_template을 사용해 자동으로 설정해둔 settings/mappings 정보를 활용해 인덱스를 생성하도록 하자.

 

# 기본적인 reindex 실행하기

old 인덱스가 있다고 가정하고, reindex를 위해 새로운 인덱스 new를 만들어보자.

그러고 new reindex를 실행해준다. 이 때, 주의할 점은 ,document 10만 이상 넘어가면 오래 걸려서 timeout이 발생할 수 있다.

따라서 작업을 비동기로 실행하는 옵션인 wait_for_completion=false를 설정해주고 진행한다.

 

POST _reindex?wait_for_completion=false
{
  "source": {
    "index": "old"
  },
  "dest": {
    "index": "new"
  }
}

 

프로세스가 종료되면 reindex가 다 된 것이다.

이후, new에 old라는 alias를 지정해줘야 한다.

POST _alias
{
  "actions": [
     {
       “add”: {
         "index": "old"
         "alias": "new"
       }
    }
  ]
}

 

alias를 지정하기 전에 기존 인덱스를 delete 명령을 통해 지운다.

이후 alias 명령을 진행한다.

 

# 다른 ES 클러스터의 데이터를 reindex 하기

 

경우에 따라서는 신규 클러스터를 운영해야 해서, 클러스터 내부에서 새롭게 reindex 하는게 아니라 remote 의 ES 클러스터의 데이터를 reindex 해야 될 수도 있다. 이럴 때에는 “source” 에 “remote” 를 지정하면 된다.

“remote” 의 index 를 reindex 하고자 한다면, 기존 클러스터의 host 가 whitelist 에 추가되어 있어야 한다. (elasticsearch.yml)

# 기존 index의 일부 필드만 reindex 하기

일부 필드만 reindex 하거나(includes), 불필요한 필드는 제외시킬 수도 있다. (excludes)

# 전체 데이터가 아닌, 일부 데이터만 reindex 하기

쿼리를 질의해서 기존 index 에서 일부 데이터만을 reindex 할 수도 있다. 일반적인 쿼리와 마찬가지로 size 를 지정할 수도 있다.

reindex 를 실행하면 한꺼번에 많은 데이터를 새로 인덱싱 해야 하기 때문에 ES 클러스터의 부하가 높아진다.

이미 부하가 높은 클러스터라면, 성능에 여유가 있는지 잘 살펴서 실행하도록 하기. 또한, reindex 의 부담을 최소화  reindex 의 부담을 최소화 하기 위해서라도 index 는 잘 쪼개서 alias 로 관리하는 습관을 들이도록 하기.

# reindex scroll batch로 진행된다.

사이즈를 조정하고 싶다면 아래와 같이 조절하면 된다.

 

# Reindex 옵션 정리

  1. version_type
    1. version_type = internal 인 경우, reindex를 여러 번 할 때마다 document version 필드가 업데이트 된다. 즉, 기존 index를 delete하고 다시 insert 된다는 의미.
    2. version_type = external 인 경우, 버전 충돌 메시지가 발생한다. old_index에 document가 추가/수정되면 이미 등록된 id는 버전 충돌이 되면서 업데이트 되지 않는다. 새로 추가/수정된 document만 입력된다. 에러를 무시하고 새로 추가/수정된 document만 제대로 반영되는 것을 원한다면 “conflicts” : “proceed” 옵션을 추가하면 된다.
  2. op_type
    1. op_type : create 옵션 밖에 없다. 만약 reindex를 한 후에 다시 reindex를 할 경우, 이미 reindex된 document가 수정되어도 reindex에 생성된 index에서는 반영되지 않고 오직 새로 생성된(create) document 만 적용된다는 것이다. 이 옵션도 같은 document가 있다면version conflict 에러가 나고 그 메시지를 피하기 위해서 conflicts: proceed 를 사용하면 된다.
  3. wait_for_completion
    1. wait_for_completion=false 옵션을 넣어주면, 재색인을 비동기로 진행할 수 있다. ES document양이 10만이 넘어가게 되면 timeout이 발생하며 작업이 중단되기 때문이다.
    2. 해당 옵션을 적용해 request를 날리면 task를 return 한다. 또한, ES는 _tasks/<task_id> 로 저장을 하게 된다. task가 끝나면 반드시task document를 지워야 한다. 그래야 ES가 공간을 회수할 수 있다.
  4. 결론
  • version_type = internal.
    • 아예 모든 데이터를 재색인 하고 싶을 때 사용.
    • 적용) 주기적으로 전체 재색인 진행 시 사용.
  • version_type = external, conflicts:proceed
    • 기존 index와 비교하여 update/create 된 document만 재색인.
    • 적용) 재색인 일부만 성공하고 일부는 실패했을 때 사용.
  • wait_for_completion
    • 비동기로 재색인 할 때 사용.
    • 적용) 전체, 일부 재색인 모두 사용.

 

 

참고 블로그

  1. Elasticsearch에서 Reindex 살펴보기

 

Comments