본문 바로가기
💻 개발 이야기/ELK Stack

[ELK] 엘라스틱서치 클러스터를 구성하는 다양한 노드에 대해 알아보자

by Jinseong Hwang 2023. 10. 17.

 
안녕하세요. 황진성입니다.
 
오늘은 Elasticsearch에서 클러스터를 구성하는 다양한 종류의 노드를 알아보고, 특히 마스터 노드가 선출되는 과정과 주의해야 할 점에 대해서도 알아보겠습니다.

 

이 글의 내용은 작성일 기준 최신 버전인 Elasticsearch 8.10 문서를 따라 작성됐습니다.

 

클러스터 구성에 앞서,


클러스터를 구성해야 하는 이유

일반적으로 클러스터는 여러 대의 컴퓨터를 병렬로 연결해서 마치 하나의 시스템인 것처럼 구성하는 것을 의미합니다. 클러스터를 구성하면  시스템 장애를 대비한 고가용성(High availability)을 높이는 동시에 시스템 성능도 높일 수 있습니다. Elasticsearch는 클러스터 구성에 필요한 여러 기능을 제공하고 있으며, 분산 처리를 지원하고 있기 때문에 굉장히 큰 데이터도 다룰 수 있습니다.
 

노드란?

클러스터를 직접 구성하는 컴퓨팅 단위를 노드(Node)라고 합니다. 클러스터는 여러 노드의 집합인데, 각 노드는 Elasticsearch가 설치되는 물리적 or 논리적 단위입니다. 일반적으로 하나의 컴퓨터를 하나의 노드로 구성하는데, 물리적인 서버뿐만 아니라 가상 서버로도 노드를 구분합니다.
 

노드가 통신하는 방법

노드가 통신할 때는 2가지 방법으로 통신합니다. 하나는 클러스터 내부에서 노드 간 통신할 때 사용하는 전송 모듈(Transport module)이고, 다른 하나는 클러스터 외부와 통신할 때 사용하는 REST API 기반의 HTTP 모듈입니다.
 
각 방식의 특징을 정리해보면 다음과 같습니다.
 
[전송 모듈]

  • 클러스터 내부에서 모듈(노드) 간 통신에 사용한다.
  • 노드 간 데이터를 분산 처리하는 구조에 적합한 방식이다.
  • 기본 포트는 9300 ~ 9399 이다.

[HTTP 모듈]

  • Elasticsearch API에서 제공하는 형태로 외부 클라이언트와 통신 시 사용한다.
  • 기본 포트는 9200 ~ 9299이다.

자세한 정보는 여기에서 확인하실 수 있습니다.
 

사용 중인 클러스터 정보 확인하기

여러 개의 노드를 하나의 Elasticsearch 노드처럼 동작하게 하는 것이 클러스터라고 말했습니다. 따라서 클러스터를 구성하는 어느 노드에 API 요청을 해도 동일한 응답을 보장합니다.
 
노드에 API 요청을 보내서 클러스터 정보를 알아내봅시다. 클러스터 정보를 확인하기 위해서는 대상 노드의 루트 경로로 요청을 보내면 됩니다. 현재 저는 로컬의 9200번 포트에서 Elasticsearch를 실행하고 있기 때문에 localhost:9200으로 요청을 보내면 됩니다.

http://localhost:9200

  • name : 현재 요청에 응답한 노드의 이름입니다. 노드 별로 이름이 다릅니다.
  • cluster_name, cluster_uuid : 클러스터의 이름과 고유값입니다. 클러스터 내 모든 노드가 동일한 값을 가집니다.
  • version : 사용 중인 Elasticsearch의 버전, 빌드 정보, 루씬 버전, 호환 버전 등의 정보입니다.
  • tagline : Elasticsearch의 슬로건인 듯합니다. 마치 나이키의 Just Do It과 같은...

 
 

노드 역할 설정하기


노드는 클러스터를 구성하는 하나의 인스턴스입니다. 일반적으로 하나의 논리적인 서버로 구성되어 데이터를 저장하고 클러스터의 인덱싱과 검색 기능에 참여합니다. 물리적인 서버 하나에 노드 하나를 구성하는 것을 권장하지만, 단일 서버에 복수의 노드를 구성해도 됩니다.
 
클러스터에 참여하는 노드의 이름은 모두 클러스터 내에서 고유하며, 각기 다른 역할을 가지고 동작합니다. 마스터 노드, 데이터 노드, 인제스트 노드, 머신러닝 노드, 코디네이터 노드 등이 있습니다. 각 역할에 대해 알아봅시다.
 
노드 별로 역할을 설정해 주기 위해서는 elasticsearch.yml 파일에 node.roles 값을 작성해 주면 됩니다.
작성할 수 있는 role은 다음과 같습니다. (8.10 버전 기준)

https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-node.html

# elasticsearch.yml
node.roles: [ data, master, voting_only ]

 
 

마스터 노드


# elasticsearch.yml
node.roles: [ master ]

정상적인 클러스터를 유지하기 위해 반드시 존재해야 하고, 마스터 노드가 없으면 클러스터 전체는 동작을 멈춥니다.
클러스터는 반드시 하나의 마스터 노드를 가져야 합니다. 마스터 노드의 역할은 다음과 같습니다.

  • 인덱스의 메타 데이터, 샤드의 위치와 같은 클러스터 상태 정보 관리
  • 클러스터 내 각 노드들과 통신하면서 클러스터의 변화를 모니터링

 
마스터 노드는 사용자가 직접 정하는 것이 아니라, 다수의 마스터 후보 노드가 투표를 통해 결정됩니다. 사용자는 마스터 후보 노드(Mater eligible node)만 지정할 수 있습니다. 마스터 노드가 선출되는 과정에서 발생할 수 있는 다양한 상황에 대해 알아봅시다.
 
표를 클러스터라고 가정합시다.
 

상황 1 : 클러스터에 4개의 노드 중 3개의 노드만 투표권을 가질 때 마스터 노드를 선출하는 경우

노드 이름 마스터 후보 여부 비고
노드1 O 노드1을 마스터 노드로 추천한다.
노드2 O 노드1을 마스터 노드로 추천한다.
노드3 O 이미 과반수가 넘어 투표에 참여하지 않는다.
노드4 X 투표권이 없다.

위 상황에서는 노드1이 과반수 이상의 투표를 받았기 때문에 마스터 노드로 선출됩니다. 노드1, 2, 3이 투표권을 가지고 있는 마스터 후보 노드이고 클러스터 내에서 N/2 + 1 (N=마스터 후보 노드 수) 이상의 표를 얻은 노드가 마스터 노드로 선출되는데, 노드 1이 3/2 + 1 = 2(소수점 버림) 표를 받았으므로 마스터 노드가 됩니다.

자기 자신에게 투표하는 것이 가능합니다.

 

상황 2 : 클러스터의 마스터 노드인 노드1이 이탈된 경우

노드 이름 마스터 후보 여부 비고
노드1 - 문제가 발생해서 클러스터에서 이탈한 상황.
노드2 O 노드3을 마스터 노드로 추천한다.
노드3 O 노드3을 마스터 노드로 추천한다.
노드4 X 투표권이 없다.

기존에 마스터 노드이자 마스터 후보 노드였던 노드1이 클러스터에서 이탈된 경우입니다. 이 때 마스터 노드를 재선출 해야 합니다. 위 표를 보면, 클러스터 내에 마스터 후보 노드이자 투표권을 가진 노드는 2개입니다. 노드2, 3이 노드3에게 투표할 경우 2/2+1=2표를 받기 때문에 마스터 노드로 선출됩니다.
 

상황 3 : 노드1이 클러스터에 복귀하는 경우

노드 이름 마스터 후보 여부 비고
노드1 O 클러스터에 복귀한다.
노드2 O -
노드3 O 여전히 마스터 노드이다.
노드4 X -

노드1은 이탈 전에 마스터 노드였지만, 이미 클러스터는 노드3을 마스터 노드로 선출한 상황입니다. 클러스터 내 노드들은 이미 마스터 노드인 노드3과 정보를 주고받고 있기 때문에 노드1이 복귀했다고 해서 다시 마스터 노드를 선출하지 않아도 됩니다. 따라서 추가적인 투표는 진행되지 않습니다.
 

상황 4 : 스플릿 브레인이 발생한 경우

[클러스터A]
노드 이름
마스터 후보 여부 비고
노드1 O 다른 노드들과 통신이 되지 않는다. 노드1을 마스터 노드로 추천한다.
독립 클러스터에서 마스터 노드로 선출되어 운영된다.
[클러스터B]
노드 이름
마스터 후보 여부 비고
노드2 O 노드3을 마스터 노드로 추천한다.
노드3 O 노드1과 통신이 되지 않는다. 노드3을 마스터 노드로 추천한다.
기존 클러스터에서 마스터 노드로 선출되어 운영된다.
노드4 X -

스플릿 브레인(Split brain)은 네트워크 장애 등으로 클러스터가 분리되었을 때, 나누어진 각각의 서브 클러스터가 서로 마스터 노드를 선출하고 독립적인 클러스터로 동작하는 상태를 의미합니다.
 
클러스터에서 스플릿 브레인이 발생하면 2개의 독립적인 클러스터로 운영되기 때문에 클러스터 상태나 인덱싱 된 데이터 등 차이가 발생합니다. 추후 네트워크가 복구되고 하나의 클러스터로 다시 합쳐질 때 데이터 정합성, 데이터 무결성 등에 문제가 생기는 등의 동기화 문제가 발생하게 됩니다.
 
스플릿 브레인을 방지하기 위해서는 마스터 후보 노드를 3 이상의 홀수 개수만큼 배치하면 됩니다. elasticsearch.yml 파일에서 `discovery.zen.minimum_master_nodes: 2`와 같이 설정할 수 있습니다. 이렇게 설정하면 네트워크 문제로 클러스터가 분리되었을 때 마스터 후보 노드 개수가 2 이상인 클러스터만 살아있고, 그렇지 않은 클러스터는 죽게 됩니다. 클러스터 처리량은 줄어들겠지만, 데이터 동기화 문제는 피할 수 있습니다.
 
즉, 스플릿 브레인 문제를 회피하기 위해서 마스터 후보 노드의 개수는 항상 홀수로 하고, 최소 마스터 후보 노드(minimum_master_nodes)는 `전체 마스터 후보 노드`/2 + 1 개로 설정해야 합니다.
 
하지만 사용자가 minimum_master_nodes 값을 임의로 설정하다 보면 실수할 수도 있습니다. Elasticsearch 7.0 이후부터는 마스터 노드 선출 알고리즘이 변경되면서 minimum_master_nodes 값을 직접 지정하지 않기 때문에 스플릿 브레인은 발생하지 않습니다. 하지만 이전 버전을 사용해야 하는 일이 있을 수도 있으니 알아두면 좋을 것 같습니다.
 

상황 5 : 투표 전용 노드가 마스터 선출을 도와주는 경우

노드 이름 마스터 후보 여부 투표 전용 여부 비고
노드1 O X 마스터 후보 노드로서 투표권이 있다.
노드2 O X 마스터 후보 노드로서 투표권이 있다.
노드3 X O 투표 전용 노드로서 투표권이 있다.

Elasticsearch 7.3 버전부터 마스터 후보 노드 중에서 마스터 노드를 선정하는 투표에는 참여하지만 실제 마스터 후보 노드는 아닌 노드들이 추가됐습니다. 투표 전용 노드(Voting only node)입니다.
 

노드 이름 마스터 후보 여부 투표 전용 여부 비고
노드1 O X 마스터 후보 노드로서 투표권이 있다.
노드2 - - 마스터 노드였지만 문제가 발생했다!
노드3 X O 투표 전용 노드로서 투표권이 있다.

기존 마스터 노드였던 노드2에 문제가 발생하면 마스터 노드를 재선출해야 합니다. 현재 이 클러스터에 남아있는 마스터 후보 노드는 노드1이 전부이다. 최소 마스터 후보 노드 수가 부족해서 클러스터는 마스터 노드를 선출할 수 없고 시스템이 중단됩니다.
 
하지만 노드3을 투표 전용 노드로서 활용하면 이 문제를 해결할 수 있습니다. 노드1과 노드3이 함께 노드1을 마스터 노드로 투표하면 노드1은 과반수 이상의 표를 얻게 되어 마스터 노드로 선출됩니다.
 
투표 전용 노드는 마스터 노드가 되지 않기 때문에 마스터 후보 노드보다 부담 없이 운영할 수 있습니다. 마스터 후보 노드들에게 대량으로 장애가 발생한 경우에도 투표 전용 노드를 적극 활용하면 고가용성을 지속적으로 보장할 수 있습니다.
 

# elasticsearch.yml
node.roles: [ master, voting_only ]

마스터 노드가 될 수 없다는 것을 의미하지만, master role은 가지고 있어야 voting_only role을 가질 수 있습니다.
 

주의사항
위 예시와는 달리, 기본적으로 모든 노드가 마스터 후보 노드입니다. 하지만 클러스터가 점점 커지면서 노드와 샤드의 개수가 많아지면 모든 노드가 마스터 노드의 정보를 공유하는 것이 부담이 될 수 있습니다. 따라서 사용자가 마스터 후보 노드를 미리 고르는 것이 전체 클러스터 성능에 도움이 될 수 있습니다.

 
 

데이터 노드


# elasticsearch.yml
node.roles: [ data ]

데이터 노드는 인덱싱 한 도큐먼트를 샤드 형태로 저장하여 데이터의 CRUD 작업과 검색, 집계 작업을 수행합니다. 실질적인 데이터 프로세싱 작업이 일어나기 때문에 가장 많은 부하를 받습니다.
 
일반적으로 데이터 노드는 마스터 노드와 별도로 운영합니다. 마스터 노드는 마스터 노드의 역할만 수행하고, 데이터 노드는 데이터 노드의 역할만 수행하는 것이 좋습니다. 만약 마스터 노드와 데이터 노드를 병행하는 경우, 데이터 노드의 부하로 마스터 노드의 성능이 떨어지면 클러스터 전체의 성능이 떨어지기 때문입니다. (성능 이슈 때문에 마스터 노드가 죽어버리면 클러스터 전체 종료...)
 
따라서 데이터 노드는 컴퓨팅 리소스(CPU, Memory, I/O 등) 모니터링을 계속 진행해야 합니다. 상황에 맞게 명시적으로 샤드 재분배를 하거나 데이터 노드를 스케일 아웃/스케일 업 등의 작업을 해줘야 합니다.
 
 

인제스트 노드


# elasticsearch.yml
node.roles: [ injest ]

https://www.elastic.co/guide/en/elasticsearch/reference/current/ingest.html

인제스트 노드(Ingest node)는 도큐먼트의 가공과 정제를 위한 인제스트 파이프라인이 실행되는 노드입니다. 인제스트 노드는 파이프라인을 통해 도큐먼트를 Elasticsearch에 인덱싱 하기 전에 원하는 형태로 전처리 할 수 있습니다.
 
얼핏 보면 Logstash의 필터와 비슷한 기능을 가지고 있습니다. 차이점으로는 다음과 같습니다.

  • 실행 주체가 Elasticsearch이다.
  • Logstash 설치 없이 Beats만 설치해서 데이터를 수집하고, 인제스트 파이프라인을 통해 데이터를 가공할 수 있다.

 
입력 데이터가 많아지면 인덱싱 요청을 버퍼에 모아서 넘겨주거나, 좀 더 복잡한 가공을 할 수 있다는 점에서 Logstash가 필요한 경우도 있습니다. 하지만 가볍고 간단하게 사용하고 싶다면 Beats와 인제스트 파이프라인을 활용해 봐도 좋을 것 같습니다.
 
새로운 인덱스, 기존 인덱스에 파이프라인을 적용해서 데이터를 가공하는 방법에 관한 내용은 아래 링크에 너무 자세하게 나와있습니다.
https://www.elastic.co/guide/en/elasticsearch/reference/current/ingest.html
 
 

머신러닝 노드


# elasticsearch.yml
node.roles: [ ml ]

머신러닝 노드(Machine learning node)는 Elasticsearch가 제공하는 머신러닝 기능을 이용할 수 있는 노드입니다. 데이터 이상 탐지(anomaly detection) 기능, 시계열 예측, 분류나 회귀 분석 등을 포함해서 여러 기능이 있다고 합니다.
 
유료 라이선스에 포함된 기능이라고 하니 당장 사용해보지는 못하지만, 아래와 같이 Kibana를 통해 이상 탐지를 할 수 있다고 합니다.

https://www.elastic.co/kr/blog/sizing-machine-learning-with-elasticsearch

 
 

코디네이터 노드


# elasticsearch.yml
node.roles: [ ]

코디네이터 노드(Coordinator node)는 REST API 요청을 처리하는 역할을 하는데, 기본적으로 모든 노드가 코디네이터 역할을 수행할 수 있습니다. 코디네이터 노드는 데이터 노드에서 검색 및 집계된 데이터를 받아서 취합해서 결과를 전달하는 역할을 수행합니다.
 
데이터 노드가 검색과 집계 연산에만 집중하고 그 외 나머지는 코디네이터 노드가 작업을 수행하도록 해서 부하를 분산하기 위해 사용합니다. 코디네이터 노드는 노드 로드밸런싱, 요청 라우팅, 요청 캐싱, 데이터 취합 등의 기능에만 온전히 집중할 수 있습니다.
 
 

노드 별 적절한 하드웨어 사양은?


  CPU 메모리 저장장치
roles: master 저사양 저사양 저사양
roles: data 고사양 고사양 고사양
roles: injest 고사양 중간사양 저사양
roles: (coordinator) 저사양 중간사양 저사양
  • master : 클러스터 상태 관리가 주목적이기 때문에 성능이 중요하지 않다.
  • data : 가장 많은 연산이 수행되기 때문에 높은 성능이 필요하다.
  • injest : 데이터 수집 및 전처리 목적이기 때문에 저장장치는 비교적 중요하지 않다.
  • coordinator : 부하를 분산하는 역할이기 때문에 성능이 크게 중요하지 않다.

 

맺음말


정리하다 보니 내용이 꽤 길어진 것 같은데, Elasticsearch 클러스터를 구축할 때 도움이 되길 바라면서 작성해 봤습니다. 다음 게시글에서는 클러스터 구축 시 고려해야 할 점, 데이터 노드의 효율을 높이는 방법, 샤드를 구성하는 방법 등에 대해 다뤄보겠습니다. 긴 글 읽어주셔서 감사합니다.
 
언제나 질문 환영합니다!
 
 

References