如何對 Amazon OpenSearch Service 中的斷路器異常狀況進行疑難排解?

2 分的閱讀內容
0

我正在嘗試將資料傳送至我的 Amazon OpenSearch Service 叢集。但是,我收到一個表示資料過大的斷路異常狀況錯誤。為什麼會發生這種情況,我該如何解決這個問題?

簡短描述

當請求達到 OpenSearch Service 節點時,斷路器會預估載入所需資料需要的記憶體量。然後,OpenSearch Service 會比較預估的大小與設定的堆積大小限制。如果您的資料預估大小大於可用堆積大小,則系統會終止查詢。因此,系統會擲回 CircuitBreakerException,以避免節點超載。

OpenSearch Service 會使用以下斷路器來避免 JVM OutofMemoryError 異常狀況:

  • 請求
  • Fielddata
  • 傳輸中請求
  • 客戶服務
  • 上層

**注意:**請務必瞭解是由這五個斷路器中的哪一個引發異常狀況,因為每個斷路器都有其調校需求。如需有關斷路器類型的詳細資訊,請參閱 Elasticsearch 網站上的斷路器設定

若要取得每個節點和每個斷路器目前的記憶體使用量,請使用以下命令:

GET _nodes/stats/breaker

此外,請注意,斷路器僅為盡力最佳機制。雖然斷路器會提供一些彈性以避免節點超載,但您最終可能仍會收到 OutofMemoryError。斷路器只有在明確預留記憶體時才能追蹤記憶體,因此並非總是能預估確切的記憶體使用量。例如,如果您有少量的記憶體堆積,則未追蹤記憶體的相對負擔會更大。如需有關斷路器和節點彈性的詳細資訊,請參閱 Elasticsearch 網站上的使用真正的記憶體斷路器以改善節點彈性

若要避免資料節點超載,請遵循對高 JVM 記憶體壓力進行疑難排解區段中提供的提示。

解決方案

斷路器異常狀況

如果您使用的是 Elasticsearch 7.x 及更高版本的 16 GB 堆積,在達到斷路器限制時,則會收到以下錯誤:

{
    "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]",
            "bytes_wanted": 16355096754,
            "bytes_limit": 16213167308
        }],
        "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]",
        "bytes_wanted": 16355096754,
        "bytes_limit": 16213167308
    },
    "status": 503
}

此範例輸出表示要處理的資料太大,上層斷路器無法處理。上層斷路器 (斷路器類型) 負責叢集的整體記憶體使用量。發生上層斷路器異常狀況時,所有斷路器使用的記憶體總數已超過設定的限制。上層斷路器會在叢集超過 16 GB 的 95% (即 15.2 GB 的堆積) 時,拋出異常狀況。

您可以計算記憶體使用量與設定斷路器限制之間的差異,以驗證此邏輯。使用我們範例輸出的值,並從「[16213167308/15gb] 的限制」中減去「實際用量:[15283269136/14.2gb]」。此計算內容會顯示此請求需要大約 1.02 GB 的 新位元組預留記憶體,才能順利處理請求。不過,在此範例中,在資料請求進入時,叢集只有少於 0.8 GB 的可用記憶體堆積。因此,斷路器會跳閘。

斷路器異常狀況訊息可以此方式解釋:

  • [<http_request>**] 的資料︰**用戶端會將 HTTP 請求傳送至您叢集中的節點。OpenSearch Service 會在本機處理請求,或將其傳遞到另一個節點進行其他處理。
  • **可能是 [#]:**處理請求時,堆積大小為何。
  • **[#] 的限制:**目前斷路器限制。
  • **實際用量:**JVM 堆積的實際用量。
  • **新位元組預留:**處理請求所需的實際記憶體。

JVM 記憶體壓力

斷路器中斷異常狀況通常是因高 JVM 記憶體壓力所造成。JVM 記憶體壓力是指用於您叢集中所有資料節點的 Java 堆積百分比。檢查 Amazon CloudWatch 中的 JVMMemoryPressure 指標,以判斷目前用量。

**注意:**資料節點的 JVM 堆積大小已設定為實體記憶體 (RAM) 的一半,最多為 32 GB。例如,如果實體記憶體 (RAM) 是每個節點 128 GB,堆積大小將仍為 32 GB (最大堆積大小)。否則,堆積大小會以為實體記憶體的一半大小來計算。

高 JVM 記憶體壓力可能是由以下原因引起:

  • 增加對叢集的請求數。檢查 Amazon CloudWatch 中的 IndexRateSearchRate 指標,以判斷您目前的負載。
  • 彙總、萬用字元,以及在查詢中使用寬廣的時間範圍。
  • 節點中的碎片分配不平衡,或一個叢集中有太多碎片。
  • 索引映射劇增。
  • 使用 fielddata 資料結構來查詢資料。Fielddata 可以消耗大量堆積空間,並在區段生命週期中持續保留在堆積中。因此,使用 Fielddata 時,叢集上的 JVM 記憶體壓力將持續很高。如需詳細資訊,請參閱 Elasticsearch 網站上的 Fielddata

疑難排解高 JVM 記憶體壓力

若要解決高 JVM 記憶體壓力,請嘗試以下秘訣:

  • 減少叢集的傳入流量,尤其是在您的工作負載繁重時更是如此。
  • 考慮擴展叢集以取得更多 JVM 記憶體,以支援您的工作負載。
  • 如果不可能進行叢集擴展,請嘗試刪除舊的或未使用的索引來減少碎片數量。由於碎片中繼資料儲存在記憶體中,因此減少碎片數可降低整體記憶體用量。
  • 啟用慢速日誌以識別錯誤請求。
    **注意:**在啟用組態變更之前,請驗證 JVM 記憶體壓力低於 85%。如此一來,您就可以避免對現有資源增加其他負擔。
  • 最佳化搜尋和索引請求,並選擇正確的碎片數。如需有關索引和碎片數的詳細資訊,請參閱開始使用 Amazon OpenSearch Service:我需要幾個碎片?
  • 停用並避免使用 fielddata。 根據預設,除非 fielddata 在索引映射中有明確定義,否則其在文字欄為上會設為 "false"。
  • 使用 reIndex API建立或更新索引範本 API,將索引映射類型變更為關鍵字。您可以使用關鍵字類型作為對文字欄位執行彙總和排序的替代方案。
  • 避免在文字欄位上彙總,以避免欄位資料增加。在您使用更多欄位資料時,就會耗用更多的堆積空間。使用叢集統計資料 API 操作來檢查欄位資料。
  • 使用以下 API 呼叫來清除 fielddata 快取:
POST /index_name/_cache/clear?fielddata=true (index-level cache)
POST */_cache/clear?fielddata=true (cluster-level cache)

**警告:**如果您清除 fielddata 快取,任何進行中的查詢將可能中斷。

如需詳細資訊,請參閱如何對 Amazon OpenSearch Service 叢集上的高 JVM 記憶體壓力進行疑難排解?


相關資訊

Amazon OpenSearch Service 的最佳實務

如何改善 Amazon OpenSearch Service 叢集的索引效能?

AWS 官方
AWS 官方已更新 3 年前