如何對 Amazon OpenSearch Service 叢集上的高 CPU 使用率進行疑難排解?
上次更新日期:2021 年 8 月 5 日
我的資料節點顯示了 Amazon OpenSearch 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)
此外,使用 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
Amazon OpenSearch Service 是 Amazon Elasticsearch Service 的後繼者。