Concurrent segment search

Cloud_ Ghost·2025년 8월 11일

opensearch

목록 보기
3/23

동시 세그먼트 검색

https://docs.opensearch.org/latest/search-plugins/concurrent-segment-search/

쿼리 단계 중에 세그먼트를 병렬로 검색하려면 동시 세그먼트 검색을 사용하세요. 동시 세그먼트 검색이 검색 지연 시간을 개선하는 경우는 다음과 같습니다:

  • 집계나 큰 범위가 포함된 요청과 같은 장시간 실행되는 요청을 보낼 때
  • 성능 향상을 위해 세그먼트를 단일 세그먼트로 강제 병합하는 대안으로

배경

OpenSearch에서 각 검색 요청은 scatter-gather 프로토콜을 따릅니다. 조정 노드가 검색 요청을 받고, 이 요청을 처리하는 데 필요한 샤드를 평가한 다음, 각 샤드에 샤드 수준 검색 요청을 보냅니다. 요청을 받은 각 샤드는 Lucene을 사용하여 로컬에서 요청을 실행하고 결과를 반환합니다. 조정 노드는 모든 샤드에서 받은 응답을 병합하고 검색 응답을 클라이언트에 다시 보냅니다. 선택적으로, 클라이언트가 응답의 일부로 문서 필드나 전체 문서를 요청한 경우 조정 노드는 최종 결과를 클라이언트에 반환하기 전에 fetch 단계를 수행할 수 있습니다.

세그먼트 동시 검색

동시 세그먼트 검색이 없으면 Lucene은 쿼리 단계 동안 각 샤드의 모든 세그먼트에서 요청을 순차적으로 실행합니다. 그런 다음 쿼리 단계는 검색 요청에 대한 최상위 히트를 수집합니다. 동시 세그먼트 검색을 사용하면 각 샤드 수준 요청이 쿼리 단계 동안 세그먼트를 병렬로 검색합니다. 각 샤드에 대해 세그먼트는 여러 슬라이스로 나뉩니다. 각 슬라이스는 별도의 스레드에서 병렬로 실행할 수 있는 작업 단위이므로 슬라이스 수가 샤드 수준 요청의 최대 병렬 처리 정도를 결정합니다. 모든 슬라이스가 작업을 완료하면 Lucene은 슬라이스에서 reduce 작업을 수행하여 병합하고 이 샤드 수준 요청에 대한 최종 결과를 생성합니다. 슬라이스는 샤드 수준 요청을 처리하는 search 스레드 풀과 다른 새로운 index_searcher 스레드 풀을 사용하여 실행됩니다.

인덱스 또는 클러스터 수준에서 동시 세그먼트 검색 활성화

OpenSearch 버전 3.0부터 동시 세그먼트 검색이 클러스터 수준에서 기본적으로 활성화됩니다. 기본 동시 세그먼트 검색 모드는 auto입니다. 업그레이드 후 집계 워크로드에서 CPU 사용률이 증가할 수 있습니다. 클러스터의 리소스 사용량을 모니터링하고 최적의 성능을 유지하기 위해 필요에 따라 인프라 용량을 조정하는 것을 권장합니다.

클러스터에서 동시 세그먼트 검색을 구성하려면 search.concurrent_segment_search.mode 설정을 사용하세요. 기존의 search.concurrent_segment_search.enabled 설정은 새로운 설정을 위해 향후 버전 릴리스에서 더 이상 사용되지 않을 예정입니다.

동시 세그먼트 검색을 두 가지 수준에서 활성화할 수 있습니다:

  • 클러스터 수준
  • 인덱스 수준

인덱스 수준 설정이 클러스터 수준 설정보다 우선순위가 높습니다. 따라서 클러스터 설정이 활성화되어 있지만 인덱스 설정이 비활성화되어 있으면 해당 인덱스에 대해 동시 세그먼트 검색이 비활성화됩니다. 이 때문에 인덱스 수준 설정은 설정에 구성된 기본값에 관계없이 명시적으로 설정되지 않는 한 평가되지 않습니다. Index Settings API를 호출하고 ?include_defaults 쿼리 매개변수를 생략하여 인덱스 수준 설정의 현재 값을 검색할 수 있습니다.

클러스터 및 인덱스 수준 search.concurrent_segment_search.mode 설정 모두 다음 값을 허용합니다:

  • auto (기본값): 이 모드에서 OpenSearch는 플러그 가능한 동시 검색 결정자를 사용하여 쿼리 평가와 요청의 집계 존재를 기반으로 검색 요청에 대해 동시 또는 순차 경로를 사용할지 결정합니다. 기본적으로 플러그인에서 구성된 결정자가 없으면 요청의 집계 존재를 기반으로 동시 검색 사용 여부가 결정됩니다. 플러그 가능한 결정자 의미론에 대한 자세한 정보는 "플러그 가능한 동시 검색 결정자"를 참조하세요.

  • all: 모든 검색 요청에서 동시 세그먼트 검색을 활성화합니다. 이는 search.concurrent_segment_search.enabledtrue로 설정하는 것과 동일합니다.

  • none: 모든 검색 요청에 대해 동시 세그먼트 검색을 비활성화하여 기능을 효과적으로 끕니다. 이는 search.concurrent_segment_search.enabledfalse로 설정하는 것과 동일합니다.

클러스터의 모든 인덱스에서 모든 검색 요청에 대해 동시 세그먼트 검색을 활성화하려면 다음 요청을 보내세요:

PUT _cluster/settings
{
   "persistent":{
      "search.concurrent_segment_search.mode": "all"
   }
}

특정 인덱스의 모든 검색 요청에 대해 동시 세그먼트 검색을 활성화하려면 엔드포인트에 인덱스 이름을 지정하세요:

PUT <index-name>/_settings
{
    "index.search.concurrent_segment_search.mode": "all"
}

기존의 search.concurrent_segment_search.enabled 설정을 계속 사용하여 클러스터의 모든 인덱스에 대해 동시 세그먼트 검색을 활성화할 수 있습니다:

PUT _cluster/settings
{
   "persistent":{
      "search.concurrent_segment_search.enabled": true
   }
}

특정 인덱스에 대해 동시 세그먼트 검색을 활성화하려면 엔드포인트에 인덱스 이름을 지정하세요:

PUT <index-name>/_settings
{
    "index.search.concurrent_segment_search.enabled": true
}

클러스터에서 동시 세그먼트 검색이 활성화되어 있는지 평가할 때 search.concurrent_segment_search.mode 설정이 search.concurrent_segment_search.enabled 설정보다 우선합니다. search.concurrent_segment_search.mode 설정이 명시적으로 설정되지 않으면 search.concurrent_segment_search.enabled 설정이 평가되어 동시 세그먼트 검색 활성화 여부를 결정합니다.

기존의 search.concurrent_segment_search.enabled 설정을 지정하는 이전 버전에서 클러스터를 업그레이드할 때 이 설정은 계속 적용됩니다. 그러나 search.concurrent_segment_search.mode가 설정되면 이전 설정을 무시하고 지정된 모드에 따라 동시 검색을 활성화하거나 비활성화합니다. search.concurrent_segment_search.mode를 구성한 후에는 클러스터에서 search.concurrent_segment_search.enabled를 null로 설정하는 것을 권장합니다:

PUT _cluster/settings
{
   "persistent":{
      "search.concurrent_segment_search.enabled": null
   }
}

특정 인덱스에 대해 이전 설정을 비활성화하려면 엔드포인트에 인덱스 이름을 지정하세요:

PUT <index-name>/_settings
{
    "index.search.concurrent_segment_search.enabled": null
}

슬라이싱 메커니즘

세그먼트를 슬라이스에 할당하기 위해 사용할 수 있는 두 가지 메커니즘 중 하나를 선택할 수 있습니다: 기본 최대 슬라이스 수 메커니즘 또는 Lucene 메커니즘.

최대 슬라이스 수 메커니즘

최대 슬라이스 수 메커니즘은 동적으로 구성 가능한 최대 슬라이스 수를 사용하고 라운드 로빈 방식으로 슬라이스 간에 세그먼트를 나누는 슬라이싱 메커니즘입니다. 이는 이미 너무 많은 최상위 샤드 요청이 있고 슬라이스 간의 경쟁을 줄이기 위해 요청당 슬라이스 수를 제한하려는 경우에 유용합니다.

OpenSearch 버전 3.0부터 동시 세그먼트 검색은 기본적으로 최대 슬라이스 수 메커니즘을 사용합니다. 최대 슬라이스 수는 Math.max(1, Math.min(Runtime.getRuntime().availableProcessors() / 2, 4)) 공식을 사용하여 클러스터 시작 시간에 계산됩니다. 클러스터 수준 또는 인덱스 수준에서 max_slice_count 매개변수를 명시적으로 설정하여 이 값을 재정의할 수 있습니다. max_slice_count 업데이트에 대한 자세한 정보는 "슬라이싱 메커니즘 설정"을 참조하세요. 기본 계산된 값으로 되돌리려면 max_slice_count를 null로 설정하세요.

Lucene 메커니즘

Lucene 메커니즘은 최대 슬라이스 수 메커니즘의 대안입니다. 기본적으로 Lucene은 샤드의 각 슬라이스에 최대 250K 문서 또는 5개 세그먼트(먼저 충족되는 조건)를 할당합니다. 예를 들어, 11개의 세그먼트가 있는 샤드를 고려해보세요. 처음 5개 세그먼트는 각각 250K 문서를 가지고 있고, 다음 6개 세그먼트는 각각 20K 문서를 가지고 있습니다. 처음 5개 세그먼트는 각각 슬라이스에 허용된 최대 문서 수를 포함하므로 각각 1개의 슬라이스에 할당됩니다. 그런 다음 다음 5개 세그먼트는 슬라이스에 허용된 최대 세그먼트 수 때문에 모두 다른 단일 슬라이스에 할당됩니다. 11번째 슬라이스는 별도의 슬라이스에 할당됩니다.

슬라이싱 메커니즘 설정

search.concurrent.max_slice_count 설정을 업데이트하여 클러스터 수준 또는 인덱스 수준에서 슬라이싱 메커니즘을 설정할 수 있습니다.

클러스터 및 인덱스 수준 search.concurrent.max_slice_count 설정 모두 다음 유효한 값을 가질 수 있습니다:

  • 양의 정수: 최대 목표 슬라이스 수 메커니즘을 사용합니다. 일반적으로 2와 8 사이의 값이면 충분합니다.
  • 0: Lucene 메커니즘을 사용합니다.

클러스터의 모든 인덱스에 대해 슬라이스 수를 구성하려면 다음 동적 클러스터 설정을 사용하세요:

PUT _cluster/settings
{
   "persistent":{
      "search.concurrent.max_slice_count": 2
   }
}

특정 인덱스에 대해 슬라이스 수를 구성하려면 엔드포인트에 인덱스 이름을 지정하세요:

PUT <index-name>/_settings
{
    "index.search.concurrent.max_slice_count": 2
}

일반 지침

동시 세그먼트 검색은 CPU 또는 JVM 힙과 같은 더 많은 리소스를 소비하는 대신 검색 요청의 성능을 향상시키는 데 도움이 됩니다. 클러스터가 동시 세그먼트 검색에 적합하게 크기가 조정되었는지 이해하기 위해 워크로드를 테스트하는 것이 중요합니다. 다음 동시 세그먼트 검색 지침을 준수하는 것을 권장합니다:

  • 슬라이스 수 2부터 시작하여 워크로드의 성능을 측정하세요. 리소스 사용률이 권장 값을 초과하면 클러스터 확장을 고려하세요. 테스트에 따르면 워크로드가 이미 CPU 리소스의 50% 이상을 소비하고 있다면 동시 세그먼트 검색을 위해 클러스터를 확장해야 합니다.
  • 슬라이스 수가 2이고 클러스터에 여전히 사용 가능한 리소스가 있다면 클러스터의 검색 지연 시간과 리소스 사용률을 모니터링하면서 슬라이스 수를 4 또는 6과 같은 더 높은 수로 늘릴 수 있습니다.
  • 많은 클라이언트가 병렬로 검색 요청을 보낼 때는 일반적으로 더 낮은 슬라이스 수가 더 잘 작동합니다. 이는 더 많은 클라이언트 수가 초당 더 많은 쿼리로 이어지고, 이는 더 높은 리소스 사용량으로 해석되기 때문에 CPU 사용률에 반영됩니다.

OpenSearch 3.0으로 업그레이드할 때 auto 모드에서 동시 검색이 기본적으로 활성화되므로 집계가 있는 워크로드에서 CPU 사용률이 높아질 수 있습니다. OpenSearch 2.x 클러스터의 CPU 사용률이 집계 워크로드를 실행할 때 25%를 초과하는 경우 업그레이드 전에 다음 옵션을 고려하세요:

  • 증가된 CPU 요구량을 수용하기 위해 클러스터의 리소스 확장을 계획하세요.
  • 사용 사례에 확장이 불가능한 경우 동시 검색을 비활성화할 준비를 하세요.

제한사항

다음 집계는 동시 검색 모델을 지원하지 않습니다. 검색 요청에 이러한 집계 중 하나가 포함되어 있으면 클러스터 수준 또는 인덱스 수준에서 동시 세그먼트 검색이 활성화되어 있어도 요청이 비동시 경로를 사용하여 실행됩니다.

  • 조인 필드의 부모 집계. 자세한 정보는 이 GitHub 이슈를 참조하세요.
  • samplerdiversified_sampler 집계. 자세한 정보는 이 GitHub 이슈를 참조하세요.

기타 고려사항

다음 섹션은 동시 세그먼트 검색에 대한 추가 고려사항을 제공합니다.

terminate_after 검색 매개변수

terminate_after 검색 매개변수는 지정된 수의 일치하는 문서가 수집되면 검색 요청을 종료하는 데 사용됩니다. 요청에 terminate_after 매개변수를 포함하면 동시 세그먼트 검색이 비활성화되고 요청이 비동시 방식으로 실행됩니다.

일반적으로 쿼리는 더 작은 terminate_after 값과 함께 사용되므로 감소된 데이터셋에서 검색이 수행되어 빠르게 완료됩니다. 따라서 이 경우 동시 검색이 성능을 더 향상시키지 못할 수 있습니다. 또한 terminate_aftertrack_total_hits 또는 size와 같은 다른 검색 요청 매개변수와 함께 사용되면 복잡성이 추가되고 예상 쿼리 동작이 변경됩니다. terminate_after를 포함하는 검색 요청에 대해 비동시 경로로 폴백하면 동시 및 비동시 요청 간의 일관된 결과가 보장됩니다.

정렬

세그먼트의 데이터 레이아웃에 따라 정렬 최적화 기능은 최소값과 최대값뿐만 아니라 이전에 수집된 값을 기반으로 전체 세그먼트를 정리할 수 있습니다. 최상위 값이 처음 몇 개 세그먼트에 있고 다른 모든 세그먼트가 정리되면 동시 세그먼트 검색으로 정렬할 때 쿼리 지연 시간이 증가할 수 있습니다. 반대로, 마지막 몇 개 세그먼트에 최상위 값이 포함되어 있으면 동시 세그먼트 검색으로 지연 시간이 향상될 수 있습니다.

용어 집계

비동시 검색은 문서 수 오류를 계산하고 doc_count_error_upper_bound 응답 매개변수에서 반환합니다. 동시 세그먼트 검색 중에는 shard_size 매개변수가 세그먼트 슬라이스 수준에서 적용됩니다. 이 때문에 동시 검색이 추가 문서 수 오류를 발생시킬 수 있습니다.

shard_sizedoc_count_error_upper_bound와 수집된 버킷 모두에 어떻게 영향을 줄 수 있는지에 대한 자세한 정보는 이 GitHub 이슈를 참조하세요.

개발자 정보

다음 섹션은 개발자를 위한 추가 정보를 제공합니다.

AggregatorFactory 변경사항

구현 세부사항으로 인해 모든 집계자 유형이 동시 세그먼트 검색을 지원할 수 있는 것은 아닙니다. 이를 수용하기 위해 주어진 집계 유형이 동시 세그먼트 검색을 지원하는지 나타내기 위해 AggregatorFactory 클래스에 supportsConcurrentSegmentSearch() 메서드를 도입했습니다. 기본적으로 이 메서드는 false를 반환합니다. 동시 세그먼트 검색을 지원해야 하는 모든 집계자는 자체 팩토리 구현에서 이 메서드를 재정의해야 합니다.

사용자 정의 플러그인 기반 Aggregator 구현이 동시 검색 경로에서 작동하는지 확인하려면 플러그인 개발자는 동시 검색이 활성화된 상태에서 구현을 확인한 다음 플러그인을 업데이트하여 supportsConcurrentSegmentSearch() 메서드를 재정의하여 true를 반환하도록 할 수 있습니다.

profile
행복합시다~

0개의 댓글