DB Study

2장. 클러스터 아키텍처 — 노드들은 어떻게 한 팀이 되는가

마스터는 지휘하고, 데이터 노드는 일하고, coordinating 노드는 교통정리를 합니다. 이후 모든 트러블슈팅과 용량 산정은 이 장의 모델 위에서 이루어집니다.

중급 ⏱ 약 25분 🎬 애니메이션 3개 선수 지식: 1장 개요
🧭
이 장에서 배우는 것

① 노드 역할(master/data/coordinating 등)의 분리 ② cluster state — 클러스터의 단일 진실 ③ 마스터 선출과 쿼럼(왜 3대인가) ④ 검색·색인 요청이 coordinating 노드에서 샤드로 fan-out되는 흐름

2.1 노드 역할 — 한 노드는 하나의 프로세스가 아니라 "역할의 집합"

Elasticsearch 노드는 node.roles 설정으로 결정되는 하나 이상의 역할을 갖습니다. 소규모에서는 한 노드가 모든 역할을 겸하지만, 규모가 커지면 역할을 분리하는 것이 운영의 기본입니다.

역할약어하는 일
masterm클러스터 상태 관리, 인덱스 생성/삭제, 샤드 할당 결정
voting_onlyv마스터 선출 투표만 참여, 자신은 마스터가 되지 않음
data_contents검색 중심의 일반(비시계열) 데이터
data_hoth최근 시계열 데이터 — 빈번한 색인/검색, SSD
data_warmw색인이 끝난 데이터, 가끔 검색
data_coldc거의 검색 안 되는 오래된 데이터, searchable snapshot
data_frozenf스냅샷 저장소 부분 마운트 — 매우 저렴, 매우 느림
ingestiingest pipeline 실행 (문서 전처리)
ml / transforml / tMachine Learning / Transform 작업
(역할 없음)-coordinating-only — 요청 라우팅과 결과 머지만 담당
# elasticsearch.yml — 역할별 노드 설정 예

# 마스터 전용 노드: 데이터/검색 부하로부터 격리
node.roles: [ master ]

# hot 데이터 노드: 최신 데이터 색인 + 검색 + 전처리
node.roles: [ data_hot, data_content, ingest ]

# coordinating-only 노드: 역할을 전부 비운다
node.roles: [ ]

시계열 데이터(로그·메트릭)는 Hot → Warm → Cold → Frozen 순으로 값싼 하드웨어로 이동시키는 것이 표준 패턴입니다. 데이터가 오래될수록 검색 빈도가 급감하기 때문에, 비용/성능 곡선을 따라 내려보내는 것이죠. 이 이동은 ILM(Index Lifecycle Management)이 자동화합니다.

💡
voting_only는 왜 있을까

마스터 쿼럼은 홀수가 권장되지만 전용 마스터 3대는 비용이 듭니다. 전용 마스터 2대 + voting_only 1대(보통 데이터 노드 겸직)로 쿼럼 3을 유지하며 비용을 줄일 수 있습니다. 단, 공식 문서는 운영 환경에서는 진짜 전용 마스터 3대를 권장합니다.

2.2 Cluster State — 클러스터의 단일 진실

Cluster state는 클러스터의 모든 메타데이터를 담은 하나의 자료구조입니다. 인덱스 설정과 매핑, 샤드가 어느 노드에 있는지, 노드 목록과 역할, ILM 정책까지 전부 여기 들어 있습니다. 그리고 이 정보의 단일 진실 공급자(single source of truth)는 마스터 노드입니다.

👑 Master cluster state v41 ① 변경 요청 발생 PUT /new-index → state v42 생성 ✍️ data-1 data-2 data-3 state v41 state v41 state v41 ③ 모든 노드에 publish state v42 ✓ state v42 ✓ state v42 ✓ 각 노드는 새 state에서 자기 몫을 실행 (예: 할당된 샤드 시작)
⚠️
Cluster state는 모든 노드가 통째로 메모리에 든다

인덱스가 수천 개, 샤드가 수만 개가 되면 state가 수백 MB로 커지고, 변경 때마다 이 큰 덩어리의 publish가 일어나 마스터가 ack를 기다리며 클러스터가 멈칫거리게 됩니다. GET _cluster/state?filter_path=metadata 응답 크기가 100MB를 넘으면 oversharding을 의심하세요.

2.3 Discovery — 노드들이 서로를 찾는 법

노드는 마법처럼 서로를 찾지 않습니다. 각 노드는 마스터 후보 노드의 주소 목록을 알고 시작해야 합니다. 7.0부터 도입된 새 Discovery 체계의 핵심 설정은 두 가지입니다.

# elasticsearch.yml

# (1) 같은 cluster.name을 가진 노드만 합류할 수 있다
cluster.name: prod-logs

# (2) seed_hosts — 처음 접속해 볼 마스터 후보들의 주소 (상시 유지)
discovery.seed_hosts:
  - master-1.es.internal
  - master-2.es.internal
  - master-3.es.internal

# (3) initial_master_nodes — "최초 부트스트랩" 한 번만 사용!
# 클러스터가 형성된 후에는 모든 노드의 yaml에서 제거할 것
cluster.initial_master_nodes:
  - master-1
  - master-2
  - master-3
🚨
단골 사고: initial_master_nodes 복사-붙여넣기

cluster.initial_master_nodes빈 클러스터를 처음 띄울 때 한 번만 의미가 있습니다. 새 노드를 추가하며 기존 yaml을 그대로 복사하면, 새 노드가 기존 클러스터를 무시하고 별도 클러스터로 부트스트랩해버릴 수 있습니다 — split-brain의 지름길입니다. 클러스터 형성 직후 모든 노드의 yaml에서 이 설정을 제거하세요.

2.4 마스터 선출 — 왜 하필 3대인가

마스터 선출은 Raft에서 영감을 받은 합의 프로토콜로 동작합니다. 선출에 투표하는 마스터 후보들의 집합을 voting configuration이라 하고, 이 집합의 과반수(strict majority)가 동의해야 마스터가 정해집니다. 과반수 규칙이 있어야 네트워크가 반으로 갈라져도 두 쪽이 동시에 마스터를 뽑는 사태(split-brain)를 막을 수 있습니다.

👑 master-1 현재 마스터 master-2 후보 (대기) master-3 후보 (대기) voting configuration = {master-1, master-2, master-3} · quorum = 2 💥 master-1 다운! 🗳️ 투표: master-2 ✓ / master-3 ✓ 2표 / 3 = 과반수 확보 → 선출 성립 👑 master-2 새 마스터로 선출! ✅ 마스터 2대뿐이었다면? 1대 장애 시 quorum(2) 미달 → 클러스터 전체 마비
마스터 후보 수quorum견딜 수 있는 장애평가
110대SPOF — 단일 장애점
220대❌ 1대만 죽어도 쿼럼 미달
321대✅ 표준 권장
431대3보다 나을 게 없는데 비용만 증가
532대대규모 클러스터용

7.x 이후 voting configuration은 노드가 추가/제거될 때 자동으로 조정됩니다. 다만 장애 상황에서 stale하게 남으면 POST _cluster/voting_config_exclusions로 수동 개입이 필요할 수 있습니다.

2.5 요청 라우팅 — coordinating 노드에서 샤드로 fan-out

클라이언트 요청은 어느 노드로 보내도 됩니다. 요청을 받은 노드가 그 순간 coordinating node가 되어 교통정리를 맡습니다. 검색은 Query then Fetch라는 2단계로 처리됩니다.

🧑‍💻 Client GET /logs/_search Node-X = Coordinating 요청 받은 노드가 그 순간 조정자 ② cluster state에서 샤드 위치 룩업 primary/replica 중 부하 분산 선택 Shard 0 (Node-A) Shard 1 (Node-B) Shard 2 (Node-C) ③ Query Phase 전 샤드로 fan-out top-K id+점수 top-K id+점수 top-K id+점수 ④ 결과 머지 글로벌 top-K 결정 ⑤ Fetch Phase 선택된 문서의 _source만 해당 샤드에서 수집 ⑥ Client 응답 ✨

색인(쓰기) 요청은 경로가 다릅니다. coordinating 노드가 hash(_id) % 샤드 수단 하나의 primary 샤드를 찾아 전달하고, primary가 색인 후 모든 in-sync replica에 동기 복제합니다. 모든 사본의 ack를 받은 뒤에야 클라이언트에 응답하므로, 색인 응답 시점에 데이터는 모든 활성 사본에 도달해 있습니다 (4장에서 상세히).

2.6 운영 팁 — 클러스터 토폴로지 설계

# 클러스터 토폴로지 상시 확인 — 운영자의 3종 세트
GET /_cluster/health

# 노드별 역할/heap/디스크 (master 칼럼의 *가 현재 마스터)
GET /_cat/nodes?v=true&h=name,node.role,heap.percent,disk.used_percent,master

# 지금 마스터는 누구인가
GET /_cat/master?v=true

✍️ 이해도 체크

운영 클러스터에서 전용 마스터 노드를 2대로 구성하면 안 되는 이유는?
✅ 마스터 선출은 voting configuration의 과반수(strict majority)가 필요합니다. 후보 2대면 quorum=2인데 1대가 죽으면 남은 1표로는 선출이 성립하지 않아, 1대 구성보다 나을 게 없습니다. 그래서 3대(장애 1대 허용) 또는 5대(장애 2대 허용)가 표준입니다.
검색 요청의 Query Phase에서 각 샤드가 coordinating 노드로 반환하는 것은?
✅ Query Phase에서는 문서 ID + 점수 같은 가벼운 정보만 모아 글로벌 top-K를 정하고, 실제 문서 내용은 Fetch Phase에서 최종 선택된 문서만 가져옵니다. 이 2단계 구조 덕에 네트워크 비용이 최소화되지만, 반대로 deep pagination(from=10000)은 모든 샤드가 from+size개를 반환해야 해서 매우 비싸집니다.
📚
원문으로 더 깊이

이 장의 원문 문서: chapters/ch02_cluster_architecture.md — data tier별 샤드 한도, forced awareness, 클러스터 구성 예시 다이어그램 등이 담겨 있습니다.