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
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/
'Elasticsearch' 카테고리의 다른 글
[elasticsearch] dis_max란 무엇인지 알아보기, 실습하기 (bool, must와 함께 쓰기) (0) | 2022.08.19 |
---|---|
Elasticsearch geographic location query distance 거리로 가까운 곳 검색하기 (0) | 2022.08.16 |
[Elasticsearch] curl create index, delete index 인덱스 생성 삭제 (0) | 2022.06.21 |
[Elasticsearch] bulk insert (index, create), update, delete with node.js (0) | 2022.06.14 |
[Elasticsearch] index alias란? alias 설정, 추가, 수정, 삭제하기 (0) | 2022.06.13 |