본문 바로가기
DataOps/Elasticsearch

[Elasticsearch] 3. 인덱스 설계 (Template, Routing)

by BenKangKang 2024. 3. 13.

3.4 템플릿

템플릿의 필요성

  • 운영하다 보면 수시로 많은 양의 유사한 구조를 가진 인덱스를 생성해야 할 때가 많다. 매번 인덱스 매핑 설정값을 지정하는 건 수고가 많이 들어간다.
  • 템플릿을 사용하면 재사용할 수 있으므로, 업무 효율을 향상시키고 반복 작업을 줄일 수 있다. 또 사람의 실수를 줄일 수 있다.

3.4.1 인덱스 템플릿

PUT _index_template/template_1
{
  "index_patterns": ["te*", "bar*"],
  "priority": 1,
  "template": {
    "settings": {
      "number_of_shards": 1
    },
    "mappings": {
      "_source": {
        "enabled": true
      },
      "properties": {
        "host_name": {
          "type": "keyword"
        },
        "created_at": {
          "type": "date",
          "format": "EEE MMM dd HH:mm:ss Z yyyy"
        }
      }
    },
    "aliases": {
      "mydata": { }
    }
  },
  "composed_of": ["component_template1", "runtime_component_template"], 
  "version": 3,
  "_meta": {
    "description": "my custom"
  }
}
  • index_patterns: 패턴
  • priority: 적용 우선 순위
  • template: 템플릿 설정
  • composed_of: 컴포넌트 템플릿 설정
PUT bar_1

3.4.2 컴포넌트 템플릿

  • 인덱스 템플릿 간 중복되는 부분을 재사용하기 위해 사용하는 템플릿
  • 작은 템플릿 블록으로 쪼갠 것으로 다양한 인덱스를 관리할 때 효율적
PUT _component_template/timestamp_mappings
{
	"template": {
		"mappings": {
			"properties": {
				"timestamp": {
					"type": "date"	
				}
			}
		}
	}
}

PUT _component_template/my_shard_settings
{
	"template": {
		"settings": {
			"number_of_shards": 2,
			"number_of_replicas": 2,
		}
	}
}

3.4.3 레거시 템플릿

  • 인덱스 템플릿, 컴포넌트 템플릿 API 는 엘라스틱서치 7.8.0 부터 추가된 기능
  • 이전에 존재하던 템플릿 API는 레거시 템플릿이 됐음
  • 그냥 인덱스 템플릿과의 차이
    • _template을 사용
    • 컴포넌트 템플릿 조합 불가능
  • 주의
    • 레거시 템플릿은 적용 우선순위가 낮음
    • 무조건 인덱스 템플릿 우선으로 확인 후, 매칭되는 인덱스 템플릿 없을 때만 레거시 템플릿 확인

3.4.4. 동적 템플릿

PUT _index_template/dynamic_mapping_template

{
  "index_patterns": ["dynamic_mapping*"],
  "priority": 1,
  "template": {
		"settings": {
			"number_of_shards": 2,
			"number_of_replicas": 2
		},
        "mappings": {
            "dynamic_templates": [
            {
                "my_text": {
                    "match_mapping_type": "string",
                    "match": "*_text",
                    "mapping": {
                        "type": "text"
                    }
                }
            },
            {
                "my_keyword": {
                    "match_mapping_type": "string",
                    "match": "*_keyword",
                    "mapping": {
                        "type": "keyword"
                    }
                }
            }
            ]
        }
  }
}
  • match_mapping_type
    • 데이터를 JSON 파서를 이용해 확인
    • boolean, double, long, string, object, date
  • match, unmatch
    • 필드 이름이 지정된 패턴과 일치하는지 확인
  • patch_match, patch_unmatch
    • 필드 이름으로 마침표를 사용한 전체 경로 이용
    • my_object.name.text*

3.4.5 빌트인 인덱스 템플릿

  • 7.9.0 이상 버전은 미리 정의된 빌트인 템플릿 제공
  • 주의
    • metrics--, logs-- 인덱스 패턴에 priority 값 100 가진 템플릿이 사전 정의되어 있음 → 해당 인덱스 사용할 경우, priority 더 높게 생성하는 등 조취 필요

3.5 라우팅

  • 인덱스 구성하는 샤딩 중 몇 번 샤드를 대상으로 작업을 수행할지 지정하기 위해 사용하는 값
  • 문서를 색인할 때마다 문서마다 하나씩 지정 가능
  • 문서 만들 때 routing id 지정하면 특정 샤드에만 생성한다.
  • 필요한 이유
    • 특정 id 단위로 조회가 많이 들어올 수 있을 경우, 로그인 아이디를 라우팅 값으로 지정 → 아이디가 동일한 문서끼리 같은 샤드에 위치시켜 검색 성능을 끌어올릴 수 있음
      • 실제 적용 예시
        • 특정 유저의 댓글을 모아서 검색하고 싶을 경우, 라우팅 id 를 user id 로 지정한다.
PUT routing_test
{
	"settings": {
			"number_of_shards": 2,
			"number_of_replicas": 2
	}
}

PUT routing_test/_doc/1?routing=myid
{
	"login_id": "myid",
	"comment": "Hello World",
}

GET routing_test/_search

3.5.1 인덱스 내에서의 _id 고유성 보장

  • 인덱스 내에서 _id 값의 고유성 검증은 샤드 단위로 보장된다.
  • 색인, 조회, 업데이트, 삭제 작업이 모두 라우팅 수행 이후의 단일 샤드 내에서 이뤄지기 때문
  • 라우팅 값이 다르게 지정되면 한 인덱스 내에서 같은 _id 를 가진 문서가 여러 개 생길 수도 있다.

3.5.2 인덱스 매핑에서 라우팅을 필수로 지정하기

  • 담당자들은 라우팅 지정에 대한 정책을 세우고 인식을 조율할 필요가 있다.
    • 예시
      • 데이터 색인 부서와 댓글 데이터 조회하는 부서는 라우팅 값으로 로그인 아이디를 지정한다는 정책을 함께 지켜야한다.

해결책1 인덱스 만들 때 routing 값을 필수로 설정

PUT routing_test2
{
	"mappings": {
		"_routing": {
			"required": true
		}
	}
}

댓글