본문 바로가기
서버구축 (WEB,DB)

Elasticsearch 버킷 제한 too_many_buckets_exception 문제 해결

by 날으는물고기 2024. 7. 7.

Elasticsearch 버킷 제한 too_many_buckets_exception 문제 해결

Elasticsearch 검색 쿼리가 실행될 때 너무 많은 버킷을 생성하려고 시도하면 제한을 초과했다는 오류 메세지가 발생합니다. 여기서 "버킷"은 특정 필드의 값이나 범위에 따라 문서를 그룹화하는 데 사용되는 데이터 구조를 말합니다.

 

이 문제를 해결하는 방법은 몇 가지가 있습니다.

  1. 쿼리 최적화: 너무 많은 버킷을 생성하지 않도록 쿼리를 조정합니다. 예를 들어, 집계(aggregations)의 범위를 줄이거나, 필요하지 않은 집계를 제거합니다.
  2. search.max_buckets 설정 변경: Elasticsearch 클러스터 설정에서 search.max_buckets 값을 늘려서 허용되는 최대 버킷 수를 증가시킬 수 있습니다. 하지만 이 방법은 메모리 사용량이 증가할 수 있으므로 주의해서 사용해야 합니다.
    PUT /_cluster/settings
    {
      "persistent": {
        "search.max_buckets": 20000
      }
    }
  3. 하드웨어 리소스 검토: 서버의 리소스(메모리, CPU 등)가 충분한지 확인하고, 필요하다면 리소스를 확장하는 것을 고려해볼 수 있습니다.

적절한 방법을 선택할 때는 현재 Elasticsearch 환경과 사용자의 요구 사항을 고려해야 합니다. 또한, 설정 변경이나 쿼리 조정은 다른 부분에 영향을 줄 수 있으므로 주의 깊게 실행해야 합니다.

버킷이란?

Elasticsearch에서 "버킷"은 데이터를 분류하고 집계(aggregation)하는 데 사용되는 데이터 구조입니다. 예를 들어, 특정 필드에 대한 통계를 계산하거나, 데이터를 특정 기준에 따라 그룹화할 때 버킷을 사용합니다. 버킷은 주로 히스토그램, 범위, 날짜 범위 등의 집계 작업에서 볼 수 있습니다. 각 버킷은 특정 기준(예: 특정 날짜 범위, 특정 값의 범위 등)을 만족하는 문서들로 구성됩니다.

왜 버킷 제한이 있는가?

Elasticsearch는 버킷 제한을 두어 시스템 리소스를 보호합니다. 버킷 수가 많아질수록 처리해야 할 데이터 양이 증가하고, 이는 메모리 사용량과 CPU 사용량을 높이며, 결과적으로 시스템의 성능 저하나 안정성 문제를 일으킬 수 있습니다. 따라서 Elasticsearch는 search.max_buckets 설정을 통해 사용자가 한 번에 요청할 수 있는 최대 버킷 수를 제한하고 있습니다.

현재 설정된 버킷 수 확인 및 변경 방법

  1. 현재 설정된 search.max_buckets 값 확인
    Elasticsearch의 클러스터 설정에서 현재 설정된 search.max_buckets 값을 확인할 수 있습니다. 이를 위해 다음과 같은 API 요청을 사용할 수 있습니다.
    GET /_cluster/settings?include_defaults=true
    이 요청은 현재 클러스터의 모든 설정과 기본 설정을 반환합니다. 여기서 search.max_buckets 값을 찾아 현재 설정된 버킷 수의 제한을 확인할 수 있습니다.
  2. search.max_buckets 설정 변경
    Elasticsearch에서는 클러스터 설정을 통해 search.max_buckets의 값을 변경할 수 있습니다. 이는 임시적(비영구적) 또는 영구적으로 설정할 수 있습니다. 다음은 search.max_buckets 값을 변경하는 예시입니다.
    PUT /_cluster/settings
    {
      "persistent": {
        "search.max_buckets": 20000
      }
    }
    위 예시에서 persistent 설정은 Elasticsearch 클러스터가 재시작된 후에도 유지되는 설정입니다. 대신 transient를 사용하면 설정이 클러스터의 다음 재시작 때까지만 유지됩니다.

이와 같이 설정을 조정함으로써, Elasticsearch에서 데이터를 더 효율적으로 관리하고 시스템의 안정성을 유지할 수 있습니다. 설정을 변경하기 전에는 항상 변경의 영향을 이해하는 것이 좋습니다. 현재 사용되고 있는 버킷 수를 확인하는 직접적인 방법은 Elasticsearch의 표준 API로 제공되지 않습니다. 그러나 집계(aggregation) 쿼리를 실행할 때 발생하는 버킷 수를 간접적으로 파악할 수 있는 몇 가지 방법이 있습니다.

  1. 집계 쿼리 실행 및 분석
    집계 쿼리를 실행하고 그 결과를 분석하여 얼마나 많은 버킷이 생성되었는지 확인할 수 있습니다. 이 방법은 특정 쿼리에 대해 어느 정도의 리소스가 소모되는지 예측하는 데 유용합니다. 예를 들어, 다음과 같은 간단한 집계 쿼리를 실행하여 특정 필드에 대한 버킷 수를 확인할 수 있습니다.
    POST /your_index/_search
    {
      "size": 0,
      "aggs": {
        "my_buckets": {
          "terms": {
            "field": "your_field"
          }
        }
      }
    }
    이 쿼리는 your_field 필드에 대해 고유 값들을 버킷으로 분류하고, 생성된 각 버킷의 문서 수를 반환합니다. 반환된 결과에서 buckets 배열의 길이를 통해 생성된 버킷 수를 알 수 있습니다.
  2. 로그 및 모니터링 도구 사용
    Elasticsearch의 로그 또는 클러스터 모니터링 도구를 사용하여 각 쿼리의 실행과 관련된 메트릭스를 확인할 수 있습니다. 예를 들어, Kibana의 모니터링 기능을 사용하면 쿼리 실행 시 발생하는 버킷 수와 같은 세부 정보를 볼 수 있습니다.
  3. 집계 메트릭스 추적
    Elasticsearch의 X-Pack 모니터링(또는 유사한 도구)을 사용하면 집계 쿼리의 실행에 대한 다양한 메트릭스를 추적할 수 있습니다. 이러한 메트릭스는 클러스터의 성능 분석 및 집계 쿼리의 효율성 평가에 도움을 줄 수 있습니다.

이러한 방법들은 모두 간접적이거나 특정 쿼리에 한정된 정보를 제공합니다. Elasticsearch 설정이나 특정 집계 쿼리가 리소스에 미치는 영향을 보다 정확히 이해하고 싶다면, 쿼리의 설계를 세심하게 검토하고 필요에 따라 전문가의 조언을 구하는 것이 좋습니다.

 

하루에 한 번씩 사용 중인 버킷 수를 집계하여 Slack으로 알림을 보내는 자동화 스크립트를 작성하기 위해 Python을 사용할 수 있습니다. 이 프로세스는 크게 세 단계로 구성됩니다.

  1. Elasticsearch에서 집계 쿼리 실행
  2. 결과 해석 및 버킷 수 계산
  3. Slack으로 알림 보내기

필요한 라이브러리

  • elasticsearch: Elasticsearch 서버와의 통신을 위한 라이브러리입니다.
  • requests: Slack 웹훅을 통해 메시지를 보내는 데 사용됩니다.
  • schedule: 작업을 매일 특정 시간에 실행하는 데 사용됩니다.
pip install elasticsearch requests schedule

예제 코드

from elasticsearch import Elasticsearch
import requests
import schedule
import time

# Elasticsearch 설정
es = Elasticsearch("http://localhost:9200")

# Slack 웹훅 URL
slack_webhook_url = 'https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX'

def fetch_bucket_count():
    # Elasticsearch에서 집계 쿼리 실행
    response = es.search(index="your_index", body={
        "size": 0,
        "aggs": {
            "my_buckets": {
                "terms": {
                    "field": "your_field"
                }
            }
        }
    })

    # 버킷 수 계산
    bucket_count = len(response['aggregations']['my_buckets']['buckets'])

    # Slack으로 결과 전송
    message = f"Current bucket count: {bucket_count}"
    requests.post(slack_webhook_url, json={"text": message})

# 매일 정해진 시간에 실행
schedule.every().day.at("10:00").do(fetch_bucket_count)

# 스케줄러 루프
while True:
    schedule.run_pending()
    time.sleep(1)

코드 설명

  • 이 스크립트는 Elasticsearch에서 주어진 인덱스와 필드를 기준으로 버킷 수를 계산합니다.
  • fetch_bucket_count 함수는 Elasticsearch에서 버킷 수를 가져와 Slack으로 알림을 보냅니다.
  • schedule 라이브러리를 사용하여 이 작업을 매일 정해진 시간(예: 오전 10시)에 실행하도록 설정합니다.

주의사항

  • 실제 서버 주소, 인덱스 이름, 필드 이름, 그리고 Slack의 웹훅 URL을 적절히 설정해야 합니다.
  • 이 스크립트는 백그라운드에서 지속적으로 실행되어야 합니다. 서버 또는 주기적 작업을 관리할 수 있는 다른 환경에서 이 스크립트를 실행하시길 권장합니다.
728x90

댓글