Elasticsearch 클러스터 성장을 위한 스케일링 전략 가이드
Elasticsearch는 실시간 검색, 로깅 및 분석 기능이 필요한 수많은 애플리케이션의 중추 역할을 해왔습니다. 데이터 볼륨이 증가하고 쿼리 부하가 높아짐에 따라 Elasticsearch 클러스터는 필연적으로 스케일링 문제에 직면합니다. 클러스터를 효과적으로 스케일링하는 것은 성능 유지, 고가용성 보장, 다운타임 없는 미래 성장을 처리하는 데 매우 중요합니다. 이 가이드는 하드웨어 및 지능적인 샤드 할당에 대한 중요 고려 사항과 함께 수평 스케일링과 수직 스케일링 모두에 대한 검증된 전략을 살펴봅니다.
성능이 저하되기 전에 적절하게 스케일링하는 방법을 이해하는 것이 성공적이고 성장하는 시스템과 응답하지 않는 병목 현상 사이의 차이를 만듭니다. 이 가이드에서는 용량을 확장하는 핵심 방법과 클러스터를 견고하게 유지하는 데 필요한 아키텍처 모범 사례를 다룰 것입니다.
Elasticsearch 스케일링 기본 사항 이해
Elasticsearch 클러스터를 스케일링하는 것은 주로 두 가지 전략을 포함합니다: 수직 스케일링 (확장)과 수평 스케일링 (분산). 최적의 전략은 종종 워크로드 특성에 따라 달라지며, 이 두 가지의 신중한 균형을 포함합니다.
수직 스케일링 (확장)
수직 스케일링은 기존 노드의 리소스를 늘리는 것을 포함합니다. 이는 가장 간단한 접근 방식이지만 물리적 한계에 빠르게 도달합니다.
수직 스케일링을 사용해야 하는 경우:
- 지연 시간(latency)이 주요 관심사이며 기존 데이터 세트에서 더 빠른 쿼리 응답이 필요할 때.
- 새 노드를 추가하면 불필요한 조정 오버헤드가 발생할 수 있는 단기적인 최고 부하를 처리할 때.
주요 리소스 업그레이드:
- RAM (메모리): 이는 종종 가장 중요한 업그레이드입니다. Elasticsearch는 JVM 힙 크기에 크게 의존합니다 (일반적으로 시스템 전체 RAM의 50%, 최대 30~32GB로 설정해야 함). 메모리가 많을수록 더 큰 캐시(필드 데이터, 요청 캐시)와 더 나은 가비지 컬렉션 성능을 얻을 수 있습니다.
- CPU: 복잡한 집계(aggregation), 과도한 인덱싱 및 높은 쿼리 동시성에 필수적입니다.
- 저장소 (디스크 I/O): 더 빠른 SSD 또는 NVMe 드라이브는 특히 I/O 부하가 높은 워크로드에서 인덱싱 처리량과 검색 속도를 크게 향상시킵니다.
⚠️ 수직 스케일링 경고: JVM 제한으로 인해, 최적의 압축된 일반 객체 포인터(oops)를 위해 힙에 약 32GB 이상을 할당할 수 없습니다. 과도한 수직 스케일링은 종종 임시방편에 불과합니다.
수평 스케일링 (분산)
수평 스케일링은 클러스터에 더 많은 노드를 추가하는 것을 포함합니다. 이를 통해 데이터와 쿼리 부하가 더 많은 시스템에 분산되어 거의 선형적인 확장성과 고가용성을 제공합니다.
수평 스케일링을 사용해야 하는 경우:
- 데이터 볼륨이 기존 노드의 용량을 초과할 때.
- 전반적인 인덱싱 처리량이나 쿼리 동시성을 개선해야 할 때.
- 장기적이고 지속 가능한 성장을 위한 주요 전략으로.
수평 스케일링은 새로운 데이터 노드를 추가함으로써 달성됩니다. 조정 노드(Coordinating nodes)도 추가할 수 있지만, 일반적으로 데이터 노드의 확장이 용량 증가를 이끌어냅니다.
확장성을 위한 아키텍처 모범 사례
스케일링은 단순히 하드웨어를 추가하는 것 이상입니다. 잘 구조화된 인덱스 및 노드 토폴로지가 필요합니다.
노드 역할 및 전문화
현대의 Elasticsearch 배포는 특히 대규모 클러스터에서 노드에 전용 역할을 할당함으로써 큰 이점을 얻습니다. 이는 무거운 작업(예: 인덱싱)과 중요한 작업(예: 검색 조정) 간의 리소스 경합을 방지합니다.
| 노드 역할 | 주요 책임 | 모범 사례 고려 사항 |
|---|---|---|
| 마스터 노드 | 클러스터 상태 관리, 안정성. | 전용 노드 3개 또는 5개 세트. 데이터 또는 수집 요청을 처리해서는 안 됩니다. |
| 데이터 노드 | 데이터 저장, 인덱싱, 검색. | 데이터 볼륨과 부하를 기준으로 적극적으로 스케일링합니다. |
| 수집 노드 | 인덱싱 전 문서 사전 처리 (수집 파이프라인 사용). | 데이터 노드에서 CPU 집약적인 사전 처리를 오프로드합니다. |
| 조정 노드 | 대규모 검색 요청 처리, 데이터 노드에서 결과 취합. | 검색 요청이 복잡해지거나 조정 오버헤드로 인해 데이터 노드에 과부하가 자주 발생할 때 추가합니다. |
샤드 할당 전략
샤드는 Elasticsearch에서 분산 및 병렬 처리의 기본 단위입니다. 샤드 할당이 제대로 이루어지지 않으면 스케일링 문제의 주요 원인이 됩니다.
1. 기본 샤드 수 최적화
기본 샤드의 올바른 개수(index.number_of_shards)를 선택하는 것은 매우 중요하며, 인덱스 생성 후 쉽게 변경할 수 없습니다 (인덱스 별칭(alias) 또는 리인덱싱을 사용하지 않는 한).
- 샤드가 너무 적을 경우: 검색 중 병렬 처리가 제한되고 효과적인 수평 스케일링을 방해합니다.
- 샤드가 너무 많을 경우: 마스터 노드에 오버헤드를 유발하고, 불필요하게 메모리 사용 공간을 늘리며, "작은 샤드 문제" 비효율성을 초래합니다.
모범 사례: 기본 샤드 크기는 10GB에서 50GB 사이를 목표로 합니다. 좋은 시작점은 일반적으로 데이터 노드당 CPU 코어당 기본 샤드 1개이지만, 이는 워크로드에 따라 크게 달라집니다.
2. 고가용성 및 읽기 처리량을 위한 복제본 샤드
복제본 샤드(index.number_of_replicas)는 중복성을 제공하고 읽기 용량을 증가시킵니다.
number_of_replicas: 1로 설정하면 모든 기본 샤드에 복사본이 하나씩 생겨 고가용성(HA)이 보장됩니다.- 복제본을 늘리면(예: 2개) 검색이 여러 샤드 복사본을 동시에 처리할 수 있게 되어 읽기 처리량이 크게 증가합니다.
HA 설정 예시:
기본 샤드가 10개이고 number_of_replicas: 1로 설정하면, 클러스터는 노드 전체에 분산된 총 20개의 샤드 복사본(기본 10개 + 복제본 10개)이 필요합니다.
PUT /my_growing_index
{
"settings": {
"index.number_of_shards": 20,
"index.number_of_replicas": 1
}
}
인식 기능(Awareness)을 사용한 핫스팟 방지
새 노드를 추가할 때 샤드가 클러스터 전체에 고르게 분산되도록 해야 합니다. Elasticsearch는 이를 자동으로 시도하지만, 특히 다중 영역 또는 다중 데이터센터 배포 환경에서는 노드 속성(예: 랙 인식)이 구성되었는지 확인해야 합니다.
샤드가 새 노드로 이동하지 않거나 노드에 과부하가 걸리는 이유를 진단하려면 클러스터 할당 설명자 API (Cluster Allocation Explainer API)를 사용하십시오.
실용적인 스케일링 단계: 성장에 대처하기
클러스터 성능이 저하되면 (높은 JVM 힙 압력, 느린 쿼리, 느린 인덱싱) 다음 단계를 순서대로 따르십시오.
1단계: 모니터링 및 진단
변경 사항을 적용하기 전에 병목 현상을 진단하십시오. 일반적인 지표:
- 높은 CPU/낮은 여유 메모리: 계산 또는 메모리 부족을 나타냄 (잠재적인 수직 스케일링 필요).
- 과도한 디스크 큐 길이: I/O 병목 현상을 나타냄 (더 빠른 디스크 또는 노드 추가 필요).
- 검색 지연 시간 급증: 종종 불충분한 캐싱 또는 너무 적은 샤드/복제본으로 인해 발생 (더 많은 메모리 또는 수평 스케일링 필요).
2단계: 즉각적인 리소스 요구 사항 해결 (수직 조정)
메모리 압력이 높으면 안전 한도(최대 32GB) 내에서 JVM 힙 크기를 늘리고 OS 파일 시스템 캐시에 사용할 수 있는 충분한 RAM이 확보되었는지 확인하십시오.
3단계: 분산 (수평 확장)
노드를 추가하는 경우 다음 절차를 따르십시오.
- 동일하거나 더 우수한 하드웨어로 새 데이터 노드를 프로비저닝합니다.
- 올바른 마스터 가능(master-eligible) 또는 데이터(data) 역할로 구성합니다.
discovery.seed_hosts를 사용하여 기존 클러스터를 가리키도록 설정합니다.- 새 노드가 조인되면 Elasticsearch는 새 용량을 활용하기 위해 기존 샤드의 리밸런싱을 자동으로 시작합니다.
4단계: 인덱스 미래 대비 (리인덱싱)
기존 인덱스의 샤드 수가 최적이 아닌 경우 새 노드를 완전히 활용할 수 없습니다. 이를 재구축해야 합니다.
- 새 인덱스 템플릿을 생성하거나 Create Index API를 사용하여 원하는 수의 샤드 및 복제본을 지정합니다.
- 리인덱스 API(Reindex API)를 사용하여 이전의 부적절한 크기의 인덱스에서 새 인덱스로 데이터를 마이그레이션합니다.
- 마이그레이션이 완료되면 별칭(alias)을 사용하여 트래픽을 전환합니다.
리인덱스 명령어 예시:
POST _reindex
{
"source": {
"index": "old_index_bad_shards"
},
"dest": {
"index": "new_index_optimized_shards"
}
}
요약 및 모범 사례 체크리스트
Elasticsearch를 효과적으로 스케일링하려면 분산 및 리소스 관리에 대한 이해를 바탕으로 한 사전 계획이 필요합니다. 수직 스케일링을 무기한으로 피하고, 부하를 수평적으로 분산시키는 데 집중하십시오.
핵심 요점:
- 수평 스케일링을 우선시하십시오: 지속적인 성장과 복원력을 위한 최상의 경로를 제공합니다.
- 전용 마스터 노드: 마스터 역할을 분리하여 클러스터 관리를 안정적으로 유지하십시오.
- 샤드 크기 조정은 영구적입니다: 인덱스 생성 시 10GB~50GB 기본 샤드 크기를 목표로 하십시오.
- JVM 힙 모니터링: 노드당 힙 크기가 30GB를 초과하지 않도록 하십시오.
- 리인덱싱 사용: 수평 확장에 따라 기본 샤드 수를 변경해야 할 때 중요한 인덱스를 재구축하십시오.