如何對 Amazon OpenSearch Service 叢集上的高 CPU 使用率進行疑難排解?

上次更新日期:2021 年 8 月 5 日

我的資料節點顯示了 Amazon OpenSearch Service (Amazon Elasticsearch Service 的後繼者) 叢集上的高 CPU 使用率。如何對此問題進行疑難排解?

簡短描述

最佳實務是維持 CPU 使用率,以確保 OpenSearch Service 擁有足夠的資源來執行任務。在高 CPU 使用率下一致執行的叢集可能會降低叢集效能。當您的叢集超載時,OpenSearch Service 將停止回應,從而導致請求逾時。

若要對叢集上的高 CPU 使用率進行疑難排解,請考慮下列方法:

  • 使用節點熱執行緒 API。(如需詳細資訊,請參閱 Elasticsearch 網站上的節點熱執行緒 API。)
  • 檢查寫入操作或大量 API 執行緒集區。(如需詳細資訊,請參閱 Elasticsearch 網站上的大量 API。)
  • 檢查搜尋執行緒集區。(如需詳細資訊,請參閱 Elasticsearch 網站上的執行緒集區。)
  • 檢查 Apache Lucene 合併執行緒集區(如需詳細資訊,請參閱 Elasticsearch 網站上的合併。)

解決方案

使用節點熱執行緒 API

如果您的 OpenSearch Service 叢集中存在固定 CPU 峰值,則使用節點熱執行緒 API。節點熱執行緒 API 充當任務管理器,向您顯示在叢集上執行的所有資源密集型執行緒的明細。

以下是節點熱執行緒 API 的範例輸出:

GET _nodes/hot_threads

100.0% (131ms out of 500ms) cpu usage by thread 
'opensearch[xxx][search][T#62]' 10/10 snapshots sharing following 10 
elements sun.misc.Unsafe.park(Native Method) 
java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) 
java.util.concurrent.LinkedTransferQueue.awaitMatch(LinkedTransferQueue.java:737)
 
java.util.concurrent.LinkedTransferQueue.xfer(LinkedTransferQueue.java:647)
 
java.util.concurrent.LinkedTransferQueue.take(LinkedTransferQueue.java:1269)
 
org.opensearch.common.util.concurrent.SizeBlockingQueue.take(SizeBlockingQueue.java:162)
 
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
java.lang.Thread.run(Thread.java:745)
注意: 節點熱執行緒輸出會列出每個節點的資訊。輸出的長度取決於在您的 OpenSearch Service 叢集中執行的節點數量。

此外,使用 cat 節點 API 來檢視目前資源使用率的明細。您可以使用以下命令縮小 CPU 使用率最高的節點子集:

GET _cat/nodes?v&s=cpu:desc

輸出中的最後一欄會顯示您的節點名稱。如需詳細資訊,請參閱 Elasticsearch 網站上的 cat 節點 API

然後,將相關節點名稱傳遞給您的熱執行緒 API:

GET _nodes/<node-name>/hot_threads

如需詳細資訊,請參閱 Elasticsearch 網站上的熱執行緒 API

節點熱執行緒輸出如下所示:

<percentage> of cpu usage by thread 'opensearch[<nodeName>][<thread-name>]

執行緒名稱會指出哪些 OpenSearch Service 處理程序正在耗用高 CPU。

檢查寫入操作或大量 API 執行緒集區

OpenSearch Service 中的 429 錯誤可能表示您的叢集正在處理太多的大量索引請求。當您的叢集中存在固定 CPU 峰值時,OpenSearch Service 會拒絕大量索引請求。

寫入執行緒集區會處理索引請求,其中包括大量 API 操作。若要確認您的叢集處理的大量索引請求是否太多,請檢查 Amazon CloudWatch 中的 IndexingRate 指標。

如果您的叢集處理的大量索引請求是否太多,則請考慮下列方法:

  • 減少叢集上的大量請求數。
  • 減少每個大量請求的大小,以便您的節點可以更有效地進行處理。
  • 如果使用 Logstash 將資料推送到 OpenSearch Service 叢集,則請減少批次大小或工作者數量。
  • 如果叢集的擷取速率變慢,則請擴展叢集 (水平或垂直)。若要擴充叢集,請增加節點數和執行個體類型,以便 OpenSearch Service 可以正確處理傳入請求。

檢查搜尋執行緒集區

耗用高 CPU 的搜尋執行緒集區表示搜尋查詢會讓 OpenSearch Service 叢集癱瘓。您的叢集可能會被單一長時間執行的查詢癱瘓。叢集執行的查詢增加也會影響您的搜尋執行緒集區。

若要檢查單一查詢是否增加 CPU 使用率,請使用任務管理 API。例如:

GET _tasks?actions=*search&detailed

任務管理 API 會擷取叢集上執行的所有作用中搜尋查詢。如需詳細資訊,請參閱 Elasticsearch 網站上的任務管理 API

下列是輸出範例:

{
  "nodes": {
    "U4M_p_x2Rg6YqLujeInPOw": {
      "name": "U4M_p_x",
      "roles": [
        "data",
        "ingest"
      ],
      "tasks": {
        "U4M_p_x2Rg6YqLujeInPOw:53506997": {
          "node": "U4M_p_x2Rg6YqLujeInPOw",
          "id": 53506997,
          "type": "transport",
          "action": "indices:data/read/search",
          "description": """indices[*], types[], search_type[QUERY_THEN_FETCH], source[{"size":10000,"query":{"match_all":{"boost":1.0}}}]""",
          "start_time_in_millis": 1541423217801,
          "running_time_in_nanos": 1549433628,
          "cancellable": true,
          "headers": {}
        }
      }
    }
  }
}

檢查描述欄位以識別正在執行的特定查詢。running_time_in_nanos 欄位指出查詢執行的時間量。若要減少 CPU 使用率,請取消耗用高 CPU 的搜尋查詢。任務管理 API 也支援 _cancel 呼叫。

注意:請務必記錄輸出中的任務 ID,以取消特定任務。在此範例中,任務 ID 是 "U4M_p_x2Rg6YqLujeInPOw:53506997"。

以下是 任務管理 POST 呼叫的範例:

POST _tasks/U4M_p_x2Rg6YqLujeInPOw:53506997/_cancel

任務管理 POST 呼叫會將任務標記為「已取消」,釋放任何相依的 AWS 資源。如果在叢集上執行多個查詢,則請使用 POST 呼叫一次取消一個查詢。取消每個查詢,直到叢集回到正常狀態為止。在查詢主體中設定適當的逾時值也是最佳實務,以防止高 CPU 峰值。(如需詳細資訊,請參閱 Elasticsearch 網站上的請求主體搜尋參數。) 若要驗證作用中的查詢數是否已減少,請檢查 Amazon CloudWatch 中的 SearchRate 指標。

注意:同時取消 OpenSearch Service 叢集中所有作用中的搜尋查詢,可能會導致用戶端應用程式端發生錯誤。

檢查 Apache Lucene 合併執行緒集區

OpenSearch Service 使用 Apache Lucene 對叢集上的文件編製索引和搜尋。Apache Lucene 執行合併操作,以減少每個碎片所需的有效區段數,並移除任何刪除的文件。每當在碎片中建立新區段時,此程序就會執行。

如果您觀察到影響 CPU 使用率的 Apache Lucene 合併執行緒操作,則請增加 OpenSearch Service 叢集索引的 refresh_interval 設定。refresh_interval 設定的增加會減慢叢集的區段建立速度。

注意將索引遷移至 UltraWarm 儲存的叢集可能會增加 CPU 使用率。UltraWarm 遷移通常會涉及強制合併 API 操作,這可能是 CPU 密集型。

若要檢查是否有任何 UltraWarm 遷移,請使用下列命令:

GET _ultrawarm/migration/_status?v