Elasticsearch 샤드 크기 조정 전략: 최적의 균형 찾기
샤드 크기, 노드 용량, 쿼리 패턴, 복구 시간 및 성장을 균형 있게 조정하여 Elasticsearch 샤드 크기를 계획합니다.
Elasticsearch 샤드 크기 조정 전략: 최적의 균형 찾기
Elasticsearch는 강력한 분산 검색 및 분석 엔진으로, 그 확장성과 성능의 많은 부분을 기본 아키텍처, 특히 샤드 개념에 의존합니다. 샤드는 기본적으로 데이터의 하위 집합을 보유하는 독립적인 Lucene 인덱스입니다. 샤드의 크기를 이해하고 최적화하는 것은 모범 사례일 뿐만 아니라 클러스터의 성능, 안정성 및 비용 효율성에 직접적인 영향을 미치는 중요한 요소입니다.
Elasticsearch 샤드 크기 조정 전략은 일회성 공식이 아닌 용량 계획 문제입니다. 메타데이터 오버헤드를 피할 수 있을 만큼 샤드가 충분히 크고, 빠르게 복구할 수 있을 만큼 충분히 작으며, 데이터 노드 전체에 인덱싱 및 검색 작업을 분산할 수 있을 만큼 충분히 많은 샤드를 원합니다.
Elasticsearch 샤드 이해하기
크기 조정에 들어가기 전에 샤드가 무엇이며 Elasticsearch 클러스터 내에서 어떻게 작동하는지 간략히 요약해 보겠습니다.
샤드란 무엇인가?
Elasticsearch에서 인덱스는 데이터의 논리적 그룹입니다. 이 데이터를 분산하고 병렬 처리를 가능하게 하기 위해 인덱스는 하나 이상의 _샤드_로 나뉩니다. 각 샤드는 자체 포함된 Lucene 인덱스입니다. 인덱스를 생성할 때 가질 기본 샤드의 수를 정의합니다.
고가용성 및 읽기 확장성을 위해 Elasticsearch는 복제본 샤드를 지정할 수도 있습니다. 복제본 샤드는 기본 샤드의 정확한 복사본입니다. 기본 샤드의 노드에 장애가 발생하면 복제본이 승격되어 그 자리를 대신하여 데이터 가용성을 보장하고 데이터 손실을 방지합니다. 복제본은 또한 검색 요청을 처리하여 읽기 부하를 분산합니다.
샤드 작동 방식
문서를 인덱싱할 때 Elasticsearch는 라우팅 알고리즘(기본적으로 문서 ID 기반)을 기반으로 문서가 속한 기본 샤드를 결정합니다. 그런 다음 이 문서는 해당 특정 기본 샤드와 해당 복제본 샤드에 저장됩니다. 검색할 때 요청은 모든 관련 샤드로 전송되며, 각 샤드는 데이터의 일부를 병렬로 처리합니다. 그런 다음 결과가 집계되어 클라이언트에 반환됩니다. 이 병렬 처리가 Elasticsearch에 엄청난 속도와 확장성을 제공하는 이유입니다.
샤드 크기가 중요한 이유
최적의 샤드 크기는 건강한 Elasticsearch 클러스터의 기본 요소입니다. 잘못된 크기 조정은 느린 쿼리 성능에서부터 비용이 많이 드는 리소스 낭비 및 불안정한 복구 시나리오에 이르기까지 다양한 문제를 초래할 수 있습니다.
성능
- 쿼리 속도: 적절한 크기의 샤드는 쿼리를 효율적으로 처리할 수 있습니다. 너무 작은 샤드는 더 많은 조정 오버헤드를 의미하고, 너무 큰 샤드는 개별 샤드 검색 시간이 길어짐을 의미합니다.
- 인덱싱 처리량: 마찬가지로 인덱싱 성능도 영향을 받을 수 있습니다. 샤드가 너무 작으면 많은 샤드를 관리하는 오버헤드가 쓰기 속도를 저하시킬 수 있습니다. 샤드가 너무 크면 개별 샤드 성능이 병목 현상을 일으킬 수 있습니다.
리소스 활용
각 샤드는 CPU, 메모리(JVM 힙) 및 디스크 I/O를 포함하여 상주하는 노드의 리소스를 소비합니다. 적절한 크기 조정은 노드가 과부하되거나 활용도가 낮아지지 않고 효율적으로 사용되도록 보장합니다.
확장성
샤드는 Elasticsearch에서 분산의 단위입니다. 수평 확장을 위해 노드를 추가하면 Elasticsearch가 노드 간에 샤드를 재조정합니다. 샤드가 너무 크면 재조정 시간이 더 오래 걸리고 더 많은 네트워크 대역폭이 필요합니다. 샤드가 너무 적으면 기본 샤드 수 이상으로 워크로드를 분산할 수 없기 때문에 확장 한계에 일찍 도달할 수 있습니다.
복구 및 안정성
- 노드 장애: 노드에 장애가 발생하면 Elasticsearch는 기본 샤드를 재할당(복제본 승격)하고 손실된 복제본을 다시 생성해야 합니다. 이 소요 시간은 관련된 샤드의 크기와 수에 직접적으로 비례합니다.
- 클러스터 복구: 큰 샤드는 복구 및 복제에 더 오래 걸리므로 노드 장애 또는 클러스터 재시작 중 취약성 기간이 늘어납니다.
샤드 크기에 영향을 미치는 요소
올바른 샤드 크기를 결정하는 것은 모든 상황에 적용되는 단일 솔루션이 아닙니다. 사용 사례와 인프라에 특정한 여러 상호 의존적인 요소에 따라 달라집니다.
- 데이터 볼륨 및 성장: 현재 데이터 크기와 예상 성장률은 기본입니다. 정적 100GB 인덱스는 매일 1TB씩 증가하는 롤링 인덱스와 요구 사항이 다릅니다.
- 문서 크기 및 스키마 복잡성: 필드가 많거나 문서가 매우 큰 인덱스는 각 문서 처리에 더 많은 리소스가 필요하므로 더 작은 샤드가 유리할 수 있습니다.
- 쿼리 패턴:
- 검색 중심: 클러스터가 주로 검색에 사용되는 경우 병렬 처리를 최대화하고 개별 샤드 검색 시간을 최소화하기 위해 더 많고 작은 샤드를 우선시할 수 있습니다.
- 분석 중심(집계): 많은 수의 매우 작은 샤드에서 결과를 결합하는 오버헤드가 커질 수 있으므로 대규모 집계는 더 큰 샤드에서 더 잘 수행될 수 있습니다.
- 인덱싱 속도: 높은 인덱싱 속도는 쓰기 부하를 분산하기 위해 더 많은 샤드의 이점을 얻을 수 있지만, 너무 많으면 오버헤드가 발생할 수 있습니다.
- 노드 사양: 데이터 노드의 CPU, RAM(JVM 힙 크기) 및 디스크 유형(SSD 대 HDD)이 중요합니다. 더 강력한 노드는 더 많은 샤드 또는 더 큰 샤드를 처리할 수 있습니다.
- 클러스터 토폴로지: 샤드를 분산하는 데 사용할 수 있는 총 데이터 노드 수는 가능한 샤드 수에 직접적인 영향을 미칩니다.
트레이드오프: 너무 많은 샤드 vs. 너무 적은 샤드
최적의 균형을 찾으려면 양극단의 결과를 이해해야 합니다.
너무 많은 샤드의 결과
더 많은 샤드가 더 많은 병렬 처리를 제공하는 것처럼 보일 수 있지만, 수확 체감의 지점이 있습니다:
- 더 높은 오버헤드: 각 샤드는 메타데이터, 열린 파일, 세그먼트 병합 등을 위해 CPU와 메모리(JVM 힙)를 소비합니다. 노드에 샤드가 너무 많으면 샤드 자체를 관리하기 위한 전체 리소스 소비가 증가하여 실제 데이터 처리를 위한 리소스가 줄어듭니다.
- 팁: 오래된 힙당 샤드 규칙은 대략적인 경고로 유용했지만 최신 Elasticsearch 버전은 샤드당 힙 오버헤드를 줄였습니다. 그럼에도 불구하고 수천 개의 작은 샤드가 있는 클러스터는 메모리를 낭비하고 클러스터 상태를 더 어렵게 만듭니다.
- 느린 복구: 노드 장애 또는 재조정 중에 많은 수의 작은 샤드를 관리하고 이동하는 것은 더 적은 수의 큰 샤드보다 더 많은 시간과 네트워크 I/O가 필요합니다.
- 리소스 경합 증가: 동일한 노드에서 많은 샤드가 활발하게 작업(예: 세그먼트 병합, 쿼리 응답)을 수행하면 CPU, 메모리 및 디스크 I/O를 놓고 경합하여 전반적인 성능이 저하됩니다.
- "샤드 블로트": 많고 대부분 비어 있는 작은 샤드가 있는 클러스터는 비효율적입니다. 비례하는 데이터 이점 없이 관리를 위해 리소스를 소비합니다.
너무 적은 샤드의 결과
반대로 샤드가 너무 적어도 심각한 문제가 발생합니다:
- 제한된 병렬 처리: 인덱스에 몇 개의 큰 샤드만 있는 경우 검색 쿼리는 클러스터의 전체 처리 능력을 활용할 수 없습니다. 워크로드를 여러 노드/코어에 분산할 수 없기 때문입니다.
- 핫스팟: 단일 노드의 큰 샤드는 읽기 또는 쓰기 요청을 불균형적으로 많이 받는 경우 "핫스팟"이 되어 해당 특정 노드의 리소스가 포화 상태가 될 수 있습니다.
- 확장의 어려움: 예를 들어 인덱스에 기본 샤드가 5개만 있는 경우 해당 인덱스를 최대 5개의 데이터 노드에만 효과적으로 분산할 수 있습니다. 모든 샤드가 이미 다른 노드에 있는 경우 노드를 더 추가해도 특정 인덱스의 성능에 도움이 되지 않습니다.
- 느린 재조정: 재조정 중에 단일 매우 큰 샤드를 네트워크를 통해 이동하는 것은 시간이 많이 걸리고 I/O 집약적인 작업으로, 클러스터 안정성에 영향을 줄 수 있습니다.
- 더 긴 복구 시간: 복구 또는 복사해야 하는 단일 큰 샤드는 장애 후 클러스터 복구 시간을 크게 연장할 수 있습니다.
일반적인 권장 사항 및 모범 사례
모든 상황에 맞는 단일 규칙은 없지만, 널리 인정받는 몇 가지 지침이 좋은 출발점을 제공합니다.
목표 샤드 크기
개별 샤드 크기(인덱싱 및 잠재적 병합 후)에 대해 가장 일반적으로 인용되는 권장 사항은 10GB에서 50GB 사이입니다. 일부 소스는 특정 시나리오(예: 대부분 추가 전용 쓰기와 복잡한 쿼리가 적은 시계열 데이터)의 경우 최대 100GB까지 확장합니다. 이 범위는 일반적으로 관리 용이성, 복구 속도 및 효율적인 리소스 사용 간의 좋은 균형을 제공합니다.
- 이 범위가 중요한 이유?:
- 복구: 이 범위의 샤드는 노드 장애 후 비교적 빠르게 복구할 수 있습니다.
- 성능: 오버헤드를 최소화할 만큼 충분히 크지만 효율적인 처리와 빠른 병합을 허용할 만큼 충분히 작습니다.
- 확장성: 노드 간 유연한 분산이 가능합니다.
노드당 샤드 수
단일 노드에 과도한 수의 샤드가 있는 것을 피하십시오. Elasticsearch는 최신 버전에서 클러스터 샤드 제한을 적용하며, 실제 제한은 힙, 매핑, 쿼리 볼륨 및 디스크 속도에 따라 다릅니다. 샤드 수를 경고 지표로 사용한 다음 JVM 압력, 클러스터 상태 업데이트 대기 시간 및 검색/인덱싱 대기 시간으로 확인하십시오.
핫-웜-콜드 아키텍처 및 샤드 크기 조정
핫-웜-콜드(HWC) 아키텍처에서 샤드 크기는 다양할 수 있습니다:
- 핫 티어: 활성 쓰기를 수신하고 자주 쿼리되는 데이터 노드. 여기서는 인덱싱 처리량과 쿼리 병렬 처리를 최대화하기 위해 약간 더 많은 샤드 또는 더 작은 샤드를 선택할 수 있습니다.
- 웜/콜드 티어: 덜 자주 액세스하는 오래된 데이터를 보유하는 노드. 이러한 샤드는 일반적으로 인덱싱이 중지되고 병합이 완료되었으므로 더 큽니다. 비용 최적화된 스토리지에서 특히 총 샤드 수와 관련 오버헤드를 줄이기 위해 더 큰 샤드(최대 100GB+)가 허용될 수 있습니다.
복제본
항상 복제본을 사용하십시오! 기본 샤드당 최소 하나의 복제본(데이터의 총 2개 복사본)은 고가용성에 중요합니다. 복제본은 또한 검색 요청을 분산하여 읽기 용량을 증가시킵니다. 최적의 복제본 수는 가용성 요구 사항과 쿼리 부하에 따라 다릅니다.
샤드 크기 결정을 위한 실용적인 전략
초기 샤드 크기 조정 전략을 도출하기 위한 단계별 접근 방식과 반복적인 개선 프로세스는 다음과 같습니다.
1단계: 총 데이터 볼륨 및 성장 추정
인덱스(또는 롤링 일별/월별 인덱스)가 수명 주기 동안 보유할 데이터 양을 예측합니다. 평균 문서 크기를 고려하십시오.
- 예시: 하루에 100GB의 데이터를 수집하고 30일 동안 보관할 것으로 예상합니다. 총 활성 데이터는 약 3TB(
100GB/일 * 30일)입니다.
2단계: 목표 샤드 크기 결정
기본 샤드당 30GB-50GB의 일반적인 권장 사항부터 시작하십시오. 사용 사례에 따라 조정하십시오:
더 작은 샤드(예: 10-20GB): 쿼리 처리량이 매우 높거나, 대규모 문서에 대한 복잡한 집계가 있거나, 데이터가 매우 자주 변경되는 경우.
더 큰 샤드(예: 50-100GB): 대부분 시계열 데이터, 추가 전용 인덱스 또는 덜 빈번하고 단순한 쿼리가 있는 경우.
예시(1단계에서 계속): 평균 기본 샤드 크기를 50GB로 목표로 합시다.
3단계: 초기 기본 샤드 수 계산
총 예상 데이터 볼륨을 목표 샤드 크기로 나눕니다.
기본 샤드 수 = (총 데이터 볼륨) / (목표 샤드 크기)
- 예시:
3000GB / 50GB = 60개의 기본 샤드.
4단계: 노드 리소스 및 힙 크기 고려
클러스터가 샤드당 GB 힙 규칙을 준수하면서 편안하게 호스팅할 수 있는 기본 및 복제본 샤드 수를 결정합니다.
- 노드당 힙: 각각 30GB의 JVM 힙을 가진 데이터 노드가 있다고 가정합니다.
- 노드당 최대 샤드 수(대략):
10-20 샤드/GB 힙규칙을 사용하면 30GB 힙 노드는30 * 10 = 300에서30 * 20 = 600개의 샤드를 호스팅할 수 있습니다. - 총 복제본: 1개의 복제본(강력 권장)을 사용하는 경우
60개의 기본 샤드 + 60개의 복제본 샤드 = 총 120개의 샤드가 있습니다. - 데이터 노드 수: 복제본이 해당 기본 샤드와 동일한 노드에 배치되지 않고 샤드를 분산할 수 있는지 확인하십시오. 프로덕션 복원력을 위해 노드 또는 영역 장애 시 할당되지 않은 복제본이 남지 않도록 충분한 데이터 노드와 영역을 사용하십시오.
예시 시나리오
각각 30GB 힙을 가진 3노드 데이터 클러스터를 가정합니다:
- 현재 계산된 총 샤드:
120개의 샤드(60 기본 + 60 복제본) - 노드당 평균 샤드:
120 총 샤드 / 3 노드 = 노드당 40개의 샤드. - 이 수는 부하 상태에서 힙 압력, 디스크 I/O, 인덱싱 대기 시간 및 검색 대기 시간이 정상으로 유지되는 경우에만 합리적입니다.
5단계: 테스트 및 모니터링
이것이 가장 중요한 단계입니다. 이론적 계산은 단지 출발점일 뿐입니다.
부하 테스트: 예상되는 인덱싱 및 쿼리 패턴을 시뮬레이션합니다. 성능 메트릭을 관찰합니다.
모니터링 도구: Kibana의 내장 모니터링, Elasticsearch의
_catAPI 또는 외부 모니터링 도구(예: Prometheus, Grafana)를 사용하여 다음을 주시하십시오:_cat/shards: 샤드 크기 및 분포를 확인합니다._cluster/stats: 특히 JVM 힙 사용량에 대한 클러스터 수준 통계.- 개별 노드의 CPU, 메모리 및 디스크 I/O.
- 인덱싱 및 검색 대기 시간.
- 세그먼트 병합 활동.
# 샤드 할당 및 크기 정보 가져오기 GET _cat/shards?v=true&h=index,shard,prirep,state,docs,store,node # 힙 사용량 및 샤드 수에 대한 클러스터 통계 가져오기 GET _cluster/stats
6단계: 반복 조정
모니터링을 기반으로 샤드 수를 조정할 준비를 하십시오. 여기에는 다음이 포함될 수 있습니다:
- 축소 API: 더 이상 쓰기가 수행되지 않는 인덱스에 대해 기본 샤드가 너무 많은 경우
_shrinkAPI를 사용하여 기본 샤드 수를 줄일 수 있습니다. 인덱스는 읽기 전용이어야 하며 샤드 배치는 축소 요구 사항을 충족해야 합니다. - 분할 API: 인덱스의 샤드가 너무 커져 성능이 저하되는 경우
_splitAPI는 기본 샤드 수를 늘릴 수 있습니다. 인덱스는 읽기 전용이어야 하며 호환 가능한 라우팅 샤드 수로 생성되어야 합니다. - 재인덱싱 API: 매핑 수정 또는 라이브 활성 쓰기 인덱스의 샤드 수 변경과 같은 더 복잡한 변경의 경우 데이터를 다른 샤드 구성을 가진 새 인덱스로 재인덱싱해야 할 수 있습니다.
일반적인 함정과 이를 피하는 방법
- 맹목적인 과도한 샤딩: 소규모 클러스터에서 데이터 1GB당 1개의 샤드를 생성하여 과도한 오버헤드를 초래합니다. 피하는 방법: 합리적인 목표부터 시작하고 데이터가 성장함에 따라 샤드를 확장하십시오.
- 인덱스의 과소 샤딩: 매우 큰 인덱스에 대해 1-3개의 샤드만 있어 병렬 처리 및 확장성이 제한됩니다. 피하는 방법: 데이터 볼륨과 노드 용량을 기준으로 계산하십시오.
- 성장 예측 무시: 미래 수집을 고려하지 않고 현재 데이터에 맞게 크기를 조정합니다. 피하는 방법: 항상 데이터 수명 기간 동안 예상되는 데이터 성장을 고려하십시오.
- 모니터링하지 않음: 설정하고 잊어버립니다. 샤드 크기, 노드 리소스 및 쿼리 성능은 시간이 지남에 따라 변경됩니다. 피하는 방법: 주요 메트릭에 대한 강력한 모니터링 및 알림을 구현하십시오.
- 경험 법칙 맹목적 따르기: 10GB-50GB 규칙은 지침이지 엄격한 법칙이 아닙니다. 특정 워크로드에 따라 변형이 필요할 수 있습니다. 피하는 방법: 항상 일반적인 권장 사항을 실제 데이터 및 사용 패턴으로 검증하십시오.
실용적인 핵심 내용
예상 데이터 볼륨과 목표 샤드 크기에서 초기 샤드 수를 선택한 다음 부하 테스트로 증명하십시오. 롤오버 또는 성장 후 복구 시간, 힙 압력, 디스크 I/O 및 대기 시간을 주시하십시오. 수치가 벗어나면 샤드 레이아웃이 문제가 되기 전에 롤오버, 축소, 분할 또는 재인덱싱을 사용하십시오.