您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關如何進行Elasticsearch集群規劃及性能優化實踐,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
我們在日常運維工作中也經常會遇到一些由于前期集群規劃不到位,導致后期業務增長集群規模大了之后帶來的各種各樣的集群可用性及穩定性問題。
這里列舉下其中比較典型的幾種集群規劃問題:
節點規格規劃問題:集群數量很大,但是每個節點的配置很低;
索引分片規劃問題:索引很小,但是設置了幾十個分片,或者索引很大,只設置了兩三個分片;
分片數量規劃問題:集群中包含 10萬+ 的分片。
下面來介紹下如何規劃好集群容量及索引配置,以及所遵循的一些原則和經驗。
集群規模的評估主要評估以下三個方面:
第一,計算資源評估,計算資源的評估主要是評估單節點的CPU和內存。
ES的計算資源一般消耗在寫入和查詢過程,經過總結大量ES集群的運維經驗,2C8G 的配置大概能支持 5k doc/s 的寫入,32C64G 的配置大概能支撐 5w doc/s的寫入能力。
第二,存儲資源評估,存儲資源的評估主要是評估磁盤的類型及容量大小。
例如ES集群使用什么類型的磁盤,SSD或者高性能云盤。以及每塊盤的容量大小,是選擇單盤多容量,還是多盤少容量。而對于冷熱分離的集群,則默認使用SSD作為熱節點,高性能云盤作為溫節點。
另外騰訊云ES支持單節點掛載多塊云硬盤,且經過性能壓測,3塊盤相比于1塊盤,吞吐量大約有2.8倍的提升。因此如果對寫入速度及IO性能要求較高,可選擇掛載多塊 SSD 磁盤。
ES冷熱分離多盤集群示意圖
第三,節點數量評估,節點數量的評估主要是評估集群數據節點的數量。
在同等集群性能的情況下,建議優先選擇高配置少節點的集群。例如 32C64G*3 節點的集群相比于 8C16G*12 節點的集群,在集群穩定性和擴容的便捷性上都有一定的優勢。
因為高配置的集群如果遇到性能瓶頸需要擴容,則只需要橫向擴容,即向集群中加入更多同等配置的節點即可;而低配置的集群在擴容節點配置時,則需要縱向擴容。
目前云上的縱向擴容方式有兩種:
第一種是滾動重啟方式擴容,這對集群穩定性會有一定的影響。
第二種是數據遷移方式擴容,其原理是先向集群中加入同等數量的高配置節點,然后將低配置節點上的數據遷移到新節點上,最后再將低配置節點剔除集群,所以這種擴容流程時間會比較長,且成本較高。
數據遷移方式縱向擴容示意圖
集群規模評估主要根據以下三點來評估:
具體的業務場景,如日志分析、指標監控、搜索業務;
業務預計的查詢及寫入QPS;
索引的數據總量。
這里結合我們的運維經驗,給出集群規模評估的幾點參考建議:
32C64G單節點配置通常可承載5W次/s的寫入;
寫入量和數據量較大時,優先選擇32C64G的節點配置;
1T的數據量預計需消耗2-4GB的內存空間;
搜索場景優先選擇大內存節點配置;
存儲容量 = 源數據 * (1 + 副本數量) * 1.45 * (1 + 預留空間) ≈ 源數據 * (1 + 副本數量) * 2.2.
索引配置的評估主要評估兩點:
第一,如何劃分索引?
在使用 index 時,建議做好定期切換索引的計劃。對于日志場景來說,寫入不大的情況下建議按天創建索引,而寫入較大的情況下,則建議按小時創建索引。
定期滾動索引的好處主要包括:能夠控制單個索引的大小,提升讀寫性能;同時能夠方式單個索引太大,影響故障恢復的時間;另外也能避免熱索引過大,從而影響快照備份恢復的時間。
第二,如何設置索引主分片數?
云上的索引主分片數默認是5個,具體的大小則需要業務根據具體的場景及數據量來優化。下面會給出具體的一些準則和經驗。
索引配置的評估同樣也要結合具體的業務場景及索引的數據量來評估,尤其是單日新增的數據量。
索引配置的評估可根據下面幾點準則進行評估:
單個分片大小控制在 30-50GB;
集群總分片數量控制在 3w 以內;
1GB 的內存空間支持 20-30 個分片為佳;
一個節點建議不超過 1000 個分片;
索引分片數量建議和節點數量保持一致;
集群規模較大時建議設置專用主節點;
專用主節點配置建議在 8C16G 以上;
如果是時序數據,建議結合冷熱分離+ILM 索引生命周期管理。
特別需要說明的是集群分片總數的大小控制上,我們經過一些性能測試發現:當集群的總分片數超過 10w 個以后,創建索引時間會增長到分鐘級。
尤其是對于寫入量在百萬 qps 以上的集群,如果總分片數在 10W+,且索引是自動創建的,那么就經常會在每次切換新索引時候,出現寫入陡降、集群不可用的情況。
下面這張圖是云上一個 100個節點,總分片數在 11W+ 的集群。每天 8點切換新索引時,寫入直接掉0,集群不可用時間在數小時不等。
集群每天8點寫入性能受到影響
對于這種問題,我們騰訊云ES團隊也有一些非常成熟的優化方案。
其中對于每天八點切換新索引時寫入陡降的問題,可通過提前創建索引來解決,且建議使用固定的 index mapping,避免大量的 put-mapping 元數據更新操作。因為對于這種節點數量和總分片數量都很大的集群來說,更新元數據是一個非常消耗性能的操作。
對于總分片數超過 10W 的問題,這種一般在日志分析場景中較為常見,如果歷史數據不是很重要,則可定期刪除歷史索引即可。
而對于歷史數據較為重要,任何數據都不能刪除的場景,則可通過冷熱分離架構+索引生命周期管理功能,將7天之前的數據存儲到溫節點,且在索引數據從熱節點遷移到溫節點時,通過 Shrink 來將主分片個數降低到一個較小的值,并且可將溫節點數據通過快照方式備份到騰訊云COS中,然后將溫節點上索引的副本設置為0,這樣便可進一步降低集群中的總分片數量。
冷熱分離+ILM+COS備份集群架構
ES集群的寫入性能受到很多因素的影響,下面是一些寫入性能方面的優化建議:
索引中每一個 doc 都有一個全局唯一的 doc_id,這個 doc_id 可自定義,也可以讓ES自動生成。
如果自定義的話,則ES在寫入過程中會多一步判斷的過程,即先Get下該 doc_id 是否已經存在。如果存在的話則執行 Update 操作,不存在則創建新的 doc。
因此如果我們對索引 doc_id 沒有特別要求,則建議讓ES自動生成 doc_id,這樣可提升一定的寫入性能。
這一條優化建議在上面也提到了,因為創建索引及新加字段都是更新元數據操作,需要 master 節點將新版本的元數據同步到所有節點。
因此在集群規模比較大,寫入qps較高的場景下,特別容易出現master更新元數據超時的問題,這可導致 master 節點中有大量的 pending_tasks 任務堆積,從而造成集群不可用,甚至出現集群無主的情況。
更新集群元數據超時
集群大量pending_tasks任務堆積
ES默認的 refresh_interval 是1s,即 doc 寫入1s后即可被搜索到。
如果業務對數據實時性要求不高的話,如日志場景,可將索引模版的 refresh_interval 設置成30s,這能夠避免過多的小 segment 文件的生成及段合并的操作。
越來越多的外部客戶正選擇將自建的ES集群遷移到騰訊云上來,客戶通常是使用 logstash 來遷移數據,由于自建集群中完整保留了數據,因此這時候可以將云上的正在寫入的索引副本設置為0, 這樣可最快完成集群遷移工作。數據遷移完成后再將副本打開即可。
ES為了提升寫入性能,提供了 Bulk 批量寫入的API,通常客戶端會準備好一批數據往ES中寫入,ES收到 Bulk 請求后則根據routing 值進行分發,將該批數據組裝成若干分子集,然后異步得發送給各分片所在的節點。
這樣能夠大大降低寫入請求時的網絡交互和延遲。通常我們建議一次Bulk的數據量控制在10M以下,一次Bulk的doc數在 10000 上下浮動。
ES Bulk請求示意圖
上面我們提到ES提供了Bulk接口支持將數據批量寫入到索引,雖然協調節點是異步得將數據發送給所有的分片,但是卻需要等待所有的分片響應后才能返回給客戶端,因此一次Bulk的延遲則取決于響應最慢的那個分片所在的節點。這就是分布式系統的長尾效應。
因此,我們可以自定義 routing 值,將一次Bulk盡量轉發到較少的分片上。
POST _bulk?routing=user_id
自定義routing
云上目前提供多種類型的磁盤可用選擇,其中1T的 SSD 云盤吞吐量為 260M/s,高性能云盤為 150M/s。因此使用SSD磁盤對于寫入性能和IO性能都會有一定的提升。
另外騰訊云現在也提供了多盤的能力,相對于單盤節點來說,3塊盤的吞吐量大約有2.8倍的提升。
我們知道ES的索引有三種狀態,分別是 Open狀態、Frozen狀態和 Close狀態。如下圖所示:
ES索引的三種狀態
Open狀態的索引由于是通過將倒排索引以FST數據結構的方式加載進內存中,因此索引是能夠被快速搜索的,且搜索速度也是最快的。
但是需要消耗大量的內存空間,且這部分內存為常駐內存,不會被GC的。1T的索引預計需要消耗2-4GB的JVM堆內存空間。
Frozen狀態的索引特點是可被搜索,但是由于它不占用內存,只是存儲在磁盤上,因此凍結索引的搜索速度是相對比較慢的。如果我們集群中的數據量比較大,歷史數據也不能被刪除,則可以考慮使用下面的API將歷史索引凍結起來,這樣便可釋放出較多的內存空間。
POST /index_name/_freeze
對于凍結索引的搜索,可以在API中指定 ignore_throttled=false 參數:
GET /index_name/_search?ignore_throttled=false { "query": { "match": { "name": "wurong" } } }
上面介紹了一些較為常見的寫入性能優化的建議和經驗,但是更為高效的優化還需要結合具體的業務場景和集群規模。
ES集群的健康狀態分為三種,分別是Green、Yellow和Red。
Green(綠色):全部主&副本分片分配成功;
Yellow(黃色):至少有一個副本分片未分配成功;
Red(紅色):至少有一個主分片未分配成功。
我們可以通過下面的API來查詢集群的健康狀態及未分配的分片個數:
GET _cluster/health { "cluster_name": "es-xxxxxxx", "status": "yellow", "timed_out": false, "number_of_nodes": 103, "number_of_data_nodes": 100, "active_primary_shards": 4610, "active_shards": 9212, "relocating_shards": 0, "initializing_shards": 0, "unassigned_shards": 8, "delayed_unassigned_shards": 0, "number_of_pending_tasks": 0, "number_of_in_flight_fetch": 0, "task_max_waiting_in_queue_millis": 0, "active_shards_percent_as_number": 99.91323210412148 }
其中需要重點關注的幾個字段有 status、number_of_nodes、unassigned_shards 和 number_of_pending_tasks。
number_of_pending_tasks 這個字段如果很高的話,通常是由于 master 節點觸發的元數據更新操作,部分節點響應超時導致的大量的任務堆積。
我們可以通過下面的API來查看具體有那些 task 需要執行:
GET /_cat/pending_tasks insertOrder timeInQueue priority source 1685 855ms HIGH update-mapping [foo][t] 1686 843ms HIGH update-mapping [foo][t] 1693 753ms HIGH refresh-mapping [foo][[t]] 1688 816ms HIGH update-mapping [foo][t]
其中 priority 字段則表示該 task 的優先級,翻看 ES 的源碼可以看到一共有六種優先級:
IMMEDIATE((byte) 0), URGENT((byte) 1), HIGH((byte) 2), NORMAL((byte) 3), LOW((byte) 4), LANGUID((byte) 5);
當集群Red時候,我們可以通過下面的API來查看分片未分配的原因:
GET _cluster/allocation/explain
查看分片未分配的原因
其中 index和shard 列出了具體哪個索引的哪個分片未分配成功。reason 字段則列出了哪種原因導致的分片未分配。這里也將所有可能的原因列出來:
INDEX_CREATED:由于創建索引的API導致未分配。 CLUSTER_RECOVERED :由于完全集群恢復導致未分配。 INDEX_REOPENED :由于打開open或關閉close一個索引導致未分配。 DANGLING_INDEX_IMPORTED :由于導入dangling索引的結果導致未分配。 NEW_INDEX_RESTORED :由于恢復到新索引導致未分配。 EXISTING_INDEX_RESTORED :由于恢復到已關閉的索引導致未分配。 REPLICA_ADDED:由于顯式添加副本分片導致未分配。 ALLOCATION_FAILED :由于分片分配失敗導致未分配。 NODE_LEFT :由于承載該分片的節點離開集群導致未分配。 REINITIALIZED :由于當分片從開始移動到初始化時導致未分配(例如,使用影子shadow副本分片)。 REROUTE_CANCELLED :作為顯式取消重新路由命令的結果取消分配。 REALLOCATED_REPLICA :確定更好的副本位置被標定使用,導致現有的副本分配被取消,出現未分配。
detail 字段則列出了更為詳細的未分配的原因。下面我會總結下在日常運維工作中常見的幾種原因。
如果未分配的分片比較多的話,我們也可以通過下面的API來列出所有未分配的索引和主分片:
GET /_cat/indices?v&health=red
the node is above the high watermark cluster setting [cluster.routing.allocation.disk.watermark.high=95%], using more disk space than the maximum allowed [95.0%], actual free: [4.055101177689788%]
當我們執行 _cluster/allocation/explain 命令后看到上面的一行語句的話,則可以判斷是該索引主分片所在的節點磁盤滿了。
解決方法:擴容磁盤提升磁盤容量或者刪除歷史數據釋放磁盤空間。
通常如果磁盤滿了,ES為了保證集群的穩定性,會將該節點上所有的索引設置為只讀。ES 7.x版本之后當磁盤空間提升后可自動解除,但是7.x版本之前則需要手動執行下面的API來解除只讀模式:
PUT index_name/_settings { "index": { "blocks": { "read_only_allow_delete": null } } }
failure IllegalArgumentException[number of documents in the index cannot exceed 2147483519
該限制是分片維度而不是索引維度的。因此出現這種異常,通常是由于我們的索引分片設置的不是很合理。
解決方法:切換寫入到新索引,并修改索引模版,合理設置主分片數。
cannot allocate because a previous copy of the primary shard existed but can no longer be found on the nodes in the cluster
這種情況通常是由于某個節點故障或者由于負載較高導致的掉線。
解決方法:找到節點掉線原因并重新啟動節點加入集群,等待分片恢復。
node does not match index setting [index.routing.allocation.require] filters [temperature:\"warm\",_id:\"comdNq4ZSd2Y6ycB9Oubsg\"]
解決方法:重新設置索引所需的屬性,和節點保持一致。因為如果重新設置節點屬性,則需要重啟節點,代價較高。
例如通過下面的API來修改索引所需要分配節點的溫度屬性:
PUT /index_name/_settings { "index": { "routing": { "allocation": { "require": { "temperature": "warm" } } } } }
cannot allocate because all found copies of the shard are either stale or corrupt
解決方法:通過reroute API來重新分配一個主分片:
POST _cluster/reroute?pretty" -d '{ "commands" : [ { "allocate_stale_primary" : { "index" : "article", "shard" : 1, "node" : "98365000222032", "accept_data_loss": true } } ] }
reached the limit of incoming shard recoveries [2], cluster setting [cluster.routing.allocation.node_concurrent_incoming_recoveries=2] (can also be set via [cluster.routing.allocation.node_concurrent_recoveries])
這種情況通常出現在集群重啟,或者某一個節點重啟后。且由于設置的分片并發恢復的值較低導致。為了盡快恢復集群健康狀態。
解決方法:可以通過調用下面的API來提升分片恢復的速度和并發度:
PUT /_cluster/settings { "transient" : { "cluster.routing.allocation.node_concurrent_recoveries": "20", "indices.recovery.max_bytes_per_sec": "100mb" } }
看完上述內容,你們對如何進行Elasticsearch集群規劃及性能優化實踐有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。