최적의 샤드 크기 조정: 클러스터 성능과 관리의 균형
Elasticsearch 샤드 크기 조정을 마스터하여 클러스터 성능을 최적화하세요. 이 가이드는 샤드 수와 크기 간의 트레이드오프를 탐구하며, 데이터 볼륨, 인덱싱 부하, 쿼리 패턴과 같은 주요 고려 사항을 다룹니다. 최적의 샤드 할당 계산, 시간 기반 인덱스 활용, ILM(Index Lifecycle Management) 구현을 위한 모범 사례를 배워 확장 가능하고 효율적인 Elasticsearch 클러스터를 구축하세요.
최적의 샤드 크기 조정: 클러스터 성능과 관리의 균형
샤드 크기 조정은 클러스터가 몇 달 동안 운영되기 전까지는 간단해 보이는 Elasticsearch 결정 중 하나입니다. 샤드는 내부적으로 Lucene 인덱스이지만, 모든 샤드에는 오버헤드가 있습니다. 너무 많은 작은 샤드는 클러스터가 메타데이터와 작은 검색 대상을 관리하느라 바쁘게 만듭니다. 너무 적은 큰 샤드는 재배치, 복구 및 일부 검색을 느리게 만듭니다.
모든 클러스터에 적용되는 보편적인 샤드 크기는 없습니다. 일일 롤오버가 있는 로깅 클러스터, 제품 검색 인덱스, 보안 분석 클러스터는 모두 다르게 동작합니다. 유용한 접근 방식은 목표 샤드 크기를 선택하고, 그에 맞춰 롤오버 또는 인덱스 생성을 설계한 다음, 실제 인덱싱 및 쿼리 동작을 기반으로 조정하는 것입니다.
Elasticsearch 샤드의 기본 개념
크기 조정 전략을 살펴보기 전에 기본 개념을 이해하는 것이 중요합니다.
- 인덱스: 문서의 모음입니다. Elasticsearch에서 인덱스는 여러 샤드로 나뉩니다.
- 샤드: 분산의 단위입니다. 각 샤드는 독립적인 Lucene 인덱스입니다. 인덱스는 여러 샤드를 포함할 수 있으며, 클러스터의 여러 노드에 분산됩니다.
- 기본 샤드: 인덱스가 생성될 때 할당되는 기본 샤드의 수입니다. 이 샤드에 데이터가 인덱싱됩니다. 기존 인덱스의
number_of_shards를 단순히 편집할 수는 없지만, Elasticsearch는 특정 조건에서 분할 및 축소 작업을 제공합니다. 많은 팀에서 기본 샤드 수를 설계 시점의 결정 사항으로 간주하는 이유는 나중에 변경하려면 계획이 필요하기 때문입니다. - 복제본 샤드: 기본 샤드의 복사본입니다. 중복성을 제공하고 읽기 처리량을 증가시킵니다. 기본 샤드에 장애가 발생하면 복제본이 기본 샤드로 승격될 수 있습니다. 복제본 샤드의 수는 언제든지 변경할 수 있습니다.
샤드가 성능에 미치는 영향
- 인덱싱 성능: 각 샤드는 인덱싱을 위해 리소스가 필요합니다. 샤드가 많을수록 요청을 관리하는 조정 노드의 오버헤드가 커집니다. 그러나 샤드가 너무 커지면 단일 샤드에 대한 인덱싱이 병목 현상이 될 수 있습니다.
- 쿼리 성능: 검색 요청은 모든 관련 기본 샤드에 분산됩니다. 샤드 수가 많으면 처리해야 하는 요청 수가 증가하여 잠재적으로 지연 시간이 증가할 수 있습니다. 반대로, 매우 큰 샤드는 Lucene이 해당 샤드 내에서 더 많은 데이터를 처리해야 하므로 검색 시간이 길어질 수 있습니다.
- 클러스터 관리: 많은 수의 샤드는 클러스터 상태 관리를 담당하는 마스터 노드의 부하를 증가시킵니다. 또한 샤드 재배치, 스냅샷 생성 및 복구와 같은 작업의 오버헤드에도 영향을 미칩니다.
- 리소스 사용률: 각 샤드는 메모리와 디스크 I/O를 소비합니다. 너무 많은 샤드는 노드 리소스를 고갈시켜 성능 저하 또는 노드 불안정을 초래할 수 있습니다.
샤드 크기 조정을 위한 주요 고려 사항
"이상적인" 샤드 크기는 고정된 숫자가 아닙니다. 특정 워크로드, 데이터 특성 및 하드웨어에 따라 달라집니다. 그러나 몇 가지 요소가 결정을 안내해야 합니다.
1. 데이터 볼륨 및 증가율
- 현재 데이터 크기: 현재 인덱스에 얼마나 많은 데이터가 있습니까?
- 증가율: 데이터가 얼마나 빨리 증가하고 있습니까? 이는 미래의 샤드 크기를 예측하는 데 도움이 됩니다.
- 데이터 보존 정책: 오래된 데이터를 삭제할 예정입니까? 이는 활성 데이터의 유효 크기에 영향을 미칩니다.
2. 인덱싱 부하
- 인덱싱 속도: 초당 몇 개의 문서를 인덱싱하고 있습니까?
- 문서 크기: 개별 문서의 평균 크기는 얼마입니까?
- 인덱싱 처리량: 현재 샤드 구성으로 노드가 인덱싱 부하를 처리할 수 있습니까?
3. 쿼리 패턴
- 쿼리 복잡성: 쿼리가 단순한 키워드 검색입니까, 아니면 복잡한 집계입니까?
- 쿼리 빈도: 데이터에 대해 얼마나 자주 쿼리가 실행됩니까?
- 쿼리 지연 시간 요구 사항: 허용 가능한 응답 시간은 얼마입니까?
4. 클러스터 토폴로지 및 리소스
- 노드 수: 클러스터에 몇 개의 노드가 있습니까?
- 노드 하드웨어: CPU, RAM 및 디스크(Elasticsearch에는 SSD를 적극 권장합니다).
- 샤드 제한: Elasticsearch에는 노드가 과도한 수의 열린 샤드를 보유하지 못하도록 하는 안전 제한이 포함되어 있습니다. 최신 버전에서는 일반적으로
cluster.max_shards_per_node를 일반 열린 인덱스에 대한 클러스터 전체의 가드레일로 사용합니다.cluster.routing.allocation.total_shards_per_node는 다릅니다. 단일 인덱스 또는 일치하는 할당 범위의 샤드가 하나의 노드에 할당될 수 있는 수를 제한합니다. 설정을 변경하기 전에 Elasticsearch 버전을 확인하세요.
샤드 할당을 위한 모범 사례
1. 목표 샤드 크기 설정
마법의 숫자는 없지만, 많은 프로덕션 클러스터는 일반적인 로그 및 검색 워크로드에 대해 약 10GB ~ 50GB 크기의 샤드를 목표로 합니다. 이 범위는 규칙이 아닌 시작점입니다. 처리량이 매우 높거나 장기 보존 시스템은 테스트 후 더 큰 샤드를 선택할 수 있습니다. 소규모 비즈니스 검색 인덱스는 단일 소형 샤드로 가장 잘 작동할 수 있습니다.
- 너무 작음(< 10GB): 과도한 오버헤드로 이어질 수 있습니다. 각 샤드는 메모리 공간을 차지하고 마스터 노드의 부하에 기여합니다. 수천 개의 작은 샤드를 관리하는 것은 상당한 운영 부담이 됩니다.
- 너무 큼(> 50GB): 성능 문제를 일으킬 수 있습니다. 세그먼트 병합, 복구 및 리밸런싱 작업이 더 오래 걸립니다. 큰 샤드에 장애가 발생하면 복구하는 데 상당한 시간이 소요될 수 있습니다.
2. 시간 기반 인덱스 고려
시계열 데이터(로그, 메트릭, 이벤트)의 경우 시간 기반 인덱스를 사용하는 것이 표준적이고 매우 효과적인 방법입니다. 여기에는 특정 기간(예: 일별, 주별, 월별)에 대한 새 인덱스를 생성하는 것이 포함됩니다.
- 예시: 하나의 거대한 인덱스 대신
logs-2023.10.26,logs-2023.10.27등을 가질 수 있습니다. - 이점: 더 쉬운 데이터 관리(ILM - Index Lifecycle Management를 통한 오래된 인덱스 삭제), 쿼리가 종종 최근 데이터를 대상으로 하므로 더 나은 성능, 제어된 샤드 크기.
3. ILM(Index Lifecycle Management) 구현
ILM 정책을 사용하면 기간, 크기 또는 문서 수에 따라 인덱스 관리를 자동화할 수 있습니다. 인덱스에 대한 단계(hot, warm, cold, delete)를 정의하고 각 단계에 대한 작업(복제본 수 변경, 인덱스 축소 또는 삭제 포함)을 지정할 수 있습니다.
- Hot 단계: 인덱스가 활발하게 쓰기 및 쿼리되고 있습니다. 성능을 최대화합니다.
- Warm 단계: 인덱스에 더 이상 쓰지 않지만 여전히 쿼리됩니다. 성능이 낮은 하드웨어로 이동하거나 잠재적으로 복제본을 줄이거나 축소할 수 있습니다.
- Cold 단계: 드물게 쿼리됩니다. Elasticsearch 라이선스, 버전 및 아키텍처에 따라 데이터를 더 저렴한 스토리지 또는 저성능 노드로 이동할 수 있습니다.
- Delete 단계: 데이터가 더 이상 필요하지 않으며 삭제됩니다.
4. 과도한 샤딩 방지
과도한 샤딩은 클러스터 크기와 데이터 볼륨에 비해 샤드가 너무 많을 때 발생합니다. 이는 성능 저하 및 관리 문제로 이어지는 일반적인 함정입니다.
- 증상: 마스터 노드의 높은 CPU 사용률, 느린 클러스터 상태 업데이트, 긴 복구 시간 및 전반적인 느린 반응.
- 완화: 처음부터 기본 샤드 수를 계획하십시오. 시간 기반 인덱스의 경우 인덱스당 합리적인 수의 기본 샤드(예: 1 또는 3)로 시작하십시오. 나중에 복제본을 추가할 수 있습니다.
5. 과도한 인덱싱 방지
마찬가지로 필요하지 않을 때 과도한 수의 인덱스를 생성하지 마십시오. 각 인덱스는 오버헤드를 추가합니다. 자연스러운 파티셔닝 메커니즘이 없는 비시계열 데이터의 경우 적절한 샤드 수를 가진 단일 인덱스로 충분한지 고려하십시오.
6. number_of_shards 설정 고려
인덱스를 생성할 때 number_of_shards 매개변수는 기본 샤드의 수를 정의합니다. 이 설정은 인덱스 생성 후 변경할 수 없습니다.
PUT my-index
{
"settings": {
"index": {
"number_of_shards": 3, // 예: 3개의 기본 샤드
"number_of_replicas": 1 // 예: 1개의 복제본 샤드
}
}
}
- 팁: 작은 인덱스나 인덱싱/쿼리 부하가 매우 낮은 인덱스의 경우 단일 기본 샤드로 충분할 수 있습니다. 더 크고 활동적인 인덱스의 경우 3개 또는 5개의 기본 샤드가 더 나은 분산과 복원력을 제공할 수 있습니다. 특히 나중에 인덱스를 분할할 계획이 있는 경우(분할은 복잡하지만) 유용합니다.
7. 리밸런싱 및 재배치
Elasticsearch는 노드 간에 균일한 분산을 보장하기 위해 샤드를 자동으로 리밸런싱합니다. 그러나 샤드가 너무 크면 이러한 작업이 리소스를 많이 사용하고 느려질 수 있습니다. 더 작고 많은 수의 샤드는 때때로 더 빠르게 리밸런싱될 수 있지만, 이는 더 많은 샤드를 관리하는 오버헤드로 인해 상쇄됩니다.
8. 쿼리 성능 튜닝
쿼리 성능이 저하되는 경우 샤드 전략을 평가하십시오. 다음을 고려하십시오.
- 샤드 수: 너무 많은 샤드는 조정 오버헤드를 증가시킬 수 있습니다.
- 샤드 크기: 매우 큰 샤드는 샤드 내 세그먼트 병합 및 검색 속도를 저하시킬 수 있습니다.
- 인덱스 설계: 적절한 매핑과 분석기를 사용하고 있습니까?
최적의 샤드 수 계산
단일 공식은 없지만, 일반적인 접근 방식은 다음과 같습니다.
- 수명 주기 동안 인덱스당 총 데이터 볼륨을 추정합니다.
- 목표 샤드 크기를 결정합니다(예: 30GB).
- 필요한 기본 샤드 수를 계산합니다:
총 데이터 볼륨 / 목표 샤드 크기. - 가장 가까운 정수로 올림합니다. 이것이 인덱스의
number_of_shards가 됩니다.- 예시: 90GB의 데이터가 예상되고 30GB 샤드를 목표로 하는 경우
90GB / 30GB = 3개의 기본 샤드가 필요합니다.
- 예시: 90GB의 데이터가 예상되고 30GB 샤드를 목표로 하는 경우
- 복원력 및 분산 고려: 중요한 인덱스의 경우 초기 데이터 볼륨이 엄격하게 요구하지 않더라도 더 나은 분산 및 복구 옵션을 위해 3개 또는 5개의 기본 샤드를 사용하는 것을 고려하십시오. 단점은 오버헤드가 증가한다는 것입니다.
- 보수적으로 시작하십시오: 일반적으로 기본 샤드 수를 변경하는 것(일반적으로 재인덱싱 또는 복잡한 해결 방법이 필요함)보다 복제본을 추가하는 것이 더 쉽습니다. 확실하지 않은 경우 더 적은 수의 기본 샤드로 시작하고 성능을 모니터링하십시오.
예시 시나리오: 로그 분석
애플리케이션 로그를 인덱싱한다고 가정해 보겠습니다.
데이터 볼륨: 월간 1TB의 로그가 예상됩니다.
데이터 보존: 로그를 30일 동안 보관합니다.
목표 샤드 크기: 20GB를 목표로 합니다.
일일 인덱스: 일일 인덱스(
logstash-YYYY.MM.DD)를 생성합니다. 각 일일 인덱스는 약1TB / 30일 ≈ 33GB의 데이터를 보유합니다.인덱스당 기본 샤드: 20GB 목표와 33GB 일일 볼륨을 고려하여 인덱스당 2개의 기본 샤드를 선택할 수 있습니다(
33GB / 20GB ≈ 1.65, 올림하여 2). 이렇게 하면 개별 샤드가 목표 크기 내에 유지됩니다.복제본: 고가용성을 위해 복제본 1개를 결정합니다.
총 샤드: 30일 보존 기간 동안 30개의 인덱스가 있으며, 각각 2개의 기본 샤드와 2개의 복제본 샤드가 있어 언제든지 총 60개의 기본 샤드와 60개의 복제본 샤드가 활성화됩니다.
이 접근 방식은 개별 샤드를 관리 가능하게 유지하고 오래된 인덱스를 간단히 삭제하여 효율적인 데이터 삭제를 허용합니다.
일반적으로 발생하는 문제
가장 일반적인 문제는 습관적으로 과도한 샤딩을 하는 것입니다. 누군가가 오래된 튜토리얼에서 해당 설정을 사용했기 때문에 5개의 기본 샤드와 1개의 복제본으로 일일 인덱스를 생성합니다. 처음에는 무해해 보입니다. 그러면 클러스터에 수백 개의 작은 인덱스, 수천 개의 작은 샤드가 생기고 마스터 노드는 클러스터 상태 업데이트에 너무 많은 시간을 소비합니다. 또한 검색이 많은 샤드에 분산되어 실제 쿼리 작업이 시작되기 전에 조정 오버헤드가 추가됩니다.
반대 문제는 복구 중에 나타납니다. 몇 개의 거대한 샤드는 평상시에는 쿼리 성능이 허용될 수 있지만, 노드에 장애가 발생하거나 롤링 재시작이 시작되면 재배치에 오랜 시간이 걸립니다. 스냅샷 및 복원도 각 샤드가 큰 작업 단위이기 때문에 느려질 수 있습니다. 복구 목표가 빡빡한 경우 쿼리 지연 시간이 괜찮아 보여도 샤드 크기가 중요합니다.
핫 샤드는 또 다른 실질적인 문제입니다. 모든 새 쓰기가 하나의 기본 샤드로 이동하면 노드를 추가해도 해당 쓰기 부하가 자동으로 분산되지 않습니다. 시간 기반 롤오버는 새 인덱스가 현재 트래픽 패턴에 맞게 크기가 조정될 수 있기 때문에 도움이 됩니다. 라우팅 선택도 중요합니다. 사용자 지정 라우팅은 강력할 수 있지만, 잘못된 라우팅 키는 너무 많은 데이터를 하나의 샤드로 보낼 수 있습니다.
더 나은 롤오버 패턴
시계열 데이터의 경우 고정된 일일 인덱스보다 크기 기반 롤오버가 관리하기 더 쉬운 경우가 많습니다. 상황에 관계없이 하루에 하나의 인덱스를 생성하는 대신 쓰기 별칭을 생성하고 ILM이 인덱스가 목표 크기, 기간 또는 문서 수에 도달하면 롤오버하도록 합니다.
PUT _ilm/policy/logs-policy
{
"policy": {
"phases": {
"hot": {
"actions": {
"rollover": {
"max_primary_shard_size": "30gb",
"max_age": "1d"
}
}
},
"delete": {
"min_age": "30d",
"actions": {
"delete": {}
}
}
}
}
}
이 패턴을 사용하면 조용한 주말에는 더 적은 인덱스가 생성되고, 바쁜 장애 발생일에는 더 일찍 롤오버될 수 있습니다. 여전히 초기 기본 샤드 수를 선택해야 하지만 롤오버는 샤드 증가가 목표에서 너무 멀어지는 것을 방지합니다.
현재 샤드 검사 방법
무엇이든 변경하기 전에 현재 클러스터를 살펴보십시오.
GET _cat/shards?v&h=index,shard,prirep,state,docs,store,node&s=store:desc
GET _cat/indices?v&h=index,pri,rep,docs.count,store.size,pri.store.size&s=pri.store.size:desc
GET _cluster/health
다음과 같은 패턴을 찾고 있습니다: 많은 작은 샤드, 몇 개의 거대한 샤드, 할당되지 않은 샤드, 고르지 않은 노드 배치, 또는 기본 저장소 크기가 의도한 목표에서 너무 멀리 떨어진 인덱스. 하나의 인덱스에 100GB의 기본 데이터와 5개의 기본 샤드가 있는 경우 각 기본 샤드는 복제본 전에 약 20GB입니다. 동일한 인덱스에 100GB와 50개의 기본 샤드가 있는 경우 불필요한 오버헤드를 생성했을 가능성이 높습니다.
마지막 참고 사항
적절한 샤드 크기 조정은 완벽한 숫자를 쫓는 것보다 클러스터를 쉽게 운영할 수 있도록 유지하는 데 더 가깝습니다. 합리적인 목표부터 시작하고, 데이터 패턴에 맞는 경우 ILM 또는 롤오버를 사용하고, 실제로 샤드 크기, 쿼리 팬아웃, 복구 시간 및 노드 압력에 어떤 일이 발생하는지 관찰하십시오. 클러스터가 이미 과도하게 샤딩된 경우 모든 오래된 인덱스를 한 번에 새 형태로 강제로 변경하려고 시도하기보다는 새 인덱스 템플릿, 롤오버, 축소 또는 재인덱싱을 통해 점진적으로 수정하십시오.