DevOps/ElasticSearch

[ElasticSearch] 인덱스, 샤드, 세그먼트, 타입, 매핑

kyoulho 2024. 10. 18. 19:00

인덱스

인덱스는 데이터를 저장하는 가장 큰 논리적 단위로, 각 인덱스는 샤드로 나누어져 저장됩니다. 인덱스는 관계형 데이터베이스의 테이블과 유사하게, 각 인덱스는 특정 유형의 데이터를 저장하며 여러 문서 (document)의 집합으로 이루어져 있습니다. 각 문서는 JSON 형식으로 저장됩니다.

인덱스의 구조와 설정

  • 인덱스는 클러스터 내에서 유일해야 하며, 중복된 이름의 인덱스를 생성할 수 없습니다. 이는 데이터 관리와 검색의 효율성을 높이기 위한 것입니다.
  • 만일 nginx의 액세스 로그를 수집한다면 nginx-access-log-YYYY.MM.DD 식의 이름을 사용하는 것을 추천합니다.


타입

과거 엘라스틱서치에서는 하나의 인덱스에 여러 타입 (Type)을 정의할 수 있었습니다. 타입은 서로 다른 데이터 유형을 하나의 인덱스에 저장할 수 있게 해 주었습니다. 그러나 타입 간의 필드 충돌 문제와 관리 복잡성으로 인해, 여러 타입을 사용하는 것이 점점 비효율적이라는 평가를 받기 시작했습니다.

타입의 제거 과정

  • 7.x 버전: 엘라스틱서치 7.x 버전 이후로는 하나의 인덱스에 여러 타입을 사용하는 것이 권장되지 않았습니다. 여러 타입을 사용할 경우, 같은 이름의 필드가 다른 매핑을 가지게 되어 데이터 일관성이 깨질 위험이 있었기 때문입니다. 이로 인해 엘라스틱서치는 인덱스 설계의 단순화와 데이터 충돌 방지를 목표로 타입 개념을 축소하기 시작했습니다.
  • 8.x 버전: 엘라스틱서치 8.x 버전에서는 타입 개념이 완전히 제거되었습니다. 이제 모든 문서는 기본적으로 _doc이라는 단일 타입으로 저장됩니다. 이는 데이터를 보다 간단하고 일관되게 관리할 수 있도록 돕습니다. 타입 제거로 인해 각 인덱스는 하나의 데이터 유형만을 나타내도록 설계되어야 하며, 데이터 모델링이 더 명확하고 단순해졌습니다.

현재의 타입 구조

이제 모든 문서는 _doc이라는 단일 타입으로만 저장됩니다. 이를 통해 데이터 모델의 혼란을 줄이고, 인덱스의 구조를 간소화하여 성능을 최적화할 수 있습니다. 단일 타입 구조는 데이터 검색 시 일관성을 유지하는 데 중요한 역할을 합니다.


샤드

샤드 (Shard)는 인덱스의 데이터를 여러 노드에 분산하여 저장하는 논리적인 공간이며, 프라이머리 샤드복제본 샤드로 구성됩니다. 프라이머리 샤드와 복제본 샤드는 서로 다른 노드에 저장되며, 하나의 노드에 동일한 번호의 프라이머리/레플리카 샤드를 두지 않음으로써 노드 장애 발생 시 데이터의 안정성을 확보합니다.

프라이머리 샤드 (Primary Shard)

모든 데이터는 먼저 프라이머리 샤드에 저장됩니다. 인덱스에 저장되는 문서는 id를 이용해 해시 알고리즘에 의해 각 샤드로 분배됩니다. 이를 통해 엘라스틱서치는 문서가 어느 샤드에 저장될지 결정하게 되며, 이로 인해 데이터는 균형 있게 분산됩니다.

최초 인덱스를 생성할 때 프라이머리 샤드의 개수를 결정하는데, 이때 결정한 프라이머리 샤드의 개수는 이후에 변경할 수 없습니다. 인덱스를 생성할 때 프라이머리 샤드 개수를 지정하지 않으면 기본적으로 1개의 프라이머리 샤드가 생성됩니다.

복제본 샤드 (Replica Shard)

복제본 샤드는 기본적으로 프라이머리 샤드당 1개의 복제본이 생성됩니다. 또한, 장애가 발생해 프라이머리 샤드가 손실되면 해당 복제본 샤드가 프라이머리 샤드로 승격되어 데이터의 가용성을 유지하게 됩니다. 복제본 샤드는 또한 검색 요청 시 부하를 분산시키는 역할을 합니다. 프라이머리 샤드와 복제본 샤드는 서로 다른 노드에 저장되며, 이를 통해 데이터의 안정성을 보장하고 클러스터 장애 시에도 데이터를 안전하게 유지할 수 있습니다. 복제본 샤드는 운영 중에도 샤드 개수를 변경할 수 있습니다.


세그먼트

인덱스에 저장되는 문서는 해시 알고리즘에 의해 샤드들에 분산 저장되고, 이 문서들은 실제로는 세그먼트라는 물리적 파일에 저장됩니다. 하지만 문서가 처음부터 세그먼트에 저장되는 것은 아닙니다. 색인된 문서는 먼저 시스템의 메모리 버퍼 캐시에 저장되며, 이 단계에서는 해당 문서가 검색되지 않습니다. 이후 엘라스틱서치의 refresh라는 과정을 거쳐야 디스크에 세그먼트 단위로 문서가 저장되고, 해당 문서의 검색이 가능해집니다.

세그먼트 구조

세그먼트는 변경 불가능한(immutable) 파일로, 새로운 데이터가 추가되거나 변경될 때마다 새로운 세그먼트가 생성됩니다. 또한 이전의 세그먼트는 불용 처리(삭제 플래그)됩니다. 이러한 동작은 업데이트뿐 아니라 삭제(delete) 시에도 동일합니다.

세그먼트 머지 (Merge)

시간이 지나면서 세그먼트가 많아지면 검색 성능이 저하될 수 있습니다. 이를 방지하기 위해 엘라스틱서치는 주기적으로 여러 세그먼트를 병합하여 더 큰 세그먼트로 만들고 불용 처리된 세그먼트들은 제거합니다. 병합은 시스템의 백그라운드에서 자동으로 수행됩니다.

 

매핑

매핑은 엘라스틱서치에서 문서(document) 구조를 정의하는 스키마와 유사한 개념입니다. 저장될 JSON 문서들이 어떤 키와 어떤 형태의 값을 가지고 있는지 정의한 것입니다. 매핑은 각 필드의 이름, 데이터 유형, 분석 방법 등을 지정하여 엘라스틱서치가 데이터를 효과적으로 저장하고 검색할 수 있도록 돕습니다.

매핑의 역할

  • 데이터 유형 지정: 각 필드의 데이터 유형을 지정하여 문자열, 숫자, 날짜 등으로 데이터를 처리할 수 있습니다.
  • 분석 및 검색 최적화: 필드의 인덱싱 방법, 텍스트 분석기 설정 등을 통해 검색 성능을 최적화할 수 있습니다.
  • 필드 속성 정의: 예를 들어, 필드가 검색 가능한지 여부, 정렬 가능한지 여부, 혹은 전체 텍스트 검색에 사용할지를 정의할 수 있습니다.

정적 매핑 (Static Mapping)

정적 매핑은 인덱스를 생성할 때 매핑을 명시적으로 정의하는 방식입니다. 각 필드의 데이터 유형과 속성을 사전에 정의하여 데이터의 일관성을 유지하고, 검색 및 색인 작업을 최적화할 수 있습니다. 정적 매핑을 사용하면 예상치 못한 데이터 유형이 추가되는 것을 방지할 수 있습니다.

동적 매핑 (Dynamic Mapping)

동적 매핑은 새로운 문서가 인덱스에 삽입될 때 자동으로 필드의 유형을 설정하는 방식입니다. 동적 매핑은 사전에 필드 구조를 정의하지 않아도 데이터를 유연하게 저장할 수 있도록 해주며, 개발 초기에 데이터 구조가 확정되지 않은 경우에 유용합니다.

엘라스틱서치는 새로운 필드가 등장할 때 해당 필드의 데이터 유형을 자동으로 추론하여 매핑에 추가합니다. 그러나 이 방식은 의도치 않은 데이터 유형이 잘못 매핑되는 문제를 야기할 수 있어 주의가 필요합니다.

필드 데이터 타입의 종류

코어 데이터 타입 설명 종류
String 문자열 text, keyword
Numeric 숫자형 long, integer, shor, byte, double, float, half_float, scaled_float
Date 날짜형 date
Boolean boolean
Binary 바이너리 binary
Range 범주 integer_range, float_range, long_range, double_range, date_range

 

728x90

'DevOps > ElasticSearch' 카테고리의 다른 글

[ElasticSearch] 클러스터와 노드  (1) 2024.10.20
[ElasticSearch]모니터링: Prometheus와 X-Pack  (1) 2024.10.19