•
클러스터와 노드의 의미
•
인덱스와 타입의 의미
•
샤드와 세그먼트의 의미
•
매핑의 역할과 의미
4.1 클러스터와 노드의 개념
: 클러스터란 여러 대의 컴퓨터 혹은 구성 요소들을 논리적으로 결합하여 전체를 하나의 컴퓨터 혹은 하나의 구성 요소처럼 사용할 수 있게 해주는 기술
: ElasticSearch 클러스터 역시 여러 개의 ElasticSearch 프로세스들을 논리적으로 결합하여 하나의 ElasticSearch 프로세스처럼 사용할 수 있게 해준다.
: 그리고 이때 클러스터를 구성하는 하나의 ElasticSearch 프로세스들을 각각 노드라 부른다.
•
클러스터란
: 왜 클러스터를 사용할까? 단일노드로 ElasticSearch를 구현할 경우, 해당 노드에 장애가 발생하면 ElasticSearch 클러스터에 접근할 수 없게 된다.
: 반면에 다수의 노드로 클러스터를 구성하면 하나의 노드에 장애가 발생해도 다른 노드에 요청할 수 있기 때문에 안정적으로 클러스터를 유지할 수 있고 이를 통해서 높은 수준의 안정성을 보장할 수 있다.
: 클러스터를 구축하게 되면 임의로 uuid가 부여되고 클러스터 이름으로 노드들은 클러스터를 찾아 구축하게 된다.
•
노드란
: 클러스터와 마찬가지로 각각의 고유한 노드 이름과 UUID가 있고 역할에 따라 여러 가지 노드로 구분할 수 있다.
노드 역할 | 설명 |
마스터 | 클러스터 구성에서 중심이 되는 노드, 클러스터의 상태 등 메타데이터를 관리한다. |
데이터 | 사용자의 문서를 실제로 저장하는 노드 |
인제스트 | 사용자의 문서가 저장되기 전 문서 내용을 사전 처리하는 노드 |
코디네이트 | 사용자의 요청을 데이터 노드로 전달하고 다시 데이터 노드로부터 결과를 취합하는 노드 |
: 노드들은 하나의 역할만 하는 것이 아니라 여러 개의 역할을 할 수 있다.
◦
마스터 노드
: 마스터 노드는 클러스터의 메타데이터를 관리하는 역할을 수행하며 반드시 클러스터 내에 한 대 이상이 존재해야 한다.
: 클러스터 내의 모든 노드는 현재 노드의 상태, 성능 정보, 자신이 가지고 있는 샤드의 정보를 마스터 노드에 알린다.
: 마스터 노드는 이런 정보들을 수집하고 관리하면서 클러스터의 안정성을 확보하기 위해 필요한 작업들을 진행한다.
◦
데이터 노드
: 사용자가 색인한 문서를 저장하고 검색 요청을 처리해서 결과를 돌려주는 역할을 한다.
: 또한 자신이 받은 요청 중 자신이 처리할 수 있는 요청은 직접 처리하고 다른 데이터 노드들이 처리해야할 요청은 해당 데이터 노드에 전달한다.
: 이때 어떤 데이터 노드로 요청을 전달할 것인지는 마스터 노드를 통해 받은 클러스터의 전체 상태 정보를 바탕으로 한다.
◦
인제스트 노드
: 사용자가 색인하길 원하는 문서의 내용 중 변환이 필요한 부분을 사전에 처리한다. 데이터 노드에 저장하기 전에 특정 필드의 값을 가공해야 할 경우 유용하게 동작한다.
◦
코디네이트 노드
: 실제 데이터를 저장하고 처리하지는 않지만 사용자의 색인이나 검색 등 모든 요청을 데이터 노드에 전달하는 역할, 문서를 저장하지 않는 데이터 노드라고 생각하면 된다.
: 이때 유념해야할 부분이 있는데 클러스터를 구성할 때 한 개 이상의 마스터 역할 노드를 구성해도 실제로는 그 중 한 대만이 메타데이터를 관리하고 데이터 노드들을 관리하는 마스터 노드 역할을 수행한다.
: 나머지 마스터 역할 노드들은 현재 동작하고 있는 마스터 노드에 장애가 발생했을 때, 새로운 마스터가 될 수 있는 마스터 후보 노드가 된다.
: 마스터 후보 노드들은 마스터 노드로부터 지속적으로 클러스터 운영에 필요한 데이터를 전달받기 때문에 항상 같은 메타 데이터를 유지하고 있다. 그래서 마스터 노드에 장애가 발생할 경우 새로운 마스터 노드가 선출 되어도 문제없이 서비스를 이어갈 수 있다.
: ElasticSearch 클러스터를 구축하고자 한다면 역할에 따라 노드의 개수를 결정하여 클러스터를 구성해야 한다.
4.2 인덱스와 타입
: 인덱스는 사용자의 데이터가 저장되는 논리적인 공간을 의미하며 타입은 인덱스 안의 데이터를 유형별로 논리적으로 나눠 놓은 공간을 의미한다. 보통 인덱스와 타입에 대해 RDBMS와 비교하기도 한다.
ElasticSearch | RDBMS |
인덱스 | 데이터베이스 |
타입 | 테이블 |
: 인덱스는 RDBMS의 데이터베이스, 타입은 테이블과 비슷한 개념으로 볼 수 있다.
: 인덱스의 이름은 클러스터 내에서 유일해야 하며, 동일한 이름의 다른 인덱스를 만들 수는 없다. 인덱스에 저장된 문서들은 앞 절에서 배운 데이터 노드들에 분산 저장된다.
4. 3 샤드와 세그먼트
: 샤드는 인덱스에 색인되는 문서들이 저장되는 물리적인 공간을 의미하며 세그먼트는 샤드의 데이터들을 가지고 있는 물리적인 파일을 의미한다.
: 하나의 인덱스는 다수의 샤드로 구성되고 하나의 샤드는 다수의 세그먼트로 구성된다. 문서들이 인덱스 내에 샤드별로 저장된다는 개념을 정확히 이해하면 특정 샤드에 장애가 발생하는 경우 장애의 규모를 정확하게 측정할 수 있다.
: 샤드는 원본인 프라이머리 샤드와 레플리카 샤드로 구분되는 데, 만약 샤드 0에 장애가 발생하면 샤드 0에 저장된 문서에는 접근할 수 없게 되고 심각할 경우 문서가 유실될 수도 있다.
: 인덱스에 저장되는 문서는 해시 알고리즘에 의해서 샤드들에 분산 저장되고 이 문서들은 실제로는 세그먼트라는 물리적 파일에 저장된다. 하지만 문서가 처음부터 세그먼트에 저장되는 것은 아닌데, 가장 먼저 시스템의 메모피 버퍼 캐시에 저장된다, 이때는 문서가 검색되지 않는다. 이후 ElasticSearch의 refresh라는 과정을 거쳐 디스크에 세그먼트 단위로 문서가 저장되고 해당 문서의 검색이 가능해진다.
: ㅅ헤그먼트는 불변의 특성을 갖는다. 즉 기존에 기록한 데이터를 업데이트하지 않는다는 뜻이다. Insert나 Delete가 일어날 경우, 해당 문서의 버전을 변경하고 기존 데이터는 사용하지 못하게 불용처리 한다.
: 이 특성으로 인해 데이터의 일관성을 유지할 수 있다. 하지만 이렇게 세그먼트 단위로 파일을 생성해서 문서를 저장할 때, 불변의 특성을 유지하기 위해 여러 개의 세그먼트로 사용자의 문서를 색인한다.
: 따라서 시간이 지남에 따라 작은 크기의 세그먼트가 점점 늘어나면 사용자가 문서를 검색할 때마다 많은 수의 세그먼트들이 응답해야 한다는 단점이 생긴다. 또한 불용 처리한 데이터들로 인해 세그먼트의 사이즈가 불필요하게 커진다.
: 이러한 단점을 보완하기 위해 ElasticSearch는 백그라운드에서 세그먼트 병합을 진행한다. 세그먼트 병합이란 여러 개의 작은 세그먼트들을 하나의 큰 세그먼트로 합치는 작업이 무수히 일어나며 불용처리 되어진 데이터들은 실제로 디스크에서 삭제된다. 이렇게 세그먼트를 병합하면 사용자의 검색 요청 시 접근해야 하는 파일의 개수가 줄어들어 사용자의 요청에 그만큼 적은 비용으로 빠르게 응답할 수 있다.
4. 4 프라이머리 샤드와 레플리카 샤드
: ElasticSearch는 서비스의 연속성을 유지하기 위해 샤드의 상태를 관리하고 유실되지 않도록 프라이머리 샤드와 레플리카 샤드로 샤드를 나눠 관리한다.
: 레플리카 샤드는 프라이머리 샤드와 동일한 문서를 가지고 있기 때문에 사용자의 검색 요청에도 응답할 수 있다. 따라서 레플리카 샤드를 늘리면 검색 요청에 대한 응답 속도를 높일 수 있다.
: 프라이머리 샤드는 인덱스를 나눠 저장하는 것이므로 특정 프라이머리 샤드에 있는 데이터를 검색해야 하는 상황에서 해당 샤드가 존재하는 노드가 오류가 발생할 경우, 데이터를 제공할 수 없다.
: 하지만 레플리카 샤드는 이를 방지한다. 각 노드에 저장되는 프라이머리 샤드와 레플리카 샤드는 서로 다른 버전의 데이터를 가지고 있고 특정 노드에 장애가 발생해 프라이머리 샤드를 사용할 수 없다면
해당 프라이머리 샤드와 같은 버전의 레플리카 샤드를 프라이머리로 승격시키고 레플리카 노드를 다른 노드에 생성한다.
: 프라이머리 샤드는 인덱스 생성 시, 정의되며 동적으로 변경이 불가능하나 레플리카 샤드는 가능하다.
: 샤드의 개수는 안정성 측면 외에도 색인과 검색의 성능 확보면에서도 중요하다. 특정 노드가 특정 인덱스의 모든 프라이머리 샤드를 보유하고 있다면 다른 노드들은 해당 요청에 대해 해당 노드로 넘겨줄 수 밖에 없다. 하지만 여러 개의 샤드로 분산되어있다면 각각의 노드가 색인과 검색 요청을 분배하여 처리한다.
4. 5 매핑
: 매핑은 RDBMS와 비교하자면 스키마와 유사하다. ElasticSearch에 저장될 Json 문서들이 어떤 키와 어떤 형태의 값을 가지고 있는 지 미리 정의하는 것
: mapping API를 통해 인덱스의 매핑 정보를 확인할 수 있다.
: 매핑 정보는 미리 정의해도 되고 정의하지 않아도 된다. 미리 정의해놓고 사용하는 것을 정적 매핑이라고 부르며 정의하지 않고 사용하는 것을 동적 매핑이라고 한다.
: 매핑이 생성되면 이후부터 생성되는 문서는 기존 매핑 정보에 따라 색인되어야 한다, 최초에 인덱스를 생성할 때에는 문서를 색인하는 것만으로 동적 매핑이 잘 이뤄지지만 이후부터는 최초에 색인한 문서와 동일한 데이터 타입을 가진 문서를 색인해야 오류가 발생하지 않는다.
코어 데이터 타입 | 설명 | 종류 |
String | 문자열 데이터 타입 | text, keyword |
Numeric | 숫자형 데이터 타입 | long, integer, short, byte, double, float, half_float, scaled_float |
Date | 날짜형 데이터 타입 | date |
Boolean | 불 데이터 타입 | boolean |
Binary | 바이너리 데이터 타입 | binary |
Range | 범주 데이터 타입 | integer_range, float_range, long_range, double_range, date_range |
: 위 표와 같이 필드의 내용에 따라 지정할 수 있는 필드 데이터 타입이 다르며 같은 종류의 데이터라도 여러 가지 필드 데이터 타입이 존재한다.
4. 6 마치며
1.
ElasticSearch는 노드들의 역할을 정의하여 클러스터로 구성하며 클러스터 단위로 사용자의 색인이나 검색 요청을 받아 서비스한다.
2.
인덱스는 사용자의 문서가 젖아되는 가장 큰 논리적인 단위이며 문서는 인데스 내에 샤드라는 단위로 저장된다.
3.
샤드에 저장되는 문서는 실제로는 세그먼트라는 물리적인 파일에 저장된다.
4.
샤드는 하나 이상의 세그먼트들로 구성된다. 백그라운드에서 세그먼트의 병합 작업이 진행되며 이를 통해 작은 크기의 세그먼트들이 큰 크기의 세그먼트들로 병합된다.
5.
샤드는 원본 데이터를 저장하는 프라이머리 샤드와 복제본인 레플리카 샤드로 나뉘며 하나의 노드에 동일한 버전의 프라이머리/레플리카 샤드를 두지 않음으로써 노드 장애 발생시 데이터의 안정성을 확보한다.
6.
사용자의 문서가 저장될 때 문서의 데이터를 기준으로 데이터 타입을 정의하며 문서의 모든 피륻에 대해 데이터 타입을 정의한 것이 인덱스의 매핑이다.