Index Template은 인덱스를 생성할 때 사용되는 설정 템플릿입니다. 새로운 인덱스가 생성될 때 매번 정의하는 번거러움을 인덱스 템플릿 설정을 통하여 해결할 수 있습니다. 인덱스 템플릿을 선언을 통해 자동적으로 새롭게 생성되는 인덱스에 설정을 적용하여 일관된 인덱스 구조와 매핑을 유지하고 반복적인 작업을 줄이는 데 사용됩니다.
Index Template 생성
실습으로 my-log라는 Index Template을 생성하여 데이터 필드가 잘 적용되는지 확인하도록 하겠습니다.
인덱스 생성 시 설정 파라미터에 대한 정보
https://opensearch.org/docs/1.2/opensearch/rest-api/index-apis/create-index/
PUT _index_template/my-log
{
"index_patterns": [
"my-log-*"
],
"template": {
"settings": {
"number_of_shards": 4,
"number_of_replicas": 1,
"refresh_interval": "5s",
"opendistro.index_state_management.policy_id": "my-ism"
},
"mappings": {
"properties": {
"cluster": {
"type": "keyword"
},
"node": {
"type": "keyword"
},
"level": {
"type": "keyword"
},
"message": {
"type": "text"
},
"timestamp": {
"type": "long"
}
},
"dynamic_templates": [
{
"default_string": {
"match": "default*",
"match_mapping_type": "string",
"mapping": {
"type": "keyword"
}
}
},
{
"default_number": {
"match": "default*",
"match_mapping_type": "long",
"mapping": {
"type": "integer"
}
}
}
]
}
}
}
index_patterns을 통해 "my-log-"로 시작하는 새롭게 생성된 인덱스에 해당 Template을 적용하도록 지정합니다.
number_of_shards 해당 인덱스의 샤드 개수를 설정합니다. Opensearch의 경우 Cluster가 여러 Data Node로 구성되는데 하나의 Data Node에 데이터가 집중되지 않도록 number_of_shards를 설정하여 여러 Data Node에 샤드를 골고루 배치할 수 있습니다.
number_of_replicas는 primary shard를 복제한 replica shard의 개수를 설정합니다. 위 설정에서는 1로 설정하여 각각의 primary shard가 복제한 샤드를 한 개씩 구성할 수 있도록 설정하여 HA 구성이 되도록 설정하였습니다.
refresh_interval은 간단하게 설명하면 검색할 수 있는 document를 refresh 하는 것을 의미합니다. Opensearch는 데이터가 들어왔다고 바로 검색이 가능한 것이 아니고 데이터가 들어오고 해당 인덱스가 refresh가 되었을 경우 검색이 가능하게 됩니다. refresh_interval을 1s로 설정하였다면 1초마다 refresh 되어 실시간처럼 검색이 가능하게 되지만 indexing 성능에 영향을 미칠 수 있습니다. 만약 본인의 환경이 실시간을 중요하게 여기지 않고 indexing 성능을 우선으로 한다면 refresh_interval값을 크게 가져가는 것을 추천합니다. 보다 자세한 정보를 원하신다면 "Lucene"에 대해 알아보는 것을 추천합니다.
opendistro.index_state_management.policy_id 설정은 ISM Policy 정책을 지정하는 것입니다. ISM은 Index state Management로 인덱스의 Lifecycle을 관리해 주는 역할을 수행합니다. 아래 링크에 정리해 두었으니 자세한 내용을 링크에서 확인해 주세요
https://stdhsw.tistory.com/entry/Opensearch-ISMIndex-State-Management
mappings.properties 설정은 데이터의 field의 타입을 지정합니다. string 타입에는 대표적으로 keyword, text 타입이 있는데 keyword는 Aggregation과 같이 통계를 내거나 반듯이 같은 값을 검색하는 데 사용되며 text의 경우 Analyzer를 통해 데이터를 분석하는 데 사용됩니다. 그 밖에 많은 field type이 존재하는데 자세한 내용은 Opensearch document를 확인해 주세요
https://opensearch.org/docs/latest/field-types/supported-field-types/index/
mappings.dynamic_templates 설정은 properties로 지정하지 않은 field의 데이터가 들어올 경우 해당 데이터의 필드 타입을 지정합니다. dynamic_templates 은 어떠한 데이터 필드가 들어올지 명확하지 않거나 동일한 이름 형식의 필드가 너무 많을 경우 사용합니다. 위에서 설정된 default_string의 경우 필드의 이름이 default로 시작되며 데이터 형식이 string일 경우 필드의 타입을 keyword로 지정하는 설정이며 default_number의 경우 default로 시작하여 데이터 형식이 number일 경우 필드의 타입을 integer로 설정합니다.
Index Template 확인하기
방금 생성한 my-log Template을 확인합니다.
GET _index_template/my-log
테스트 해보기
지정된 Template이 잘 적용되는지 bulk를 이용하여 실제 데이터를 넣어 확인합니다. (참고로 bulk는 HTTP Body의 가장 마지막 라인에 enter를 한번 더 넣어줘야지 Error가 발생하지 않습니다.)
POST _bulk
{ "index": { "_index": "my-log-2023-07-10"} }
{ "cluster": "my-test-cluster", "node": "worker-1", "level": "debug", "message": "[debug] data send successful", "timestamp": 1688992028}
{ "index": { "_index": "my-log-2023-07-10"} }
{ "cluster": "my-test-cluster", "node": "worker-1", "level": "debug", "message": "[debug] data send successful", "timestamp": 1688992038}
{ "index": { "_index": "my-log-2023-07-10"} }
{ "cluster": "my-test-cluster", "node": "worker-1", "level": "debug", "message": "[debug] data send successful", "timestamp": 1688992048}
{ "index": { "_index": "my-log-2023-07-10"} }
{ "cluster": "my-test-cluster", "node": "worker-2", "level": "debug", "message": "[debug] data send successful", "timestamp": 1688992029}
{ "index": { "_index": "my-log-2023-07-10"} }
{ "cluster": "my-test-cluster", "node": "worker-2", "level": "debug", "message": "[debug] data send successful", "timestamp": 1688992030}
{ "index": { "_index": "my-log-2023-07-10"} }
{ "cluster": "my-test-cluster", "node": "worker-2", "level": "debug", "message": "[debug] data send successful", "timestamp": 1688992031}
{ "index": { "_index": "my-log-2023-07-10"} }
{ "cluster": "my-test-cluster", "node": "worker-2", "level": "debug", "message": "[debug] data send successful", "timestamp": 1688992033}
{ "index": { "_index": "my-log-2023-07-10"} }
{ "cluster": "my-test-cluster", "node": "worker-1", "level": "err", "message": "[err] failed data send", "timestamp": 1688992048}
{ "index": { "_index": "my-log-2023-07-10"} }
{ "cluster": "my-test-cluster", "node": "worker-1", "level": "warn", "message": "[warn] json format is not valid", "timestamp": 1688992041}
{ "index": { "_index": "my-log-2023-07-10"} }
{ "cluster": "my-test-cluster", "node": "worker-1", "level": "err", "message": "[err] failed data send", "timestamp": 1688992042}
{ "index": { "_index": "my-log-2023-07-10"} }
{ "cluster": "my-test-cluster", "node": "worker-2", "level": "debug", "message": "[debug] data send successful", "timestamp": 1688992031, "default-text": "APP Test"}
{ "index": { "_index": "my-log-2023-07-10"} }
{ "cluster": "my-test-cluster", "node": "worker-2", "level": "debug", "message": "[debug] data send successful", "timestamp": 1688992033, "default-text": "APP Test"}
{ "index": { "_index": "my-log-2023-07-10"} }
{ "cluster": "my-test-cluster", "node": "worker-1", "level": "err", "message": "[err] failed data send", "timestamp": 1688992048, "default-text": "APP Test"}
{ "index": { "_index": "my-log-2023-07-10"} }
{ "cluster": "my-test-cluster", "node": "worker-1", "level": "warn", "message": "[warn] json format is not valid", "timestamp": 1688992041, "default-number": 111111}
{ "index": { "_index": "my-log-2023-07-10"} }
{ "cluster": "my-test-cluster", "node": "worker-1", "level": "err", "message": "[err] failed data send", "timestamp": 1688992042, "default-number": 222222}
정상적으로 데이터가 들어갔는지 확인해 봅니다.
POST my-log-2023-07-10/_search
{
"query": {
"bool": {
"must": [
{
"match_all": {}
}
]
}
},
"from": 0,
"size": 20
}
마지막으로 저장된 데이터와 해당 데이터의 필드 타입이 어떻게 설정되었는지 확인합니다.
GET my-log-2023-07-10/
결과는 다음과 같습니다.
{
"my-log-2023-07-10": {
"aliases": {},
"mappings": {
"dynamic_templates": [
{
"default_string": {
"match": "default*",
"match_mapping_type": "string",
"mapping": {
"type": "keyword"
}
}
},
{
"default_number": {
"match": "default*",
"match_mapping_type": "long",
"mapping": {
"type": "integer"
}
}
}
],
"properties": {
"cluster": {
"type": "keyword"
},
"default-number": {
"type": "integer"
},
"default-text": {
"type": "keyword"
},
"level": {
"type": "keyword"
},
"message": {
"type": "text"
},
"node": {
"type": "keyword"
},
"timestamp": {
"type": "long"
}
}
},
"settings": {
"index": {
"opendistro": {
"index_state_management": {
"policy_id": "my-ism"
}
},
"refresh_interval": "5s",
"number_of_shards": "4",
"provided_name": "my-log-2023-07-10",
"creation_date": "1688992258343",
"number_of_replicas": "1",
"uuid": "n24SvkagRl2OI0NcHb5SXw",
"version": {
"created": "136297827"
}
}
}
}
}
template으로 지정한 필드의 경우 정상적으로 필드의 타입이 적용된 것을 확인할 수 있습니다. 그리고 default-number와 default-text의 경우 직접적으로 지정하지는 않았지만 dynamic_templates 설정을 통하여 자동적으로 문자열 타입은 keyword로 지정되고 숫자 타입은 integer로 설정된 것을 확인할 수 있습니다.
'Opensearch' 카테고리의 다른 글
Elasticsearch에서 Opensearch로 서비스 Migration (0) | 2023.10.27 |
---|---|
Opensearch Searchable Snapshot (0) | 2023.07.17 |
Opensearch Snapshot (AWS S3)백업 및 복구 (0) | 2023.07.17 |
Opensearch SM(Snapshot Management) (0) | 2023.07.17 |
Opensearch ISM(Index State Management) (0) | 2023.07.13 |