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

3 分的閱讀內容
0

我的資料節點在 Amazon OpenSearch Service 叢集上顯示高 CPU 使用率。

簡短說明

最佳做法是維持 CPU 使用率,以便確保 OpenSearch Service 執行工作所需的資源足夠。持續以高 CPU 使用率執行的叢集可能會降低叢集效能。當叢集超載時,OpenSearch Service 會停止回應,進而導致要求逾時。

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

  • 使用節點熱執行緒 API。
  • 檢查寫入作業或大量 API 執行緒集區。
  • 檢查搜尋執行緒集區。
  • 檢查 Apache Lucene 合併執行緒集區。
  • 檢查 JVM 記憶體壓力
  • 檢閱您的碎片策略
  • 最佳化您的查詢

解決方法

使用節點熱執行緒 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。

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

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

OpenSearch Service 中的 429 錯誤可能表示您的叢集處理的大量索引要求過多。當叢集中的 CPU 使用率持續發生激增時,OpenSearch Service 會拒絕大量索引要求。

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

如果您的叢集處理的大量索引要求過多,請考慮下列方法:

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

如需更多詳細資訊,請參閱 Elasticsearch 網站上的大量 API

檢查搜尋執行緒集區

高度耗用 CPU 的搜尋執行緒集區,即表示搜尋查詢會讓您的 OpenSearch Service 叢集不堪重負。您的叢集可能會遭到一個長時間執行的查詢所占據。叢集執行的查詢增加也會影響您的搜尋執行緒集區。

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

GET _tasks?actions=*search&detailed

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

注意: 只有在任務管理 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 叢集中同時取消所有作用中的搜尋查詢,可能會導致用戶端應用程式發生錯誤。

如需更多詳細資訊,請參閱 Elasticsearch 網站上的執行緒集區

檢查 Apache Lucene 合併執行緒集區

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

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

注意將索引移轉至 UltraWarm 儲存體的叢集可能會增加您的 CPU 使用率。UltraWarm 移轉通常涉及強制合併 API 作業,這可能會大量佔用 CPU。

若要檢查 UltraWarm 移轉,請使用下列命令:

GET _ultrawarm/migration/_status?v

如需更多詳細資訊,請參閱 Elasticsearch 網站上的合併

檢查 JVM 記憶體壓力

檢閱叢集節點中 Java 堆積的 JVM 記憶體壓力百分比。如果 JVM 記憶體壓力達到 75%,Amazon OpenSearch Service 會觸發並行標記掃描 (CMS) 記憶體回收器。如果 JVM 記憶體壓力達到 100%,則 OpenSearch Service JVM 會設定為結束,並最終因為「記憶體不足」(OutOfMemory,OOM) 而導致重新啟動。

在下列範例日誌中,JVM 處於建議的範圍內,但叢集受到長時間執行的記憶體回收影響:

[2022-06-28T10:08:12,066][WARN ][o.o.m.j.JvmGcMonitorService]
[515f8f06f23327e6df3aad7b2863bb1f] [gc][6447732] overhead, spent [9.3s]
collecting in the last [10.2s]

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

檢閱您的碎片策略

視叢集大小而定,您的叢集可能會因為碎片太多而使效能降低。最佳做法是每 GiB 的 Java 堆積不超過 25 個碎片

根據預設,Amazon OpenSearch Service 的碎片策略為 5:1,其中每個索引會分為五個主要碎片。在每個索引中,每個主要碎片也有自己的複本。OpenSearch Service 會自動將主要碎片和複本碎片分配給不同的數據節點,並確保在發生故障時有備份。

如需更多詳細資訊,請參閱如何重新平衡 Amazon OpenSearch Service 叢集中不均勻的碎片分佈?

最佳化您的查詢

大量彙總、萬用字元查詢 (尤其是開頭萬用字元) 和正規表達式查詢,在運算方面可能成本昂貴並導致 CPU 使用率激增。搜尋慢速日誌和索引慢速日誌可協助您診斷昂貴且有問題的查詢。

如需更多詳細資訊,請參閱使用 Amazon CloudWatch Logs 監控 OpenSearch 日誌

相關資訊

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

如何解決 Amazon OpenSearch Service 中的搜尋或寫入拒絕問題?

調整 Amazon OpenSearch Service 網域大小

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