Elasticsearch 常見問題的解決思路


本文為es性能監控基礎的擴展,大家可以先看下性能監控基礎,熟悉下es的基本原理。為翻譯性質文檔,感謝原作者,原始文檔地址

類似於汽車的運行方式,Elasticsearch旨在讓用戶快速上手和運行,而無需了解其所有的內部工作。然而我們在使用過程中,總會遇到這樣那樣的問題。下文將介紹Elasticsearch使用時經常遇到的一些挑戰,以及我們如何應對這些挑戰。如下列舉了5個常見問題:

一、我的es集群是紅色或者黃色的,我該如何處理?

正如性能監控基礎中所講,如果缺少一個或多個主分片(及其副本),則集群狀態將報告為紅色,如果缺少一個或多個副本分片,則集群狀態將呈黃色。通常情況下,當某個節點由於某種原因(硬件故障,較長的垃圾收集時間等)而退出群集時,會發生這種情況。一旦節點回復,其分片在轉為active之前會處於initializing。(這個在head中可以通過觀察分片顏色得到)
當節點重新加入群集時,initializing 分片的數量會達到峰值,然后隨着分片轉為active,峰值回落。如下圖:

在此initializing 期間,集群狀態可能會從綠色轉換為黃色或紅色,直到恢復節點上的分片重新轉為active。 在許多情況下,黃色或紅色的簡單狀態更改可能不需要您采取任何行動。

但是,如果您注意到群集狀態長時間處於紅色或黃色狀態,請檢查集群節點的數量。

如果活動節點的數量低於預期,則表示至少有一個節點丟失連接,並且無法重新加入群集。 要查找離開集群的節點,請檢查類似於以下行的日志(默認位於Elasticsearch主目錄的logs文件夾中)。

[TIMESTAMP] ... Cluster health status changed from [GREEN] to [RED] (reason: [[{<NODE_NAME>}...] left])

節點故障的原因可能會有所不同,從硬件或管理程序故障,到內存不足錯誤。檢查節點失敗的同一時間發生的任何性能指標異常。例如當前搜索速率或索引請求突然增加,如果確認是請求增加導致,那么這是一個暫時的故障,可以嘗試讓該斷開的節點重新加入集群。如果你無法恢復該節點,則可以添加新節點,並讓Elasticsearch從任何可用的副本分片恢復; 副本分片可以升級到主分片,並重新分發到剛剛添加的新節點上。

如果主分片和副分片都丟失了,則可以使用Elasticsearch的快照和還原模塊盡可能多地恢復丟失的數據。但是,如果您丟失了分片的主副本和副本副本,則可以使用Elasticsearch的快照和還原模塊盡可能多地恢復丟失的數據。 如果您還不熟悉此模塊,則可以將其用於在遠程存儲庫中存儲索引的快照以進行備份。

二、數據節點磁盤空間不夠了

如果所有數據節點的磁盤空間不足,將需要在集群中添加更多的數據節點。 還需要確保您的索引具有足夠的主分片,以便能夠在所有這些節點之間平衡其數據。

然而,如果只有某些節點的磁盤空間不足,這通常是索引分片太少的一個標志。 如果一個索引由幾個非常大的分片組成,那么Elasticsearch很難在各數據節點之間進行數據均衡。

將分片分發給各節點時,Elasticsearch會考慮各個節點的磁盤可用空間。默認情況下,不會將分片分發給磁盤使用率超過85%的節點。在Datadog中,您可以設置閾值警報,以便在任何單個數據節點的磁盤空間使用率達到80%時通知您,以便足夠的時間采取行動。

低磁盤使用空間有兩種補救措施。 (1)刪除過時的數據。 這對所有用戶來說可能不是一個可行的選擇,但是如果您正在存儲基於時間的數據,則可以存儲舊索引數據的快照,用於備份,同時更新索引設置以關閉這些過時索引的副本功能。(2)如果你需要所有的數據都存在集群中備用,要么升級硬件資源(vertically scale )、要么水平擴展集群(horizontally scale增加節點,這個是比較合適的)。為了更好適應數據不斷的增長,應該要多指定主分片的個數。

水平擴展集群的另外一個方法是創建一個新的索引並使用一個別名to join the two indices together under one namespace. 雖然單個分片存儲數據無技術意義上的上限,但是一般建議每個分片不超過50GB。

三、我的搜索執行時間過長怎么辦?

根據正在搜索的數據類型和每個查詢的結構方式,搜索性能有很大差異。根據您的數據的組織方式,你可能需要嘗試幾種不同的方法,以便找到一個能提高搜索性能的方法。這里介紹兩個: 自定義路由和強制合並

通常,當節點接收到搜索請求時,它需要將該請求傳達給索引中每個分片的副本。 自定義路由允許將相關數據存儲在相同的分片上,以便您只需搜索單個分片來滿足查詢。

例如,您可以通過在索引blog_index中的mapping中指定_routing值,將所有blogger1的數據存儲在同一個分片上。

curl -XPUT "localhost:9200/blog_index" -d '
{
  "mappings": {
    "blogger": {
      "_routing": {
        "required": true 
      }
    }
  }
}'

當您准備索引與blogger1相關的文檔時,請指定路由值:

curl -XPUT "localhost:9200/blog_index/blogger/1?routing=blogger1" -d '
{
  "comment": "blogger1 made this cool comment"
}'

現在,為了搜索blogger1的注釋,您需要記住在查詢中指定路由值,如下所示:

curl -XGET "localhost:9200/blog_index/_search?routing=blogger1" -d '
{
  "query": {
    "match": {
      "comment": {
        "query": "cool comment"
      }
    }
  }
}'

在Elasticsearch中,每個搜索請求必須檢查所命中的每個分片的每個segment。還可以通過在一個或多個索引上觸發Force Merge API來減少每個分片的segment數。 Force Merge API(或2.1.0之前的版本中的Optimize API)將提示索引中的segment繼續合並,直到每個碎片的segment計數減少為max_num_segments(默認為1)。如果大量觸發merges的成本相對降低,這種方法可以進行嘗試。

當分片上segment的數量很多時,強制merge segment將非常浪費。例如,強制將一個索引中的10000個segments壓縮到5000個並不耗費太多時間。但是,如果將這10000個segments壓縮為1個,將耗費數個小時的時間。The more merging that must occur, the more resources you take away from fulfilling search requests,這可能背離你的初衷。因此通常在非高峰時段(午夜)安排強制合並。

四、如何加快我的index速度

Elasticsearch預先配置了許多設置,嘗試確保您保留足夠的資源來搜索和索引數據。但是,如果您使用Elasticsearch嚴重偏向寫入,則可能會發現調整某些設置以提高索引性能是有意義的,即使這意味着丟失一些搜索性能或副本數據。 下面,我們將探討一些方法來優化用例來進行索引,而不是搜索數據。 (預設值是兼顧搜索和索引)
  • 分片分配: 如果你要創建一個更新頻繁的索引,請確保指定足夠的主分片,以便您可以在所有節點間均勻分布索引負載。一般建議是每個集群中的節點分配一個主分片。如果你的CPU和磁盤夠用,2個或者更多的主分片是可行的(注意:這個是對單個索引來描述的)。但是,請記住,分片過度分配會增加開銷,並可能會對搜索產生負面影響,因為搜索請求需要打到索引中的每個分片。另一方面,如果分配的分片數少於節點數,you may create hotspots?因為包含這些分片的節點需要處理比不包含任何索引分片的節點更多的索引請求。
  • 禁止 merge throttling: merge throttling是elasticsearch的一個自動機制:當es檢測到合並速度落后於索引速度時,es會throttle 索引請求。 如果要優化索引性能,而不是搜索性能,可以通過更新集群設置來禁止掉merge throttling(通過將indices.store.throttle.type設置為“none”)。You can make this change persistent (meaning it will persist after a cluster restart) or transient (resets back to default upon restart), based on your use case.
  • 增加indexing buffer的大小: 這個index-level 設置(indices.memory.index_buffer_size)決定了在將文檔寫入到磁盤上的segment之前buffer的總大小。默認為總heap的10%,以便為索引請求預留更多的heap,which doesn’t help you if you’re using Elasticsearch primarily for indexing.??
  • 先index,后replicate: 初始化索引時,在索引設置中指定零個復本分片,並在索引完成后添加副本。 這將提高索引性能。但是有一定的風險。
  • 刷新間隔拉長: 增加Index Settings API中的刷新間隔。 默認情況下,索引刷新過程每秒都會發生一次,但是在較大的索引期間,降低刷新頻率可以幫助減輕部分工作量。
  • 調整translog設置: 從版本2.0開始,Elasticsearch將在每次請求后將Translog數據刷新到磁盤,從而降低硬件故障時數據丟失的風險。如果你中索引性能,並且不太擔心潛在的數據丟失的可能,您可以將index.translog.durability更改為異步。 有了這一點,索引只會在每個sync_interval上提交寫入磁盤,而不是在每個請求之后提交寫入磁盤,從而使其更多的富余資源可以提供索引請求。

五、如何處理buik thread pool rejections ?

Thread pool rejections 通常是發送過多過快請求的標志。如果這是一個暫時故障(例如,您本周必須索引異常大量的數據,並且您預計很快就會恢復正常),你可以嘗試減慢請求的速度。 但是,如果希望集群能夠維持當前的請求速率,則可能需要通過添加更多的數據節點來擴展集群。為了利用增加節點數的處理能力,您還應確保您的索引包含足夠的分片,以便能夠均勻地將所有節點的負載分散。

總結:

由於優化結果將根據您的具體用例和設置而有所不同,您可以測試不同的設置和索引/查詢策略,以確定哪些方法對您的集群最有效。

總之尋找合適自己場景的優化和解決辦法,避重就輕、合理選擇。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM