회사에서 사용 중인 Elastic Search 일정 Template의 데이터 필드 타입이
무언가의 이슈로 인해서 수정해야 할 일이 생겼다.
데이터 필드 타입 바꾸는 걸로 포스팅을 쓸게 있다니?
사실, 결론부터 말하면 한번 지정하여 Template를 등록한 후에는 데이터 필드 타입을 변경할 수 없다!

오마이갓
아니 그러면 어떻게 해야 할까?
기존 Template를 Delete 하고 새로 만들면 된다!
이상.

장난이었다.
(진짜 이 방식으로 했다가 지운 데이터를 필요로 하는 개발자분에게 저 이모티콘 처럼 사과를 해야 하기도 했다.)
개발환경이거나 데이터가 수집되기 전이라면 위의 방식처럼 삭제하고 새로 만들어도 무방하지만,
운영환경이거나 수집되고 있는 데이터를 지워서는 안 되는 경우에는
그저 지우고 새로 만드는 방식으로는 대응할 수가 없다.
그래서 나는 Re-Index 방식을 알아보게 되었다.
Re-Index는 기존 Index에 쌓여있던 데이터를 새로운 Index로 옮기는 작업을 해준다.
즉, Cumtom_Idx 라는 Index에 저장된 데이터를
새로운 Index인 Custom_Idx_2 라는 Index로 옮기는 거다.
하지만 다른 이름으로 한 번의 Re-Index는 제 문제를 해결해주지 못했다.
운영상에서는 아예 새로운 이름의 Index로 옮기게 되면
Index 이름을 사용하는 모든 기능들에 문제가 생길 거다.
그래서 나는 Re-Index 작업을 두 번 해야겠다고 생각하게 되었다.
즉, 임시 백업용 Index를 만들겠다는 의미다.
알아보기 쉽게 정리해 보면
(실제 사용하는 인덱스는 Use_Idx 백업용 인덱스는 Temp_Idx 라고 지칭)
1. Use_Idx Template 에 수정하고자 하는 데이터 타입 수정
새로운 Template Json 을 동일한 Template에 PUT 메소드 API로 요청하면 오버 라이딩된다.
2. Temp_Idx Template 생성
데이터 타입 수정 후의 Use_Idx Template와 동일하게 만든다.
3. Use_Idx 를 Temp_Idx 에 Re-Index
re-index 완료될 때까지 대기해야하고
데이터 타입이 변경되면서 수정이 필요한 부분은 적절한 스크립트로 작성해줘야 한다.
(이 부분은 뒤에서 다시 다루자)
4. 데이터가 쌓여있는 Use_Idx를 제거
5. Temp_Idx 를 Use_Idx 에 Re-Index
마찬가지로 완료될 때까지 대기해야 한다.
6. Temp_Idx 제거
순서로 진행이 된다.
그때그때 명령어로 실행하기가 번거로워서 쉘 스크립트로 구성해보았다.
SOURCE_INDEX='Use_Idx'
DEST_INDEX='Temp_Idx'
# 1. Use_Idx Template 에 수정하고자 하는 데이터 타입 수정하기
curl -X PUT 'http://localhost:9200/_template/'"${SOURCE_INDEX}"'' -H 'Content-Type: application/json' -d '{
"order": 0,
"index_patterns": [
""
],
"settings": {
"index": {
"number_of_shards": "",
"number_of_replicas": "",
"refresh_interval": "",
"lifecycle": {
"name": "'${SOURCE_INDEX}'"
},
"sort.field": "",
"sort.order": ""
}
},
"mappings": {
"properties": {
"checkTime": {
"type": "date",
"format": "epoch_millis" # 이곳이 수정되었다.
},
"checkResult": {
"type": "integer"
}
}
},
"aliases": {
"'${SOURCE_INDEX}'": {}
}
}'
# 2. Temp_Idx Template 생성하기
curl -X PUT 'http://localhost:9200/_ilm/policy/'"${DEST_INDEX}"'' -H 'Content-Type: application/json' -d '{
"policy": {
"phases": {
"delete": {
"min_age": "",
"actions": {
"delete": {}
}
}
}
}
}'
curl -X PUT 'http://localhost:9200/_template/'"${DEST_INDEX}"'' -H 'Content-Type: application/json' -d '{
"order": 0,
"index_patterns": [
""
],
"settings": {
"index": {
"number_of_shards": "",
"number_of_replicas": "",
"refresh_interval": "",
"lifecycle": {
"name": "'${DEST_INDEX}'"
},
"sort.field": "",
"sort.order": ""
}
},
"mappings": {
"properties": {
"checkTime": {
"type": "date",
"format": "epoch_millis"
},
"checkResult": {
"type": "integer"
}
}
},
"aliases": {
"'${DEST_INDEX}'": {}
}
}'
일단 기존 Template 는 데이터 타입을 수정하고, 백업용 Template 를 만든다.
SOURCE_INDEX='Use_Idx'
DEST_INDEX='Temp_Idx'
# 3. Use_Idx 를 Temp_Idx 에 Re-Index 하기
curl -X GET 'http://localhost:9200/_cat/indices' | grep "${SOURCE_INDEX}" | awk '{print $3}' | while read line
do
date=${line: (-11)}
source_index_date=${SOURCE_INDEX}${date}
dest_index_date=${DEST_INDEX}${date}
echo $source_index_date
echo $dest_index_date
curl -X POST 'http://localhost:9200/_reindex?wait_for_completion=false' -H 'Content-Type: application/json' -d '{
"source": {
"index": "'${source_index_date}'"
},
"dest": {
"index": "'${dest_index_date}'"
},
"script": {
"lang": "painless",
"source": "ctx._source.checkTime = Instant.ofEpochSecond(ctx._source.checkTime).toEpochMilli()"
}
}'
done
이 포스팅에 주된 주제인 re-index 를 하는 과정이다.
중요한 부분을 다시 한번 정리해보자면,
1. wait_for_competion=false
Re-Index 작업에도 Timeout 설정이 있기 때문에 데이터 양이 많으면 Timeout이 걸리게 돼서
이 Timeout 설정을 무시하고 계속 Re-Index 작업을 진행하고 싶을 때 설정
2. script
위에서 얘기했듯이 데이터 타입이 변경되면서 필요한 스크립트를 작성하는 거다.
나는 'keywork' 에서 'epoch_millis' 로 변경되었기 때문에 적절한 함수를 사용해서 데이터를 변경해줬다.
(함수의 생김새나 Elastic Search 개발언어를 고려하면 Java 같다.)
SOURCE_INDEX='Use_Idx'
DEST_INDEX='Temp_Idx'
curl -X GET 'http://localhost:9200/_cat/indices' | grep "${DEST_INDEX}" | awk '{print $3}' | while read line
do
date=${line: (-11)}
source_index_date=${SOURCE_INDEX}${date}
dest_index_date=${DEST_INDEX}${date}
echo $source_index_date
echo $dest_index_date
# 4. 데이터가 쌓여있는 use_idx를 제거하기
curl -X DELETE 'http://localhost:9200/'${source_index_date}
# 5. temp_idx 를 use_idx 에 re-index 하기
curl -X POST 'http://localhost:9200/_reindex?wait_for_completion=false' -H 'Content-Type: application/json' -d '{
"source": {
"index": "'${dest_index_date}'"
},
"dest": {
"index": "'${source_index_date}'"
}
}'
done
정상적으로 데이터가 Temp_Idx로 백업이 되었다면 기존 Use_Idx는 지워주고,
데이터 타입이 변경된 Temp_Idx 를 다시 Use_Idx 에 Re-Index 작업한다.
SOURCE_INDEX='Use_Idx'
DEST_INDEX='Temp_Idx'
curl -X GET 'http://localhost:9200/_cat/indices' | grep "${DEST_INDEX}" | awk '{print $3}' | while read line
do
date=${line: (-11)}
source_index_date=${SOURCE_INDEX}${date}
dest_index_date=${DEST_INDEX}${date}
echo $source_index_date
echo $dest_index_date
curl -X DELETE 'http://localhost:9200/'${dest_index_date}
done
마지막으로 원복이 정상적으로 완료되면 Temp_Idx도 제거한다.
업무를 하면서 Elastic Search 데이터베이스를 다루게 되었는데
취준 때나 보통 많이 쓰는 일반 RDBMS랑은 굉장히 다른 사용법에 흥미를 느끼는 중이다.
그리고 요즘엔
'사용방법' 보다는 '효율적인 사용' 이나 '안전한 구축 및 운영' 같은 키워드에 관심이 생기고 있다.
공부할 것이 참 많은 개발의 세계!
'Database > Elastic Search' 카테고리의 다른 글
Elastic Search는 Thread Pool 관리를 어떻게 할까? (0) | 2022.07.14 |
---|