Amazon OpenSearch Service에서 검색 또는 쓰기 거부를 해결하려면 어떻게 해야 하나요?

8분 분량
0

Amazon OpenSearch Service 클러스터에 검색 또는 쓰기 요청을 제출하면 요청이 거부됩니다.

간략한 설명

OpenSearch Service 클러스터에서 데이터를 쓰거나 검색할 때 다음과 같은 HTTP 429 오류 또는 es_rejected_execution_exception이 발생할 수 있습니다.

error":"elastic: Error 429 (Too Many Requests): rejected execution of org.elasticsearch.transport.TransportService$7@b25fff4 on
EsThreadPoolExecutor[bulk, queue capacity = 200, org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor@768d4a66[Running,
pool size = 2, active threads = 2, queued tasks = 200, completed tasks = 820898]] [type=es_rejected_execution_exception]"

Reason={"type":"es_rejected_execution_exception","reason":"rejected execution of org.elasticsearch.transport.TcpTransport$RequestHandler@3ad6b683 on EsThreadPoolExecutor[search, queue capacity = 1000, org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor@bef81a5[Running, pool size = 25, active threads = 23, queued tasks = 1000, completed tasks = 440066695]]"

다음 변수는 HTTP 429 오류 또는 es_rejected_execution_exception의 원인이 될 수 있습니다.

  • 데이터 노드 인스턴스 유형 및 검색 또는 쓰기 제한
  • 인스턴스 지표의 높은 값
  • 활성 및 큐 스레드
  • 높은 CPU 사용률 및 JVM 메모리 압력

클러스터에 대한 검색쓰기 요청으로 인해 HTTP 429 오류가 발생할 수 있습니다. 클러스터의 단일 노드 또는 여러 노드에서 거부될 수도 있습니다.

참고: Elasticsearch의 버전에 따라 _index API에 대한 호출을 처리합니다. Elasticsearch 버전 1.5와 2.3은 인덱스 스레드 풀을 사용합니다. Elasticsearch 버전 5.x, 6.0 및 6.2는 대량 스레드 풀을 사용합니다. Elasticsearch 버전 6.3 이상은 쓰기 스레드 풀을 사용합니다. 자세한 내용은 Elasticsearch 웹사이트에서 Thread pool을 참조하세요.

해결 방법

데이터 노드 인스턴스 유형 및 검색 또는 쓰기 제한

데이터 노드 인스턴스 유형에는 고정된 가상 CPU(vCPU)가 있습니다. 노드가 큐에 들어가기 전에 노드가 수행할 수 있는 동시 검색 또는 쓰기 작업을 검색하려면 수식에 vCPU 수를 연결하세요. 활성 스레드가 가득 차면 스레드가 큐로 넘어가 결국 거부됩니다. vCPU와 노드 유형 간의 관계에 대한 자세한 내용은 OpenSearch Service 가격을 참조하세요.

또한 노드당 검색 또는 노드당 쓰기를 수행할 수 있는 횟수에는 제한이 있습니다. 이 제한은 스레드 풀 정의와 Elasticsearch 버전 번호를 기반으로 합니다. 자세한 내용은 Elasticsearch 웹사이트에서 Thread pool을 참조하세요.

예를 들어, Elasticsearch 클러스터(버전 7.4)의 5개 노드에 대해 R5.2xlarge 노드 유형을 선택하는 경우, 노드에는 8개의 vCPU가 있습니다.

다음 공식을 사용하여 검색 요청에 대한 최대 활성 스레드를 계산하세요.

int ((# of available_processors * 3) / 2) + 1

다음 공식을 사용하여 쓰기 요청에 대한 최대 활성 스레드를 계산합니다.

int (# of available_processors)

R5.2xlarge 노드의 경우 최대 13개의 검색 작업을 수행할 수 있습니다.

(8 VCPUs * 3) / 2 + 1 = 13 operations

R5.2xlarge 노드의 경우 최대 8개의 쓰기 작업을 수행할 수 있습니다.

8 VCPUs = 8 operations

노드가 5개인 OpenSearch Service 클러스터의 경우 최대 65개의 검색 작업을 수행할 수 있습니다.

5 nodes * 13 = 65 operations

노드가 5개인 OpenSearch Service 클러스터의 경우 최대 40개의 쓰기 작업을 수행할 수 있습니다.

5 nodes * 8 = 40 operations

인스턴스 지표의 높은 값

429 예외 문제를 해결하려면 클러스터에 대한 다음 Amazon CloudWatch 지표를 확인하세요.

  • IndexingRate: 분당 인덱싱 작업 수입니다. 두 개의 문서를 추가하고 업데이트하는 _bulk API를 한 번 호출하여 두 개의 문서를 추가하고 두 개를 업데이트하는 것은 노드에 분산될 수 있는 네 개의 작업으로 계산됩니다. 해당 인덱스에 하나 이상의 복제본이 있는 경우, 클러스터의 다른 노드도 총 4개의 인덱싱 작업을 기록합니다. 문서 삭제는 IndexingRate 지표에 포함되지 않습니다.
  • SearchRate: 데이터 노드에 있는 모든 샤드에 대한 분당 총 검색 요청 수입니다. \ _search API를 한 번 호출하면 여러 샤드의 결과가 반환될 수 있습니다. 하나의 노드에 서로 다른 샤드 5개가 있는 경우 클라이언트가 한 번만 요청했더라도 노드는 이 지표에 대해 "5"를 보고합니다.
  • **CoordinatingWriteRejected:**조정 노드에서 발생한 총 거부 수입니다. 이러한 거부는 OpenSearch Service 시작 이후 누적된 인덱싱 압력으로 인해 발생합니다.
  • PrimaryWriteRejected: 기본 샤드에서 발생한 총 거부 횟수입니다. 이러한 거부는 마지막 OpenSearch Service 시작 이후 누적된 인덱싱 압력으로 인해 발생합니다.
  • ReplicaWriteRejected: 인덱싱 압력으로 인해 복제본 샤드에서 발생한 총 거부 횟수입니다. 이러한 거부는 마지막 OpenSearch Service 시작 이후 누적된 인덱싱 압력으로 인해 발생합니다.
  • **ThreadpoolWriteQueue:**쓰기 스레드 풀의 대기 중인 작업 수입니다. 이 지표는 높은 CPU 사용량 또는 높은 인덱싱 동시성 때문에 요청이 거부되는지를 알려줍니다.
  • ThreadpoolWriteRejected: 쓰기 스레드 풀에 대기 중인 작업의 수입니다.
    참고: 기본 쓰기 큐 크기가 OpenSearch Service 버전 7.9에서 200에서 10,000으로 증가했습니다. 따라서 이 지표는 더 이상 OpenSearch Service의 거부를 나타내는 유일한 지표가 아닙니다. 버전 7.9 이상에서 거부를 모니터링하려면 CoordinatingWriteRejected, PrimaryWriteRejectedReplicaWriteRejected 메트릭을 사용하세요.
  • ThreadpoolSearchQueue: 검색 스레드 풀에 대기 중인 작업의 수입니다. 큐 크기가 지속적으로 높으면 클러스터를 확장하는 것이 좋습니다. 최대 검색 대기열 크기는 1,000개입니다.
  • ThreadpoolSearchRejected: 검색 스레드 풀에서 거부된 작업의 수입니다. 이 숫자가 계속 증가하면 클러스터 확장을 고려하세요.
  • JVMMemoryPressure: JVM 메모리 압력은 클러스터 노드에서 Java 힙의 비율을 지정합니다. JVM 메모리 압력이 75%에 도달하면 OpenSearch Service는 동시 마크 스윕(CMS) 가비지 수집기를 시작합니다. 가비지 수집은 CPU를 많이 사용하는 프로세스입니다. JVM 메모리 압력이 몇 분 동안 이 비율로 유지되면 클러스터 성능 문제가 발생할 수 있습니다. 자세한 내용은 Amazon OpenSearch Service 클러스터의 높은 JVM 메모리 사용량 문제를 해결하려면 어떻게 해야 하나요?를 참조하세요.

참고: 나열된 스레드 풀 메트릭은 IndexingRateSearchRate에 대한 정보를 제공하는 데 도움이 됩니다.

CloudWatch로 OpenSearch Service 클러스터를 모니터링하는 방법에 대한 자세한 내용은 인스턴스 지표를 참조하세요.

활성 및 큐 스레드

CPU가 부족하거나 요청 동시성이 높으면 큐가 빠르게 채워져 HTTP 429 오류가 발생할 수 있습니다. 대기열 스레드를 모니터링하려면 CloudWatch에서 ThreadpoolSearchQueueThreadpoolWriteQueue 지표를 확인하세요.

활성 및 대기열 스레드에서 검색 거부가 있는지 확인하려면 다음 명령을 사용하세요.

GET /_cat/thread_pool/search?v&h=id,name,active,queue,rejected,completed

활성 및 대기열 스레드에서 쓰기 거부를 확인하려면 "검색"을 "쓰기"로 바꾸세요. 출력의 거부완료 값은 누적 노드 카운터이며, 새 노드가 시작되면 재설정됩니다. 자세한 내용은 Elasticsearch 웹사이트에서 cat 스레드 풀 API의 ** 명시적 열을 사용한 예제** 섹션을 참조하세요.

참고: 각 노드의 대량 대기열은 사용 중인 Elasticsearch 버전에 따라 50개에서 200개의 요청을 수용할 수 있습니다. 대기열이 가득 차면 새 요청이 거부됩니다.

검색 및 쓰기 거부 오류

검색 거부

검색 거부 오류는 활성 스레드가 사용 중이고 대기열이 최대 작업 수까지 채워졌음을 나타냅니다. 따라서 검색 요청이 거부될 수 있습니다. 검색 속도 느림 로그에 이러한 오류 메시지가 표시되도록 OpenSearch Service 로그를 구성할 수 있습니다.

참고: 추가 오버헤드를 방지하려면 느린 로그 임계값을 넉넉한 양으로 설정하세요. 예를 들어, 대부분의 쿼리에 11초가 걸리고 임계값이 "10"인 경우 OpenSearch Service는 로그를 작성하는 데 더 많은 시간이 걸립니다. 느린 로그 임계값을 20초로 설정하면 이러한 오버헤드를 피할 수 있습니다. 그러면 느린 쿼리 중 일부(11초 이상 소요되는 쿼리)만 로그에 기록됩니다.

검색 속도 느림 로그를 CloudWatch로 푸시하도록 클러스터를 구성한 후 느린 로그 생성에 대한 특정 임계값을 설정하세요. 다음 HTTP POST 호출로 느린 로그 생성에 대한 특정 임계값을 설정할 수 있습니다.

curl -XPUT http://<your domain’s endpoint>/index/_settings -d '{"index.search.slowlog.threshold.query.<level>":"10s"}'

쓰기 거부

쓰기 거부로 429 오류 메시지가 표시되면 대량 큐 오류가 발생했음을 나타냅니다. **es_rejected_execution_exception[bulk]**는 큐가 가득 차서 모든 새 요청이 거부되었음을 나타냅니다. 이 대량 큐 오류는 클러스터에 대한 요청 수가 대량 큐 크기(**threadpool.bulk.queue_size)**를 초과할 때 발생합니다. 각 노드의 대량 큐는 사용 중인 Elasticsearch 버전에 따라 50개에서 200개 사이의 요청을 수용할 수 있습니다.

이러한 오류 메시지가 인덱스 속도 저하 로그에 표시되도록 OpenSearch Service 로그를 구성할 수 있습니다.

참고: 추가 오버헤드를 방지하려면 느린 로그 임계값을 넉넉한 양으로 설정하세요. 예를 들어, 대부분의 쿼리가 11초가 걸리고 임계값이 "10"인 경우 OpenSearch Service는 로그를 작성하는 데 추가 시간이 걸립니다. 느린 로그 임계값을 20초로 설정하면 이러한 오버헤드를 피할 수 있습니다. 그러면 느린 쿼리 중 일부(11초 이상 소요되는 쿼리)만 로그에 기록됩니다.

검색 속도 느림 로그를 CloudWatch로 푸시하도록 클러스터를 구성한 후 느린 로그 생성에 대한 특정 임계값을 설정하세요. 느린 로그 생성에 대한 특정 임계값을 설정하려면 다음 HTTP POST 호출을 사용하세요.

curl -XPUT http://<your domain’s endpoint>/index/_settings -d '{"index.indexing.slowlog.threshold.query.<level>":"10s"}'

쓰기 거부 모범 사례

다음은 쓰기 거부를 완화하는 몇 가지 모범 사례입니다.

  • 문서가 더 빨리 색인되면 쓰기 대기열이 용량에 도달할 가능성이 줄어듭니다.
  • 워크로드와 원하는 성능에 따라 대량 크기를 조정하세요. 자세한 내용은 Elasticsearch 웹사이트에서 색인 속도 조정을 참조하세요.
  • 애플리케이션 로직에 지수 재시도 로직을 추가하세요. 지수 재시도 로직은 실패한 요청이 자동으로 재시도되도록 합니다.
    참고: 클러스터에 지속적으로 높은 동시 요청이 발생하는 경우 지수 재시도 논리는 429 오류를 해결하는 데 도움이 되지 않습니다. 트래픽이 갑자기 또는 가끔 급증하는 경우 이 모범 사례를 사용하세요.
  • Logstash에서 데이터를 수집하는 경우, 작업자 수와 벌크 크기를 조정하세요. 벌크 크기를 3~5MB 사이로 설정하는 것이 가장 좋습니다.

인덱싱 성능 조정에 대한 자세한 내용은 OpenSearch Service 클러스터에서 인덱싱 성능을 개선하려면 어떻게 해야 하나요?을 참조하세요.

검색 거부 모범 사례

다음은 검색 거부를 완화하는 몇 가지 모범 사례입니다.

  • 더 큰 인스턴스 유형으로 전환합니다. OpenSearch Service는 더 빠른 검색 결과를 위해 파일 시스템 캐시에 크게 의존합니다. 검색 요청에 대한 각 노드의 스레드 풀에 있는 스레드 수는 int((# of available_processors * 3) / 2) + 1과 같습니다. 검색 요청을 처리할 스레드를 더 많이 확보하려면 더 많은 vCPU가 있는 인스턴스로 전환하세요.
  • 지정된 인덱스 또는 임계값이 적절한 모든 인덱스에 대해 검색 속도 느림 로그를 켭니다. 실행하는 데 시간이 오래 걸리는 쿼리를 확인하고 해당 쿼리에 대한 검색 성능 전략을 구현하세요. 자세한 내용은 초보자를 위한 Elasticsearch 검색 문제 해결 또는 고급 튜닝을 참조하세요. 느린 Elasticsearch 쿼리 찾기 및 수정하기를 참조하세요.
AWS 공식
AWS 공식업데이트됨 일 년 전