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

最後更新日期:2021 年 10 月 19 日

當我向我的 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的發生:

  • 資料節點執行個體類型和搜尋或寫入限制
  • 執行個體指標的數值太高
  • 作用中和佇列的執行緒

向叢集提出搜尋寫入請求,可能會產生 HTTP 429 錯誤。叢集的單一節點或多個節點也可以拒絕請求。

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

解決方案

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

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

此外,每個節點可以進行的搜尋次數或寫入次數也有限制。這個限制取決於執行緒集區的定義和 Elasticsearch 的版本號碼。如需詳細資訊,請參閱 Elasticsearch 網站上的執行緒集區

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

使用下列公式可以計算搜尋請求的作用中執行緒上限:

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:寫入執行緒集區中被拒絕的任務數目。
    注意:預設寫入佇列大小在 OpenSearch Service 7.9 版中從 200 個增加到 10,000 個。因此,此指標不再是 OpenSearch Service 拒絕的唯一指標。使用 CoordinatingWriteRejectedPrimaryWriteRejectedReplicaWriteRejected 指標來監控 7.9 版和更新版本中的拒絕。如需詳細資訊,請參閱 UltraWarm 指標
  • ThreadpoolSearchQueue:搜尋執行緒集區中已排佇列的任務數目。如果佇列太長的情況持續,請考慮擴展叢集。搜尋佇列的大小上限為 1,000。
  • ThreadpoolSearchRejected:搜尋執行緒集區中被拒絕的作業數目。如果這個數字持續增加,請考慮擴展叢集。

注意:列出的執行緒集區指標有助您了解 IndexingRateSearchRate 的相關資訊。

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

作用中和佇列的執行緒

如果缺乏 CPU 或處理大量並行請求的能力,佇列可能會快速填滿,導致 HTTP 429 錯誤。若要監控佇列執行緒,請檢查 Amazon CloudWatch 中的 ThreadpoolSearchQueueThreadpoolWriteQueue metrics 指標。

若要檢查作用中和佇列執行緒的任何搜尋拒絕問題,請使用下列命令:

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

若要檢查作用中和佇列執行緒的寫入拒絕問題,請以 “write” 替換 “search”。在輸出中的拒絕完成數值是累計節點數值,這些數值會在啟動新節點時重設。如需詳細資訊,請參閱 Elasticsearch 網站上 cat 執行緒集區 API明確欄位範例一節。

注意:每個節點上的大量佇列可以容納 50 到 200 項請求,具體取決於您使用的 Elasticsearch 版本。佇列已滿時會拒絕新請求。如需詳細資訊,請參閱 Elasticsearch 網站上的執行緒集區

搜尋和寫入拒絕的錯誤範例

搜尋拒絕

搜尋拒絕錯誤表示作用中的執行緒正在忙碌中,而該佇列已達最高任務數目上限。因此,您的搜尋請求可能會遭到拒絕。您可以設定 OpenSearch Service 日誌,讓這些錯誤訊息出現在搜尋慢速日誌中。

注意:若要避免增加額外負擔,請將慢速日誌臨界值設定為較高的數值。例如,若您大部分的查詢需要花費 11 秒,而您將臨界值設定為 “10”,則 OpenSearch Service 將需要花費更多的時間來編寫日誌。您可以將慢速日誌的臨界值設定為 20 秒,以避免造成此類額外負擔。屆時,日誌只會記錄一小部分較慢的查詢 (即花費超過 11 秒的查詢)。

設定叢集以將搜尋慢速日誌推送到 Amazon 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 秒的查詢)。

設定叢集以將搜尋慢速日誌推送到 Amazon 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 之間。

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

搜尋拒絕情況的最佳實務

以下是減少搜尋拒絕情況的一些最佳實務:

  • 切換至較大的執行個體類型。為了加快搜尋速度,OpenSearch Service 相當依賴文件系統快取。每個節點上執行緒集區的搜尋請求執行緒數目按照下列計算:int((# of available_processors * 3) / 2) + 1。切換至具有更多 vCPUs 的執行個體,以取得更多執行緒來處理搜尋請求。
  • 為指定索引或所有索引啟用具有合理臨界值的搜尋慢速日誌。檢查哪些查詢需要較長時間來執行,並為查詢實作搜尋效能策略。如需詳細資訊,請參閱 Elasticsearch 網站上的適用於初學者的 Elasticsearch 搜尋疑難排解進階調校:尋找和修復慢速 Elasticsearch 查詢

Amazon OpenSearch Service 是 Amazon Elasticsearch Service 的後繼者。


此文章是否有幫助?


您是否需要帳單或技術支援?