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

3 分的閱讀內容
0

當我將搜尋或寫入請求提交至我的 Amazon OpenSearch Service 叢集時,請求會被拒絕。

簡短說明

當您在 OpenSearch Service 叢集中寫入或搜尋資料時,您可能會收到下列 HTTP 429 錯誤或 es_rejected_execution_exception

error":"elastic: Error 429 (Too Many Requests): rejected execution of org.elasticsearch.transport.TransportService$7@b25fff4 on
EsThreadPoolExecutor[bulk, queue capacity = 200, org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor@768d4a66[Running,
pool size = 2, active threads = 2, queued tasks = 200, completed tasks = 820898]] [type=es_rejected_execution_exception]"

Reason={"type":"es_rejected_execution_exception","reason":"rejected execution of org.elasticsearch.transport.TcpTransport$RequestHandler@3ad6b683 on EsThreadPoolExecutor[search, queue capacity = 1000, org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor@bef81a5[Running, pool size = 25, active threads = 23, queued tasks = 1000, completed tasks = 440066695]]"

下列變數可能會導致 HTTP 429 錯誤或 es_rejected_execution_exception

  • 資料節點執行個體類型和搜尋或寫入限制
  • 執行個體指標的高值
  • 活動執行緒和佇列執行緒
  • 高 CPU 使用率和 JVM 記憶體壓力

可能會因為向叢集發出的搜尋寫入請求而發生 HTTP 429 錯誤。拒絕情形也可能來自叢集的單一節點或多個節點。

**注意事項:**不同版本的 Elasticsearch 會使用不同的執行緒集區來處理對 _index API 的呼叫。1.5 版和 2.3 版 Elasticsearch 會使用索引執行緒集區。5.x、6.0 和 6.2 版 Elasticsearch 會使用大量執行緒集區。6.3 版及更高版本 Elasticsearch 會使用寫入執行緒集區。如需詳細資訊,請參閱 Elasticsearch 網站上的執行緒集區

解決方法

資料節點執行個體類型和搜尋或寫入限制

資料節點執行個體類型具有固定的虛擬 CPU (vCPU)。將 vCPU 計數插入您的公式,以擷取節點可在進入佇列之前執行的並行搜尋寫入作業。如果活動執行緒已滿,則執行緒會溢出至佇列,最終遭到拒絕。如需有關 vCPU 和節點類型之間關係的詳細資訊,請參閱 OpenSearch Service 定價

此外,您可以在每個節點執行的搜尋或寫入數量也受到限制。此限制基於執行緒集區定義和 Elasticsearch 版本編號而定。如需詳細資訊,請參閱 Elasticsearch 網站上的執行緒集區

例如,如果您為 Elasticsearch 叢集 (7.4 版) 中的五個節點選擇 R5.2xlarge 節點類型,則該節點將擁有 8 個 vCPU。

請使用下列公式計算搜尋請求的活動執行緒數量上限:

int ((# of available_processors * 3) / 2) + 1

請使用下列公式來計算寫入請求的活動執行緒數量上限:

int (# of available_processors)

您最多可以在 R5.2xlarge 節點上執行 13 個搜尋作業:

(8 VCPUs * 3) / 2 + 1 = 13 operations

您最多可以在 R5.2xlarge 節點上執行 8 個寫入作業:

8 VCPUs = 8 operations

您最多可在具有五個節點的 OpenSearch Service 叢集上執行 65 個搜尋作業:

5 nodes * 13 = 65 operations

您最多可以在具有五個節點的 OpenSearch Service 叢集上執行 40 個寫入作業:

5 nodes * 8 = 40 operations

執行個體指標的高值

若要對 429 例外狀況進行疑難排解,請檢查叢集的下列 Amazon CloudWatch 指標:

  • **IndexingRate:**每分鐘的索引作業數目。對 _bulk API 的單一呼叫 (新增兩個文件並更新兩個文件),將被計算為四個可能跨節點的作業。如果該索引有一個或多個複本,則叢集中的其他節點也會記錄總共四個索引作業。文件刪除不會計入 IndexingRate 指標中。
  • **SearchRate:**資料節點上所有碎片的每分鐘搜尋請求總數。對 _search API 的單次呼叫,可能會傳回來自許多不同碎片的結果。如果一個節點上有五個不同的碎片,即使用戶端只提出一個請求,節點依然會針對此指標報告 “5”。
  • **CoordinatingWriteRejected:**在協調節點上出現的拒絕總數。這些拒絕情形是由 OpenSearch Service 啟動以來累積的索引壓力所造成。
  • **PrimaryWriteRejected:**主要碎片上出現的拒絕總數。這些拒絕情形是由上次 OpenSearch Service 啟動以來累積的索引壓力所造成。
  • **ReplicaWriteRejected:**因索引壓力而在複本碎片上出現的拒絕總數。這些拒絕情形是由上次 OpenSearch Service 啟動以來累積的索引壓力所造成。
  • **ThreadpoolWriteQueue:**寫入執行緒集區中佇列任務的數目。此指標會告訴您請求是因為 CPU 使用率較高,還是因為並行索引作業數量較高而遭到拒絕。
  • **ThreadpoolWriteRejected:**寫入執行緒集區中遭拒的任務數目。
    **注意事項:**在 7.9 版 OpenSearch Service 中,預設寫入佇列大小從 200 個增加至 10,000 個。因此,此指標不再是 OpenSearch Service 拒絕的唯一指標。請使用 CoordinatingWriteRejectedPrimaryWriteRejectedReplicaWriteRejected 指標來監控 7.9 版及更新版本中的拒絕情形。
  • **ThreadpoolSearchQueue:**搜尋執行緒集區中佇列任務的數目。如果佇列大小持續維持在較高的範圍,請考慮擴展叢集。搜尋佇列大小上限為 1,000。
  • **ThreadpoolSearchRejected:**搜尋執行緒集區中遭到拒絕的任務數目。如果這個數字持續提高,請考慮擴展您的叢集。
  • **JVMMemoryPressure:**JVM 記憶體壓力會指定叢集節點中 Java 堆積的百分比。如果 JVM 記憶體壓力達到 75%,OpenSearch Service 會啟動並行標記掃描 (CMS) 垃圾回收器。垃圾回收是一個大量佔用 CPU 的流程。如果 JVM 記憶體壓力在數分鐘內保持此百分比,則可能會遇到叢集效能問題。如需詳細資訊,請參閱如何疑難排解 Amazon OpenSearch Service 叢集上的高 JVM 記憶體壓力?

**注意事項:**列出的執行緒集區指標有助於通知您 IndexingRateSearchRate

如需有關使用 CloudWatch 監控 OpenSearch Service 叢集的詳細資訊,請參閱執行個體指標

活動執行緒和佇列執行緒

如果缺少 CPU 或出現大量並行請求,則佇列可能會遭到快速填滿,進而導致 HTTP 429 錯誤。若要監控您的佇列執行緒,請檢查 CloudWatch 中的 ThreadpoolSearchQueueThreadpoolWriteQueue 指標。

若要檢查「作用中」和「佇列」執行緒是否出現任何搜尋拒絕情形,請使用下列命令:

GET /_cat/thread_pool/search?v&h=id,name,active,queue,rejected,completed

若要檢查「作用中」和「佇列」 執行緒是否出現寫入拒絕情形,請使用 "write" 取代 "search"。輸出中的 rejectedcompleted 值是累加節點計數器,系統會在啟動新節點時重設這些計數器。如需詳細資訊,請參閱 Elasticsearch 網站上 cat 執行緒集區 API具有明確資料欄的範例一節。

**注意事項:**每個節點上的大量佇列可以容納 50 到 200 個請求,具體情況取決於您使用的 Elasticsearch 版本。當佇列已滿時,系統會拒絕新的請求。

搜尋和寫入拒絕的錯誤

搜尋拒絕

搜尋拒絕錯誤代表作用中執行緒處於忙碌狀態,而且佇列已經因為達到工作數量上限而遭到填滿。因此,您的搜索請求可能會遭到拒絕。您可以設定 OpenSearch Service 日誌,讓這些錯誤訊息顯示在搜尋慢速日誌中。

**注意事項:**若要避免額外的費用,請將慢速日誌臨界值設定為較充分的數字。例如,如果您的大多數查詢都需要 11 秒才能完成,而您的臨界值為 “10”,則 OpenSearch Service 會需要更多時間來寫入日誌。您可以透過將慢速日誌臨界值設定為 20 秒來避免這種額外費用。然後,系統就只會記錄少部分的較慢查詢 (花費時間超過 11 秒)。

在將您的叢集設定為將搜尋慢速日誌推送至 CloudWatch 之後,請設定特定的慢速日誌產生臨界值。您可以使用下列 HTTP POST 呼叫來設定特定的慢速日誌產生臨界值:

curl -XPUT http://<your domain’s endpoint>/index/_settings -d '{"index.search.slowlog.threshold.query.<level>":"10s"}'

寫入拒絕

作為寫入拒絕的 429 錯誤訊息,即代表出現大量佇列錯誤。es_rejected_execution_exception[bulk] 表示您的佇列已滿,且任何新請求都遭到拒絕。當對叢集的請求數量超過大量佇列大小 (threadpool.bulk.queue_size) 時,就會發生此大量佇列錯誤。每個節點上的大量佇列可以容納 50 到 200 個請求,具體情況取決於您使用的 Elasticsearch 版本。

您可以設定 OpenSearch Service 日誌,讓這些錯誤訊息顯示在索引慢速日誌中。

**注意事項:**若要避免額外的費用,請將慢速日誌臨界值設定為較充分的數字。例如,如果您的大多數查詢都需要 11 秒才能完成,而您的臨界值為 “10”,則 OpenSearch Service 將需要額外的時間來寫入日誌。您可以透過將慢速日誌臨界值設定為 20 秒來避免這種額外費用。然後,系統就只會記錄少部分的較慢查詢 (花費時間超過 11 秒)。

在將您的叢集設定為將搜尋慢速日誌推送至 CloudWatch 之後,請設定特定的慢速日誌產生臨界值。若要設定特定的慢速日誌產生臨界值,請使用下列 HTTP POST 呼叫:

curl -XPUT http://<your domain’s endpoint>/index/_settings -d '{"index.indexing.slowlog.threshold.query.<level>":"10s"}'

寫入拒絕最佳實務

下列是一些可減少寫入拒絕的最佳實務:

  • 當建立文件索引的速度變得更快時,寫入佇列較不可能達到容量上限。
  • 請根據您的工作負載和所需的效能調整大量處理的大小。如需詳細資訊,請參閱 Elasticsearch 網站上的調整索引速度
  • 在應用程式邏輯中新增指數式重試邏輯。指數式重試邏輯可確保系統自動重試失敗的請求。
    **注意事項:**如果您的叢集持續遇到高度並行請求,則指數式重試邏輯將無法協助解決 429 錯誤。當流量會突然或偶爾出現突然激增時,請使用此最佳實務。
  • 如果您要從 Logstash 擷取資料,請調整工作者數量和大量處理的大小。最佳實務是將大量處理的大小設定為 3 至 5 MB 之間。

如需索引效能調整的詳細資訊,請參閱如何改善 OpenSearch Service 叢集的索引效能?

搜尋拒絕最佳實務

下列是一些可減少搜尋拒絕的最佳實務:

  • 切換到較大的執行個體類型。OpenSearch Service 主要依賴檔案系統快取,以取得更快的搜尋結果。每個節點上執行緒集區中搜尋請求的執行緒數量等於下列數量:int((# of available_processors * 3) / 2) + 1。切換到具有更多 vCPU 的執行個體,以獲得更多執行緒來處理搜索請求。
  • 為指定索引或所有具有合理臨界值的索引開啟搜尋慢速日誌。進行檢查以查看哪些查詢需要更長的執行時間,並為您的查詢實作搜尋效能策略。如需詳細資訊,請在 Elasticsearch 網站上參閱針對初學者的 Elasticsearch 搜尋疑難排解進階調整: 尋找和修復緩慢的 Elasticsearch 查詢
AWS 官方
AWS 官方已更新 2 年前