본문 바로가기

Elasticsearch

운영중인 Elasticsearch reindex alias 무중단 예제 코드 및 사용 방법 / Zero downtime reindex alias

반응형

 

 

Reindex란 ? 

데이터를 입력하는 것 

 

 

Reindex를 하는 이유는 ? 

1) index의 mapping을 수정해야 할 때 

- analyzer, analyzer's definition 등을 수정 시 

2) Cluster upgrade or migration

- Elasticsearch version 5.x 이하일 경우 ES가 index를 읽을 수가 없어서 이런 경우에도 Reindex 진행

3) 새로운 index에 기존의 데이터를 재입력하고 싶을 때 

- 하지만 Reindex라는 말 그대로 mapping 정보 등은 제외하고 only 데이터만 가져옴 

 

Reindex 실행 전 반드시 알아야할 점은?

1) _source 가 enabled 상태인 Index만 reindex가 가능

2) mapping정보까지 카피하는 것이 아니기 때문에 reindex할 새로운 Index에 Mapping작업도 원본과 동일하게 해주어야 한다. 

 

 

 

 

 

Alias란 ?

존재하는 Index에 alias기능으로 특정 index를 바라보도록 설정하는 것 (특정 index를 바라보는 index 역할을 하는 것 - 하지만 data를 가지고 있지는 않음) 

 

ex) address 라는 Index에 "alias_address"라는 명으로 alIas를 설정 -> application query를 "address"라는 Index로 직접적으로 하지 않고 "alias_address"로 query를 날린다. alias_address 는 결국 address를 바라보기 때문에 같은 데이터를 반환한다. 

 

alias를 처음 접했을 때 아주 생소했는데 생각보다 설정하는 것이 매우 간단했다! 자세한 자세한 Alias 개념 설명 및 사용 방법 (alias 생성, 추가, 동시 추가, 삭제 방법)  👇👇

https://blckchainetc.tistory.com/418

 

[Elasticsearch] What is Alias? and How to use it? / alias란 ? alias 세팅하기, 사용법

Alias란 ? What is Alias in Elasticsearch ? Alias란 data stream 또는 indices에 대한 두번째 이름(별칭)이다. 대부분의 ES APIs는 data stream 또는 index 이름 대신에 alias를 받는다. Alias를 사용하는 주된..

blckchainetc.tistory.com

 

 

 

 

 

 

Alias 가 어떻게 무중단 reindex를 가능하게 할까? 

 

Alias 이용한 no downtime reindex process

1. Application은 "index_alias" 라는 alias명(이 alias가 바라보고 있는 Index가 아닌)으로 query를 날린다. 

 

2. "index_alias"는 현재 인덱스 current_index를 바라본다. 

 

3. Mapping설정이 되어 있는 새로운 new_index를 만든다.

 

4. new_index로 reindex (from current_index)를 한다. (데이터 이동)  or 동시에 current_index와 new_index에 write 입력한다. ====> 데이터가 모두 인덱싱이 완료되면 ==> 5번

 

5. alias가 current_index 대신 new_index를 바라보도록 수정한다. alias명을 동일하게 해 놓아야 기존의 alias이름으로 query를 보내던 코드들을 수정할 필요가 없다. 기존의 current_index를 바라보던 alias를 remove 하고 새로 new_index를 바라보는 동일한 이름의 alias를 설정한다. 

 

6. 불필요해진 기존의 current_index를 삭제한다. 

 

7. 무언가 잘못되면 final alias change 를 revert해야 한다. 

 

 

 

 

처음에는 잘 이해하기 어려웠다. 많은 블로그 글을 읽고 직접 해보면서 이해한 바는 

 

A 라는 기존에 존재하는 index가 있다. A index의 mapping을 변경하고 싶어서 mapping을 변경하려고 하지만 ES db는 이렇게 변경하기보다 아예 새로운 mapping을 가진 새로운 index를 만들어 data indexing해야 한다. 

새로운 B 임시 인덱스를 생성한다. (새로운 Mapping을 가진) 

 

여기서 alias없이 reindex를 하게 된다면 

 A ---> B로 인덱싱을 하고 A를 삭제, 다시 수정된 mapping을 가진 A 생성 B ---> A 로 인덱싱. ("A"라는 인덱스 이름을 유지하고 싶은 경우)   그리고 불필요해진 임시 인덱스 B 삭제 

위의 경우 A가 사라지고 인덱싱 되는 동안은 운영환경에서 돌고 있는 수많은 쿼리들 (index A를 향하는) 이 갈 곳이 없어진다. 

 

alias가 있는 경우 

A 인덱스에 alias를 "data"라는 이름으로 설정해 놓는다. 새로운 인덱스 B를 생성한다. 

A ---> B로 인덱싱(reindex)을 한다. "data" alias가 가리키고 있는 index "A"에서 ---> "B"로 변경한다. (_alias remove, add) 불필요한 A를 삭제한다. 

그럼 끝 ! downtime없이 reindex가 된다. 

이 경우, index의 이름이 크게 중요하지 않은 것 같다. 왜냐하면 어차피 alias 가 가리키고 있는 특정 인덱스 이름만 간단히 바꾸면 되고, 어차피 query날리는 곳에서 쓰는 Index명은 alias 이름일 것이다. 그래서 굳이 인덱스 이름을 바꾸기 위해 다시 B->A로 reindex를 안해도 된다.

 

모든 index에 alias를 생성해서 사용하는 것을 권장한다. 만드는데 비용도 안들고 위험도 없기 때문! 오히려 없으면 리스크 발생 확율이 높다.

 

 

 

 

직접 해보기 

elasticsearch dev tool version

PUT index_a                        // index_a 생성 
{
  "mappings": {
    "properties": {
      "subject": {
        "type": "text"
      },
      "content": {
        "type": "text"
      }
    }
  }
}

POST index_a/_doc                        // 내용 insert 여러번 반복함
{
  "subject": "주제.,",
  "content": "내용.,"
}
GET index_a/_search                       // 검색해보기 

PUT index_a/_alias                      // alias 설정
{
  "alias": "my_alias"
}

GET index_a/_alias                       // index_a에 설정된 alias 확인

GET my_alias/_search                      // alias로 search query 날려서 잘 나오는지 확인

PUT index_b                      // 새로운 index 생성 (mapping 필수)
{
  "mappings": {
    "properties": {
      "subject": {
        "type": "text"
      },
      "content": {
        "type": "text"
      }
    }
  }
}

POST _reindex                       // index_a ---> index_b    data 인덱싱 (넣기)
{
  "source": {
    "index": "index_a"
  },
  "dest": {
    "index": "index_b"
  }
}

GET index_b/_search                      // Index_b에 데이터 잘 들어갔는지 확인

GET index_a/_alias                      // alias 잘 있는지 첵
GET index_b/_alias                      // 아직 alias 없음 

POST _aliases                      // index_a의 alias 삭제 index_b에 alias 설정
{
  "actions": [
    {
      "remove": {
        "index": "index_a",
        "alias": "my_alias"
      }
    },
    {
      "add": {
        "index": "index_b",
        "alias": "my_alias"
      }
    }
    ]
}

GET index_a/_alias                      // alias 없어짐
GET index_b/_alias                      // alias 생김 

DELETE index_a 	                     // 필요없는 Index 삭제

 

 

 

curl version

1. new_index 생성 
curl -XPUT http://localhost:9200/new_index -H'Content-Type:application/json' -d '{"mappings":{"properties":{"weight":{"type":"long"}}}}'

2. new_index에 데이터 입력
curl -X POST http://localhost:9200/new_index/_doc -H'Content-Type:application/json' -d'{"weight":1}'
x 여러번 반복

3. new_index에 alias 설정
curl -X PUT http://localhost:9200/_alias -H'Content-Type:application/json' -d'{"actions":[{"add":{"index":"new_index","alias":"my_alias"}}]}'

4. 새로운 인덱스 brand_new_index 생성
curl -XPUT http://localhost:9200/brand_new_index -H'Content-Type:application/json' -d '{"mappings":{"properties":{"weight":{"type":"long"}}}}'

5. new_index ----> brand_new_index로 reindex 
curl -XPOST http://localhost:9200/_reindex -H'Content-Type:application/json' -d'{"source":{"index":"new_index"},"dest":{"index":"brand_new_index"}} '

6. brand_new_index에 데이터 잘 들어갔는지 확인
curl -XGET http://localhost:9200/brand_new_index/_search

7. new_index 에 설정된 my_alias 를 brand_new_index로 설정 
curl -XPOSThttp://localhost:9200/_aliases -d'{"actions":[{"remove":{"index":"new_index", "alias": "my_alias"}},{"add":{"index":"brand_new_index","alias":"my_alias"}}]} ' -H'Content-Type:application/json'

8. alias 확인 
curl -XGET http://localhost:9200/brand_new_index/_alias  // my_alias 가 나와야함
curl -XGET http://localhost:9200/new_index/_alias // alias 존재하지 않음

9. my_alias로 query 잘 나오는지 확인 
curl -XGET http://localhost:9200/my_alias/_search 

10. new_index 삭제 
curl -XDELETE http://localhost:9200/new_index


 

 

 

 


 

 

 

Alias를 사용한 Reindex 장점

1. 직관적이다. 

2. Revertible 되돌릴 수 있다. 

3. ES 밖 소스로부터 새로운 field를 포함할 수 있다. 

 

 

 

Alias를 사용한 Reindex 단점 

1. 오직 하나의 ES cluster 안에서 작동한다. 

2. 꽤 할일이 있지만 딱 하나의 케이스만을 핸들한다. (Requires quite some work, but handles only one use case)

3. 기존 인덱스와 새로운 인덱스 간의 데이터 일관성을 어떻게 유지하는지 아무도 모른다. 

 

 

 

 

 

Reference : https://tuleism.github.io/blog/2021/elasticsearch-zero-downtime-reindex/

https://wedul.site/618

반응형