Amazon Elasticsearch Service에서 회로 차단기 예외 문제를 해결하려면 어떻게 해야 합니까?

최종 업데이트 날짜: 2021년 4월 6일

Amazon Elasticsearch Service(Amazon ES) 클러스터로 데이터를 전송하려고 합니다. 하지만 데이터가 너무 크다는 회로 차단기 예외 오류가 나타납니다. 왜 이런 현상이 발생하며, 이 문제를 해결하려면 어떻게 해야 합니까?

간략한 설명

요청이 Amazon ES 노드에 도달하면 회로 차단기는 필요한 데이터를 로드하는 데 필요한 메모리 용량을 추정합니다. 그런 다음 Amazon ES는 예상 크기를 구성된 힙 크기 제한과 비교합니다. 데이터의 예상 크기가 사용 가능한 힙 크기보다 크면 쿼리가 종료됩니다. 그 결과, 노드 과부하를 방지하기 위해 CircuitBreakerException이 발생합니다.

Amazon ES는 다음 회로 차단기를 사용하여 JVM OutofMemoryError 예외를 방지합니다.

  • Request
  • Fielddata
  • In flight requests
  • Accounting
  • Parent

참고: 각 회로 차단기에는 고유한 튜닝 요구 사항이 있으므로 이러한 5개의 회로 차단기 중 어느 것으로 인해 예외가 발생하는지 아는 것이 중요합니다. 회로 차단기 유형에 대한 자세한 내용은 Elasticsearch 웹 사이트에서 회로 차단기 설정을 참조하세요.

노드 및 차단기당 현재 메모리 사용량을 확인하려면 다음 명령을 사용합니다.

GET _nodes/stats/breaker

또한 회로 차단기는 최선의 노력 메커니즘일 뿐입니다. 회로 차단기는 노드 과부하에 대한 복원력을 제공하지만 OutOfMemoryError가 계속 수신될 수 있습니다. 회로 차단기는 명시적으로 예약된 경우에만 메모리를 추적할 수 있으므로 정확한 메모리 사용량을 미리 예측하지 못할 수도 있습니다. 예를 들어 적은 양의 메모리 힙이 있는 경우 추적되지 않은 메모리의 상대적인 오버헤드가 더 커집니다. 회로 차단기 및 노드 복원력에 대한 자세한 내용은 Elasticsearch 웹 사이트의 실제 메모리 회로 차단기를 사용하여 노드 복원력 향상을 참조하세요.

데이터 노드에 과부하가 걸리지 않도록 하려면 [높은 JVM 메모리 압력 문제 해결(Troubleshooting high JVM memory pressure)] 섹션에서 제공되는 팁을 따르십시오.

해결 방법

회로 차단기 예외

16GB의 힙이 있는 Elasticsearch 버전 7.x 이상을 사용하는 경우 회로 차단기 제한에 도달하면 다음 오류가 나타납니다.

"error": {
        "root_cause": [
            {
                "type": "circuit_breaking_exception",
                "reason": "[parent] Data too large, data for [<HTTP_request>] would be [16355096754/15.2gb], which is larger than the limit of [16213167308/15gb], real usage: [15283269136/14.2gb], new bytes reserved: [1071827618/1022.1mb]",
               }
      ]
}

이 예제 출력은 처리할 데이터가 너무 커서 상위 회로 차단기가 처리할 수 없음을 나타냅니다. 상위 회로 차단기(회로 차단기 유형)는 Elasticsearch 클러스터의 전반적인 메모리 사용을 처리합니다. 상위 회로 차단기 예외가 발생하면 모든 회로 차단기에 사용되는 총 메모리 용량이 설정된 제한을 초과했습니다. 클러스터가 16GB 중 95%(15.2GB의 힙)를 초과하면 상위 차단기가 예외를 발생시킵니다.

메모리 사용량과 설정된 회로 차단기 한도 간의 차이를 계산하여 이 로직을 확인할 수 있습니다. 예제 출력의 값을 사용하고 “limit of [16213167308/15gb]”에서 “real usage: [15283269136/14.2gb]”를 뺍니다. 이 계산은 요청을 성공적으로 처리하기 위해 이 요청에 약 1.02GB의 새 바이트 예약 메모리가 필요하다는 것을 보여 줍니다. 하지만 이 예에서는 데이터 요청이 들어왔을 때 클러스터의 사용 가능한 메모리 힙이 0.8GB 미만이었습니다. 결과적으로 회로 차단기가 작동합니다.

회로 차단기 예외 메시지는 다음과 같이 해석할 수 있습니다.

  • data for [<HTTP_request>]: 클라이언트가 클러스터의 노드로 HTTP 요청을 보냅니다. Amazon ES는 요청을 로컬에서 처리하거나 추가 처리를 위해 다른 노드로 전달합니다.
  • would be [#]: 요청이 처리될 때 힙 크기를 나타냅니다.
  • limit of [#]: 현재 회로 차단기 한도입니다.
  • real usage: JVM 힙의 실제 사용량입니다.
  • new bytes reserved: 요청을 처리하는 데 필요한 실제 메모리 용량입니다.

JVM 메모리 압력

회로 차단 예외는 높은 JVM 메모리 압력에 의해 발생하는 경우가 많습니다. JVM 메모리 압력은 Elasticsearch 클러스터에서 모든 데이터 노드에 사용되는 Java 힙의 백분율을 말합니다. Amazon CloudWatch의 JVMMemoryPressure 지표를 통해 현재 사용량을 확인합니다.

참고: Amazon ES 데이터 노드의 JVM 힙 크기는 물리적 메모리(RAM) 크기의 절반인 최대 32GB로 설정됩니다. 예를 들어 실제 메모리(RAM)가 노드당 128GB이면 힙 크기는 32GB(최대 힙 크기)입니다. 그렇지 않으면 힙 크기가 실제 메모리 크기의 절반으로 계산됩니다.

높은 JVM 메모리 압력은 다음으로 인해 발생할 수 있습니다.

  • 클러스터에 대한 요청 수 증가. Amazon CloudWatch에서 IndexRateSearchRate 지표를 확인하여 현재 부하를 확인합니다.
  • 집계, 와일드카드 및 쿼리에서 넓은 시간 범위 사용.
  • 노드 간 불균형한 샤드 할당 또는 클러스터의 너무 많은 샤드.
  • 인덱스 매핑 폭발.
  • fielddata 데이터 구조를 사용하여 데이터 쿼리. Fielddata는 많은 양의 힙 공간을 사용할 수 있으며 세그먼트의 수명 동안 힙에 남아 있습니다. 따라서 fielddata가 사용될 때 JVM 메모리 압력은 클러스터에서 높게 유지됩니다. 자세한 내용은 Elasticsearch 웹 사이트에서 Fielddata을 참조하세요.

높은 JVM 메모리 압력 문제 해결

높은 JVM 메모리 압력을 해결하려면 다음 팁을 시도하세요.

  • 특히 워크로드가 많은 경우 클러스터로 들어오는 트래픽을 줄입니다.
  • 워크로드를 지원하기 위해 더 많은 JVM 메모리를 확보하려면 클러스터를 확장하는 것이 좋습니다.
  • 클러스터 확장이 불가능한 경우 이전 인덱스 또는 사용되지 않는 인덱스를 삭제하여 샤드 수를 줄입니다. 샤드 메타데이터는 메모리에 저장되므로 샤드 수를 줄이면 전체 메모리 사용량을 줄일 수 있습니다.
  • 느린 로그를 활성화하여 잘못된 요청을 식별합니다. 참고: 구성 변경을 활성화하기 전에 JVM 메모리 압력이 85% 미만인지 확인하세요. 이렇게 하면 기존 리소스에 대한 추가 오버헤드를 방지할 수 있습니다.
  • 검색 및 인덱싱 요청을 최적화하고 올바른 샤드 수를 선택합니다. 자세한 내용은 Amazon Elasticsearch Service 시작하기: 얼마나 많은 샤드가 필요합니까?를 참조하세요.
  • fielddata를 비활성화하고 사용하지 않습니다. 기본적으로 fielddata는 인덱스 매핑에 달리 명시적으로 정의되지 않은 경우 텍스트 필드에 “false”로 설정됩니다.
  • 인덱스 reindex API를 사용하거나 index template API를 생성하거나 업데이트하여 인덱스 매핑 유형을 키워드로 변경합니다. 키워드 유형을 텍스트 필드에 대해 집계 및 정렬을 수행하는 대안으로 사용할 수 있습니다.
  • 필드 데이터의 증가를 방지하려면 텍스트 필드를 집계하지 마세요. 필드 데이터를 많이 사용할수록 더 많은 힙 공간이 소비됩니다. cluster stats API 작업을 사용하여 필드 데이터를 확인합니다.
  • 다음 API 호출을 사용하여 fielddata 캐시를 지웁니다.
POST /index_name/_cache/clear?fielddata=true (index-level cache)
POST */_cache/clear?fielddata=true (cluster-level cache)

경고: fielddata 캐시를 지우면 진행 중인 쿼리가 중단될 수 있습니다.

자세한 내용은 내 Amazon Elasticsearch Service 클러스터의 높은 JVM 메모리 압력 문제를 해결하려면 어떻게 해야 합니까?를 참조하세요.