Tagged: 엘라스틱서치

ElasticSearch 7.13 기반 책 리뷰

오래전에 “시작하세요! 엘라스틱서치” 라는 책을 구매해 본적이 있다. 지금도 소장하고 있는데, 엘라스틱서치에 대한 기본적인 개념을 익히는데 손색이 없는 책이라 평가하고 싶다. 단, 내가 볼때에 엘라스틱서치에 버전이 6.4 이다 보니 없어져버린 기능들은, 예를들어 펫싯, 볼 필요가 없었다.

오늘은 최신의 ElasticSearch 7.13 버전에서 이 책에 내용을 한번 살펴보고자 한다. 엘라스틱서치는 버전이 올라감에 따라 변경된 부분이 상당히 많아진다는 점을 생각해보면 꽤 도움이 될법한 내용들이라 생각한다.

엘라스틱서치의 데이터 구조 – 타입(Type) 없어짐

엘라스틱서치의 데이터 구조를 설명에서 인덱스(Index), 타입(Type), 도큐먼트(Document) 단위로 이루어진다고 설명했다. 하지만 엘라스틱서치 7.x 로 버전이 높아짐에 따라 타입은 이제 없다. 이에 대해서 엘라스틱서치 개발사에서 다음과 같은 페이지를 제공해 설명해 주고 있다.

위 문서를 보면 예를들어서 타입이 뭔지 설명하고 있으며 왜 없앴는지 타입을 이용했던 방법의 대안은 무엇인지 상세히 설명해 주고 있다.

그런데, 과연 타입(Type) 은 없어졌을까?

PUT 메소드 대신 POST 그리고 Content-Type 지정

책에 다음과 같은 예제가 나온다.

하지만 위와 같이 오류가 발생한다.

다음과 같이 Header 에 json 컨텐츠 타입을 지정해 줘야 한다.

앞서 매핑 타입이 없어졌다고 했지만 데이터를 입력하면 잘 들어 간다. GET 메소드를 이용한 조회도 잘 된다. 하지만 이것은 한가지 트릭과 같은데, 매핑에는 타입이 안나온다.

매핑 결과를 보면 타입(Type) 이 안나온다.

hotels 매핑 오류

책에는 hotels 인덱스 생성을 위해서 매핑(Mapping) 을 먼저 작성해 주는데 다음과 같다.

“Root mapping definition has unsupported parameters” 위와같이 오류가 발생 한다. 타입이 문제가 되는 경우라고 볼 수 있다. 위 내용을 수정하면 다음과 같다.

  • 매핑 타입 제거
  • string 타입을 제거하고 text 로 대체
  • not_analyzed 를 false 로 대체
  • dateOptionalTime 을 date_optional_time 으로 변경

성공적으로 생성 됐다.

Bulk 데이터 임포트

대량의 데이터를 엘라스틱서치에 입력할때에는 벌크(Bulk) api 를 이용한다. 매핑의 타입이 없기 때문에 타입을 제거해야 한다.

그리고 벌크 API 를 이용할때에는 다음과 같은 Content-Type 을 입력해줘야 한다.

위와같이 application/x-ndjson 을 지정해 줘야 한다.

ElasticSearch Nodes

ElasticSearch 는 노드(node) 로 불리운다. Node 는 ElasticSearch 의 독립된 인스턴스다. 그런데, 이 Node 에는 역할이 있으며 어떻게 Node 에 역할을 부여하는지에 해서 알아본다.

Node Type

Master Node

마스터 노드(Master Node) 는 ElasticSearch 의 클러스터(Cluster) 전체를 총괄하는 역할을 맡는다. ElasticSearch 는 분산검색엔진이며 각 노드들은 특정한 일을 하기 위한 하나의 그룹내의 멤버들로 관리되는데 이렇게 ‘하나의 그룹’ 을 클러스터라고 한다.

클러스터내에 노드들의 상태를 점검하고 이들의 유기적인 통제를 해야할 필요가 있는데, 이러한 역할을 하는 것이 바로 마스터 노드이다.

ElasticSearch 의 공식 문서에 보면 ‘Master Eligible Node’ 라는 말이 나온다. ‘마스터를 수행할만한 노드’ 정도로 해석되는데, 쉽게말하면 ‘마스터 후보군’ 이다. 이는 마스터 후보군이 존재하며 여기서 단 하나의 마스터가 선출되어 동장하고 만일 선출된 마스터가 장애를 겪는다면 마스터 후보군중에서 다른 마스터를 선출하게 된다.

Data Node

ElasticSearch 클러스터에서 실질적인 데이터를 저장하고 데이터 관련 연산을(Search, Aggregation 등) 수행하는 노드다.

샤드(Shard) 라는 개념이 바로 이 노드에 존재한다.

Ingest Node

파이프라인 스트림(Pipeline Stream) 이라고 한다. 문서를 인덱싱하기 전에 문서를 변형하는 역할을 수행 한다. 만일 각 노드에 대한 모니터링 기능을 켜게되면 반드시 Ingest Node 가 필요하게 된다.

Coordinating Node

코디네이팅 노드는 외부의 요청을 받아서 내부의 마스터 노드에 전달해준다. 벌크 인덱싱, 검색단계 줄이기등의 역할을 수행하기도 한다.

하나의 노드가 여러개의 역할을 중복해서 수행 가능하다. 그래서 개발을 위한 ElasticSearch 는 오직 하나의 노드만으로 모든 것을 할 수 있다.

 

Communication with Nodes

ElasticSearch 내에 노드들끼리는 TCP 통신을 기반으로 한다. 외부에 검색 쿼리(Query) 요청은 Http 통신을 기반으로 한다.

이제 여기서 생각을 해보자. 코디네이텅 노드의 역할을 분리해서 별도로 운영해야하느냐 하는 문제이다. 만일 코디네이텅 노드가 없을 경우에는 마스터 노드가 검색쿼리 요청을 받아야 하는 상황이 된다.

ElasticSearch 아키텍쳐1
ElasticSearch 아키텍쳐1

하지만 만일 코디네이팅 노드가 추가 된다면 다음과 같다.

ElasticSearch 아키텍쳐2
ElasticSearch 아키텍쳐2

뭘 하던간에 동작하는데에는 아무런 문제가 없지만 첫번재 아키텍쳐에서는 ELB 가 마스터 노드의 상태를 체크하고 잘못된 마스터 노드에 대해 제외를 시켜줘야 한다.

두번째 아키텍쳐에서는 ELB가 마스터 노드를 직접 제어하는 대신에 코디네이팅 노드를 제어한다.

유연성 측면에서 봤을때는 두번째 아키텍쳐가 더 좋아보이지만 그렇다고 딱히 아키텍쳐1번도 유연성에 문제가 있어보이지는 않는다.

Kibana 를 포함한 전체 아키텍쳐

Kibana 를 포함한 전체 아키텍쳐
Kibana 를 포함한 전체 아키텍쳐

Kibana 를 운영하기 위해서는 Ingest 노드가 필요하게 된다. 코디네이팅 노드를 포함하면 적어도 8개, Kibana 를 포함하면 9개 노드가 필요하게 된다.