본문 바로가기

책/기초부터 다지는 ElasticSearch 운영 노하우- 프로그래밍인사이트

[ElasticSearch] ElasticSearch 기본 개념 (클러스터, 노드, 인덱스, 샤드, 세그먼트, 매핑)

 

안녕하세요!

키크니 개발자 입니다. 🦒

 

 

오늘은 간단하게 클러스터, 노드, 인덱스, 샤드, 세그먼트, 매핑에 대해서 알아보았습니다. 

 

 

클러스터란?

여러 대의 컴퓨터 혹은 구성 요소들을 논리적으로 결합하여 전체를 하나의 컴퓨터 혹은 하나의 구성 요소처럼 사용할 수 있게 해주는 기술이다.

 

클러스터 특징

  • 여러 개의 엘라스티서치 프로세스들은 논리적으로 결합하여 하나의 엘라스틱서치 프로세스처럼 사용할 수 있게 해준다.
    이 때 클러스터를 구성하는 하나 하나의 엘라스틱서치 프로세스를 노드라고 부른다.
  • 여러 개의 노드로 클러스터를 구성하고 이 노드들이 하나의 엘라스틱서치처럼 동작하기 때문에 어느 노드에 API를 요청해도 동일한 응답과 동작을 보장 받을 수 있다.
  • 단일 노드로 클러스터를 구성하게 되면 노드에 장애가 발생하면 엘라스틱서치 클러스터에 접근 할 수 없는 요청 불가 상태가 된다.
  • 다수의 노드로 클러스터를 구성하면 하나의 노드에 장애가 발생해도 다른 노드에 요청할 수 있기 때문에 높은 안정성을 보장한다.
    • 다수의 노드로 구성된 엘라스틱서치 클러스터는 고유의 클러스터 이름과 UUID를 가진다.
    • 두 가지 고유한 속성을 통해 클러스터 내에 속한 노드들이 서로 동일한 클러스터 내에 있음을 인식하고 클러스터링 된다.

클러스터 정보 확인하기

curl localhost:9200

결과값

{
    "name": "elasticsearch",
    "cluster_name": "my-elasticsearch",
    "cluster_uuid": "680Dns66RPKthRNwmENNcw",
    "version": {
        "number": "6.6.0",
        "build_flavor": "default",
        "build_type": "rpm",
        "build_hash": "a9861f4",
        "build_date": "2019-01-24T11:27:09.439740Z",
        "build_snapshot": false,
        "lucene_version" : "7.6.0",
        "minimum_wire_compativility_version" : "5.6.0",
        "minimum_index_compatibility_version" : "5.0.0"
    },
    "tagline": "You Know, for Search"
}
  • name : 클러스터에 속한 노드들 중 현재 요청에 응답한 노드의 이름
    다수의 노드로 구성되어있으면 노드별로 값이 달라질 수 있다.
  • cluster_name : 클러스터의 이름이다.새로운 노드를 클러스터에 추가하기 위해서는 같은 이름을 사용해야 된다. (아니면 에러 발생)클러스터에 속한 모든 노드들은 클러스터 이름이 같다.
  • cluster_uuid : 클러스터의 UUID이다.이 값은 클러스터가 최초 생성될 때 자동으로 생성되는 것으로 사용자가 지정하는 것은 아니다.클러스터에 속한 모든 노드가 동일한 값을 가진다.

노드란?

클러스터를 구성하는 논리적인 엘라스틱서치 프로세스 하나를 의미한다.

 

노드의 특징

  • 노드도 클러스터와 마찬가지로 각각의 고유한 노드 이름과 UUID가 있고 역할에 따라 여러 가지 노드로 구분할 수 있다.
  • 각각의 노드들은 하나의 역할만 하는 것이 아니라 동시에 다양한 역할을 할 수도 있다.
  • 클러스터를 구성할 때 역할에 따라 노드의 개수를 결정해서 클러스터를 구성해야 한다.

노드 역할

노드 역할 설명
마스터 노드 - 클러스터 구성에서 중심이 되는 노드
- 클러스터의 상태 등 메타 데이터를 관리(여러 개의 마스터 노드들은 항상 같은 메타 데이터를 유지)
- 반드시 한 대 이상으로 구성
- 클러스터 내에서 메타데이터를 관리하는 마스터 노드는 한 대, 나머지 마스터 노드는 장애가 발생했을 때 마스터 후보 노드가 된다.
- 마스터 노드는 마스터 역할이 가능한 노드와 실제 마스터 역할을 하는 노드로 구분
데이터 노드  - 사용자의 문서를 실제로 저장하는 노드
- 검색 요청을 처리해서 결과를 돌려주는 역할
- 자신이 처리할 수 있는 요청은 직접 처리 혹은 다른 데이터 노드들이 처리해야 할 요청은 해당 데이터 노드에 전달
인제스트 노드 - 사용자의 문서가 저장되기 전 문서 내용을 사전 처리하는 노드(특정 필드 값을 가공)
- 사용자가 색인하길 원하는 문서의 내용 중 변환이 필요한 부분을 사전에 처리
코디네이트 노드 - 사용자의 요청을 데이터 노드로 전달하고, 다시 데이터 노드로부터 결과를 취합하는 노드

 

인덱스란? 

사용자의 데이터가 저장되는 논리적인 공간을 의미하며 타입은 인덱스 안의 데이터를 유형별로 논리적으로 나눠 놓은 공간을 의미한다.

더보기

💡 논리적인 주소 공간, 물리적인 주소 공간이란?

 

- 논리적인 주소 공간: 논리적 주소 공간은 프로세스 관점에서 자신이 가지고 있는 메모리 크기

- 물리적인 주소 공간: 물리적 주소 공간은 하드웨어에 실제로 존재하는 주소

인덱스의 특징

  • RDBMS는 데이터베이스 안에 여러 개의 테이블을 가질 수 있지만, 엘라스틱서치는 6.x 버전 이후로는 하나의 인덱스에 하나의 타입만 가질 수 있다.
  • 엘라스틱서치는 6.x 버전 이후로 단일 타입만 허용하기 때문에 큰 이슈가 없다면 _doc 을 타입명으로 사용하게 된다. (엘라스틱서치는 _doc 타입을 권고한다.)
    • 엘라스틱서치 5.x 버전의 클러스터에는 ‘_' 를 사용하여 타입을 생성할 수 없다. (’_’를 사용하면 에러가 발생한다.)
    {
    	"type" : "invalid_type_name_exception",
    	"reason" : "Document mapping type name can't start with '_', found: [_doc]"
    }
    
  • 인덱스의 이름은 클러스터 내에서 유일해야 하며, 동일한 이름의 다른 인덱스를 만들 수 없다.
    • 엘러스틱서치 6.x에 멀티 타입을 적용하면 에러가 발생한다.
    {
    	"type" : "illegal_argument_exception",
    	"reason" : "Rejecting mapping update to [multimappings] as the final mapping would have more than 1 type: [type2, type1]"
    }
    
  • 엘라스틱서치 5.x 버전은 멀티 타입(하나의 인덱스에 여러 개의 타입)을 사용할 수 있었기 때문에 인덱스 내에서 타입이 논리적으로 분리될 수 있다.
    • 멀티 타입을 허용하지 않는 이유 : 인덱스에 존재하는 서로 다른 타입에서 동일한 이름(필드)의 JSON 문서 필드를 만들 수 있어서 의도치 않은 검색 결과가 나타나는 문제가 발생하였기 때문이다.
  • 버전 업그레이드 작업 전에 사용하고 있는 인덱스들 중에 멀티 타입을 사용하는 인덱스가 있는지 꼭 확인해야 한다. 만약 멀티 타입을 사용하는 인덱스가 있을 경우 타입별로 인덱스를 분리하는 형태로 재구성해야 한다.

저는 RDBMS의 개념이 ElasticSearch 보다 더 익숙하다 보니 용어가 헷깔리는 부분이 꽤 많았습니다.

💡 RDBMS 와 ElasticSearch 비교

Relational Database ElasticSearch
Database Index
Table Type
Row Document
Column Field
Index Analyze
Primary key _id
Schma Mapping
Physical partition Shard
Logical partition Route
Relational Parent/Child, Nested
SQL Query DSL

 

샤드란?

인덱스에 색인 되는 문서들이 저장되는 논리적인 공간

 

샤드의 특징

  • 하나의 인덱스는 다수의 샤드로 구성되고, 하나의 샤드는 다수의 세그먼트로 구성 된다.
  • 샤드는 1개 이상의 세그먼트로 구성 되는데 샤드마다 세그먼트 개수는 서로 다를 수 있다.
  • 인덱스를 샤드로 나누고 데이터 노드에 샤드를 할당한다. 각각의 샤드에 문서를 저장하는 방식으로 사용자의 데이터를 저장한다.
  • 샤드는 원본인 프라이머리 샤드복제본인 레플리카 샤드로 구성된다. (최악의 상황을 방지하기 위해 데이터를 복사하여 안정성을 보장한다.)
  • 프라이머리 샤드는 최초 인덱스를 생성할 때 개수를 결정(6.x버전 까지는 자동으로 5개 기본 설정)하는데 이 때 결정한 프라이머리 샤드는 이후에 변경할 수 없다.

인덱스의 프라이머리 샤드 개수 설정하여 생성하기

curl -X PUT "localhost:9200/shard_index?pretty" -H 'Content-Type: application/json' -d' 
{
	"index.number_of_shards":5 
}'
curl -X GET "localhost:9200/shard_index?pretty"

결과값

 

  • “number_of_shards” : “5” : 인덱스 설정에서 지정한 대로 5개의 프라이머리 샤드로 구성 된 인덱스가 생성되었다.
  • “number_of_replicas” : “1” : 레플리카 샤드의 개수를 지정하지 않았지만 기본값으로 한 개의 레플리카 샤드가 설정되었다.
  • 복제본인 레플리카 샤드는 운영 중에도 샤드 개수를 변경할 수 있다.

세그먼트란?

인덱스에 저장되는 문서는 해시 알고리즘에 의해서 샤드들에 분산 저장되고, 이 문서들은 실제로 세그먼트라는 물리적 파일에 저장된다.

 

세그먼트의 특징

  • 생성 된 문서는 처음부터 세그먼트에 저장되는 것이 아니라 시스템의 메모리 버퍼 캐시에 저장된다.
  • 불변의 특성을 갖는다. (기존에 기록한 데이터를 업데이트하지 않는다.)
  • 단점으로는 불변의 특성을 유지하기 위해 여러 개의 세그먼트로 사용자의 문서를 색인하고, 시간이 지나 많은 수의 세그먼트들이 응답해야 한다. (세그먼트의 크기가 커지게 된다.)
    • 이러한 단점을 보완하기 위해 백그라운드에서 세그먼트 병합을 진행한다.
    • 백그라운드에서 여러 개의 작은 세그먼트들을 하나의 큰 세그먼트로 합치는 작업을 의미한다.

문서 색인의 결과값

{
    "_index":"contents",
    "_type":"_doc",
    "_id":"1",
    "_version":2,1,
    "result":"updated",
    "_shards": {
        "total":2,
        "successful":1,
        "failed": 0
    },
    "_seq_no":1,
    "_primary_term":1
}
  • result : updated
    • 우리가 일반적으로 알고 있는 기존 데이터를 변경하는 과정이 아니다.
      데이터를 업데이트하려고 시도하면 새로운 세그먼트에 업데이트할 문서의 내용을 새롭게 쓰고, 기존의 데이터는 더 이상 쓰지 못하게 불용 처리 한다.
      이러한 동작은 update뿐만 아니라 delete도 마찬가지이다.
      delete를 시도하면 지우지 않고 불용처리만 한다. → 이 특성으로 인해 데이터의 일관성을 유지할 수 있다.

 

매핑이란?

RDBMS랑 비교하면 스키마와 유사하다.

엘라스틱서치에 저장 될 JSON 문서들이 어떤 키와 어떤 형태의 값을 가지고 있는지 정의한 것이다.

 

매핑 정보 확인

  • mapping API를 활용하여 인덱스의 매핑 정보를 확인할 수 있다. firstindex라는 인덱스에 정의 된 매핑 정보를 보는 API이다.
  • mappings 필드에 타입의 이름(_doc)이 나온다. 그 후 properties 필드 아래에 매핑 정보가 나온다.
curl -X GET "localhost:9200/firstindex/_mapping?pretty"
  • 정적 매핑 : 미리 정의해 놓고 사용하는 것
  • 동적 매핑 : 정의하지 않고 사용하는 것
  • 매핑의 데이터 타입과 다른 데이터가 색인 되는 경우 mapper_parsing_exception가 발생한다.

 

엘라스틱서치에서 사용 가능한 필드 데이터 타입의 종류

코어 데이터 타입 설명
String 문자열 데이터 타입
Numeric 숫자형 데이터 타입
Date 날짜형 데이터 타입
Boolean 불 데이터 타입
Binary 바이너리 데이터 타입
Range 범주 데이터 타입

 

  • 정리
    • 엘라스틱서치는 노드들의 역할을 정의하여 클러스터로 구성하며, 클러스터 단위로 사용자의 색인이나 검색 요청을 받아 서비스한다.
    • 인덱스는 사용자의 문서가 저장되는 가장 큰 논리적인 단위이며, 문서는 인덱스 내에 샤드라는 단위로 저장된다.
    • 샤드에 저장되는 문서는 실제로는 세그먼트라는 물리적인 파일에 정리된다.
    • 샤드는 하나 이상의 세그먼트들로 구성된다. 백그라운드에서 세그먼트의 병합 작업이 진행되며 이를 통해 작은 크기의 세그먼트들이 큰 크기의 세그먼트로 합쳐진다.
    • 샤드는 원본 데이터를 저장하는 프라이머리 샤드와 복제본인 레플리카 샤드로 나뉘며, 하나의 노드에 동일한 번호의 프라이머리/레플리카 샤드를 두지 않음으로써 노드 장애 발생시 데이터의 안정성을 확보한다.
    • 사용자의 문서가 저장될 때 문서의 데이터를 기준으로 데이터 타입을 정의하며, 문서의 모든 필드에 대해 데이터 타입을 정의한 것이 인덱스의 매핑이다.

 

 

 

 

References

- 기초부터 다지는 ElasticSearch 운영 노하우

http://www.yes24.com/Product/Goods/96520155

- https://medium.com/@vdongbin/node-js-%ED%99%98%EA%B2%BD%EC%97%90%EC%84%9C-aws-elastic-search-%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0-ba8c4ead7daf

반응형