文章轉載自:https://mp.weixin.qq.com/s/8nWV5b8bJyTLqSv62JdcAw
第一篇:Elasticsearch 磁盤使用率超過警戒水位線
從磁盤常見錯誤說下去
當客戶端向 Elasticsearch 寫入文檔時候報錯:
cluster_block_exception [FORBIDDEN/12/index read-only / allow delete (api)];
在 elasticsearch 的日志文件中報錯如下:
flood stage disk watermark [95%] exceeded ... all indices on this node will marked read-only
出現如上問題多半是:磁盤使用量超過警戒水位線,索引存在 read-only-allow-delete 索引塊數據。
報錯釋義
基礎認知:磁盤三個警戒水位線:
報錯表明數據節點的磁盤空間嚴重不足,並且已達到磁盤洪泛警戒水位線(磁盤使用率95%+,洪水泛濫的意思)。
為防止磁盤變滿,當節點達到洪泛警戒水位線時,Elasticsearch 會阻止向該節點的任何索引分片寫入數據,如果該數據塊影響到相關的系統索引,可能會導致 Kibana 或者其他 Elastic Stack 功能不可用。
修復指南
cat shards 驗證分片分配
要驗證分片是否正在移出受影響的節點,請使用 cat shards API。
GET _cat/shards?v=true
explain 驗證分配細節
如果分片仍然保留在節點上,請使用集群 allocation/explain API 獲取其分配狀態的說明。
GET _cluster/allocation/explain
{
"index": "my-index",
"shard": 0,
"primary": false,
"current_node": "my-node"
}
如上 API幾個參數解釋如下:
- index: 對應索引。
- shard:分片號。
- primary:是否主分片。
- current_node: 節點名稱。
四個參數需要結合業務實際進行修改。
恢復寫入,可以上調磁盤警戒水位線。
要立即恢復寫入操作,你可以暫時上調磁盤警戒水位並移除寫入塊。
如下命令行是集群層面更新設置的操作。
PUT _cluster/settings
{
"persistent": {
"cluster.routing.allocation.disk.watermark.low": "90%",
"cluster.routing.allocation.disk.watermark.high": "95%",
"cluster.routing.allocation.disk.watermark.flood_stage": "97%"
}
}
索引塊的五種不同狀態如下:
- 狀態一:index.blocks.read_only
設置為 "true"可以使索引和索引元數據只讀,"false "可以允許寫入和元數據改變。
- 狀態二:index.blocks.read_only_allow_delete
類似於index.blocks.read_only,但也允許刪除索引釋放磁盤資源。
基於磁盤的分片分配器(The disk-based shard allocator)可以自動添加和刪除index.blocks.read_only屬性的數據塊。
這里依然會引申出刪除索引文檔和刪除索引本身的區別等知識點:
(1)刪除索引文檔會出現刪除后磁盤使用率反而增加的現象,因為刪除的本質是 version 的 update;只有刪除索引才相當於物理刪除,會立即釋放磁盤空間。
(2)當 index.blocks.read_only_allow_delete 被設置為true時,刪除文檔是不允許的,僅允許刪除索引。
(3)當磁盤使用率達到洪泛警戒水位線 95% 時,Elasitcsearch 會強制所有包含分片數據的索引的數據庫設置為:index.blocks.read_only_allow_delete 屬性。
(4)當磁盤使用率低於高警戒水位線 90% 時,index.blocks.read_only_allow_delete 屬性會自動釋放。
- 狀態三:index.blocks.read
設置為 "true",代表禁止對索引進行讀操作。
- 狀態四:index.blocks.write
設置為 "true "代表禁止對索引的數據寫入操作。
與read_only不同,這個設置並不影響元數據。例如,你可以用一個 write 塊關閉一個索引,但是你不能用一個 read_only 塊關閉一個索引。
- 狀態五:index.blocks.metadata
設置為 "true "代表禁用索引元數據的讀寫。
所以,如下的設置本質上是破除磁盤洪泛警戒水位線 95% 的 index.blocks.read_only_allow_delete 的限制,讓索引繼續可以寫入數據。
個人評價:應急可以用。
PUT */_settings?expand_wildcards=all
{
"index.blocks.read_only_allow_delete": null
}
長期解決方案
作為長期解決方案,我們建議您將節點添加到受影響的數據層或升級現有節點實現節點磁盤擴容以增加磁盤空間。
比如:data_hot 熱節點爆滿,建議:
- 添加新的熱節點
- 為已有熱節點磁盤擴容。
要釋放額外的磁盤空間,你可以使用刪除索引 API 刪除不需要的索引。DELETE my-index
重置磁盤警戒水位線操作
當長期解決方案到位時,可使用如下命令行重置磁盤警戒水位線。
PUT _cluster/settings
{
"persistent": {
"cluster.routing.allocation.disk.watermark.low": null,
"cluster.routing.allocation.disk.watermark.high": null,
"cluster.routing.allocation.disk.watermark.flood_stage": null
}
}
小結
為避免磁盤使用率吃緊的問題,建議如下:
第一:“不等下雨天之前就修好屋頂”,而不是“下了雨之后應急修補屋頂”。
第二:做好磁盤使用率監控和預警操作。
第三:提前規划設置 total_shards_per_node 參數,以使得各個節點分片分配數相對均衡。
第二篇:Elasitcsearch CPU 使用率突然飆升
Elasticsearch 高CPU 使用率的內涵
Elasticsearch 使用線程池來管理並發操作的 CPU 資源。
Elasticsearch 高 CPU 使用率通常意味着一個或多個線程池不足以支撐業務需求。如果線程池資源耗盡,Elasticsearch 將拒絕與線程池相關的請求。例如,如果搜索線程池(search thread pool)耗盡,Elasticsearch 將拒絕搜索請求,直到有更多線程可用。
上圖更直觀的解釋了線程池、隊列、客戶端請求之間的關系,拿檢索線程為例:
- 當請求比較少時,線程池完全可以處理過來;
- 當前再多一些時,需要線程池隊列排隊;
- 如果請求再多,就超出了線程池和隊列的最大負載,導致異常報錯。
診斷 Elasticsearch 高 CPU 使用率
核查 CPU 使用率
使用 cat nodes API 獲取每個節點的當前 CPU 使用率。
GET _cat/nodes?v=true&s=cpu:desc
返回結果:
如上所示,CPU 即為 cpu 使用率,name 為節點的名稱。
也可以借助 Kibana Stack Monitoring 進行可視化監控,CPU 監控如下紅圈所示:
核查熱點線程
如果某個節點的 CPU 使用率很高,請使用節點熱點線程 API 檢查該節點上運行的資源密集型線程。
GET _nodes/my-node,my-other-node/hot_threads
此 API 以純文本形式返回任何熱點線程的細節。
降低 CPU 使用率的實操方案
擴展集群
繁重的數據寫入(indexing)和搜索負載會耗盡較小的線程池。為了更好地處理繁重的工作負載,向集群添加更多節點或升級(擴容)現有節點以增加容量。
分散批量請求
批量請求雖然比單個請求效率更高,但大型批量寫入或多搜索請求需要大量 CPU 資源。
如果可能,提交較小的請求並在它們之間留出更多時間。
這里的較小有多小?需要結合業務實際、結合線程池和隊列大小不斷調出最優值。
取消長時間運行的搜索
長時間運行的搜索會阻塞搜索線程池中的線程。
要檢查這些搜索,請使用任務管理 API。
GET _tasks?actions=*search&detailed
上述命令行響應的描述包含檢索請求及其查詢細節,其中:running_time_in_nanos 顯示搜索運行了多長時間。
{
"nodes" : {
"oTUltX4IQMOUUVeiohTt8A" : {
"name" : "my-node",
"transport_address" : "127.0.0.1:9300",
"host" : "127.0.0.1",
"ip" : "127.0.0.1:9300",
"tasks" : {
"oTUltX4IQMOUUVeiohTt8A:464" : {
"node" : "oTUltX4IQMOUUVeiohTt8A",
"id" : 464,
"type" : "transport",
"action" : "indices:data/read/search",
"description" : "indices[my-index], search_type[QUERY_THEN_FETCH], source[{\"query\":...}]",
"start_time_in_millis" : 4081771730000,
"running_time_in_nanos" : 13991383,
"cancellable" : true
}
}
}
}
}
可以使用 _cancel API
取消任務以釋放資源:
POST _tasks/oTUltX4IQMOUUVeiohTt8A:464/_cancel
避免耗費資源的搜索
舉例:前綴匹配的 wildcard 查詢、多重聚合或分桶設置過大的單重聚合都會非常耗費資源。
避免策略包含但不限於:
- 避免腳本 script 檢索。
- 少使用:fuzzy、regexp、prefix、wildcard檢索
- 避免將 range 檢索應用到 text 和 keyword 類型。
- 避免多表關聯 Join 類型。
- 使用 index.max_result_window 索引設置降低大小限制。
- 使用 search.max_buckets 集群設置降低允許的聚合桶的最大數量。
- 使用 search.allow_expensive_queries 集群設置禁用耗費資源的查詢。
小結
建議提前做好集群監控和指標預警工作,“防范於未然”,結合節點的 CPU 核數最大化的提升線程池和隊列的使用率。
第三篇:Elasticsearch 斷路器報錯
啥是斷路器
斷路器(circuit breakers)都指定了它可以使用內存的限制。
Elasticsearch 包含多個斷路器,用於防止操作導致內存泄露錯誤(OutOfMemoryError)。
此外,還有一個父級斷路器(parent-level breaker),規定了所有斷路器可以使用的內存總量。
如果Elasticsearch估計某項操作會導致內存使用率超過斷路器設置的上限,它會停止操作並返回錯誤。
默認情況下,父級斷路器在 JVM 內存使用率達到 95% 時觸發。為了防止錯誤,官方建議在使用率持續超過 85% 的情況下,采取措施減少內存壓力。
Elasticsearch 斷路器報錯示例
客戶端請求報 429 錯誤
如果一個請求觸發了一個斷路器,Elasticsearch會返回一個錯誤,其 HTTP 狀態代碼為429。
{
'error': {
'type': 'circuit_breaking_exception',
'reason': '[parent] Data too large, data for [<http_request>] would be [123848638/118.1mb], which is larger than the limit of [123273216/117.5mb], real usage: [120182112/114.6mb], new bytes reserved: [3666526/3.4mb]',
'bytes_wanted': 123848638,
'bytes_limit': 123273216,
'durability': 'TRANSIENT'
},
'status': 429
}
熟悉Http 協議的同學都知道:在HTTP協議中,響應狀態碼 429 Too Many Requests 表示在一定的時間內用戶發送了太多的請求,即超出了“頻次限制”。
日志報錯 Data too large
elasticsearch.log 也會記錄斷路器錯誤。例如:分片的過程中會觸發斷路器。
可能的報錯如下:
Caused by: org.elasticsearch.common.breaker.CircuitBreakingException: [parent] Data too large, data for [<transport_request>] would be [num/numGB], which is larger than the limit of [num/numGB], usages [request=0/0b, fielddata=num/numKB, in_flight_requests=num/numGB, accounting=num/numGB]
檢查JVM的內存使用情況
使用命令行查看 JVM 使用率
使用 cat nodes API 來獲得每個節點的當前堆內存使用率 heap.percent。
GET _cat/nodes?v=true&h=name,node*,heap*
返回結果如下:
name id node.role heap.current heap.percent heap.max
node-02 WCwv cdfhilmrstw 287mb 28 990.7mb
要獲得每個斷路器的 JVM 內存使用量,請使用節點統計 node stats API。
GET _nodes/stats/breaker
返回結果如下:
如何防止斷路器出錯
降低JVM的內存壓力
高的 JVM 內存壓力經常導致斷路器錯誤。可能導致 JVM 使用率暴增的原因列舉如下:
原因 1:分片大小設置不合理,存在過多小分片。
因為每個分片都會有內存的使用。官方建議分片大小 30GB-50GB之間。
原因 2:復雜的檢索或查詢操作。
舉例:wildcard 查詢、設置很大分桶數的聚合操作都是非常“吃”內存的,要避免。
原因 3:存在映射“爆炸”現象
定義太多的字段或將字段嵌套得太深,會導致使用大量內存的映射“爆炸”。
原因 4:存在大型批量請求
大型的批量索引或多重搜索請求會造成 JVM 的內存壓力。
原因 5:節點硬件資源受限
物理內存本身就很小,這種是“硬傷”,為避免后患,需要整個團隊知悉並想辦法協調解決。
避免在 text 類型字段上使用 fielddata
本質原因:需要對 text 字段進行聚合操作,默認 text 是做分詞操作的,無法實現聚合和排序,只有 fielddata:true 開啟后才可以。
但,開啟 fielddate:true 會使用大量的 JVM 內存。為了避免這種情況,建議 Elasticsearch 默認在文本字段上禁用 fielddata。
官方建議:如果你已經啟用了 fielddata 並觸發了 fielddata 斷路器,請考慮禁用它並使用關鍵字字段 keyword 代替。
清除 fieldata 緩存
如果你已經觸發了 fielddata 斷路器並且不能禁用 fielddata,需要使用清除緩存 API 來清除 fielddata 緩存。
清理緩存的命令如下:
POST _cache/clear?fielddata=true
第四篇:Elasticsearch JVM 堆內存使用率飆升
症狀:高 JVM 內存使用率
高 JVM 內存使用率會降低集群性能並觸發斷路器錯誤(導致內存熔斷)。
為了防止這種情況發生,如果節點的 JVM 內存使用率持續超過 85%,官方建議采取措施降低內存壓力。
診斷 JVM 內存壓力
檢查 JVM 內存使用情況
借助:node stats API 進行排查。
GET _nodes/stats?filter_path=nodes.*.jvm.mem.pools.old
結果如下:
{
"nodes": {
"J2-fr3wzSqqJk9cwoi2urw": {
"jvm": {
"mem": {
"pools": {
"old": {
"used_in_bytes": 179796016,
"max_in_bytes": 1798569984,
"peak_used_in_bytes": 179796016,
"peak_max_in_bytes": 1798569984
}
}
}
}
}
}
}
堆內存使用率為:used_in_bytes / max_in_bytes = 179796016/ 1798569984 = 9.996%
,接近 10%。
能和 kibana 可視化監控結果保持一致:
垃圾回收日志檢查
隨着內存使用量的增加,垃圾收集變得更加頻繁並且需要更長的時間。
你可以在 elasticsearch.log 中跟蹤垃圾收集事件的頻率和時長。
例如,以下事件表明 Elasticsearch 在過去 40 秒中花費了超過 50%(21 秒)執行垃圾收集。
[timestamp_short_interval_from_last][INFO ][o.e.m.j.JvmGcMonitorService] [node_id] [gc][number] overhead, spent [21s] collecting in the last [40s]
降低JVM 堆內存使用率方案
減少分片數
關於分片的幾點認知:
第一:搜索請求是以分片為單位發起的。
至少 7.16 版本之前是,如下圖示更能說明問題。
這暗示了什么?
必然是:分片越多,檢索越慢。
因為:跨大量分片的搜索可能會耗盡節點的搜索線程池,這可能導致吞吐量低和搜索速度慢。
第二:每個索引和分片都有內存和 CPU 開銷。
每個索引和每個分片都需要一些內存和 CPU 資源。
在大多數情況下,一小組大分片比許多小分片使用更少的資源。
為什么呢?解釋一下:
分片的底層是 Lucene 分段。
段的元數據會保留在 JVM 堆內存中,以便快速檢索。
分片越多,意味着分段會越多,進而分段元數據會越多,JVM 堆內存使用率會越高。反之,則相反。
第三:Elasticsearch 會在相同角色的節點間平衡分片。
節點角色划分是 7.x 高版本新的節點定義方式,其目的是:節點用途更明確。
當添加新節點或某節點出故障時,Elasticsearch 會自動在相同角色層的剩余節點之間重新平衡索引的分片。
關於減少分片數,更確切的是如何合理規划分片,官方建議如下:
第一:盡量避免 delete_by_query 刪除文檔,更好的方案是直接刪除索引。
第二:使用 datastrem 和 ILM 索引生命周期管理管理時序數據。
第三:分片大小控制在 10GB-50GB。
第四:控制在每 GB 堆內存 20 個分片以內。也就是說:具有 30GB 堆內存的節點最多應該有 600 個分片。
第五:避免單個節點分片過多、負載過重。如果單個節點包含太多分片,且索引量很大,則該節點可能會出現問題。
可以使用如下命令行加以控制:
PUT my_index_001/_settings
{
"index": {
"routing.allocation.total_shards_per_node": 5
}
}
避免復雜檢索
復雜搜索會占用大量的內存空間。建議啟用:慢日志進行排查。
導致內存使用率飆升的復雜查詢,通常具備如下的特點:
- size 召回值設置的巨大;
- 包含分桶值很大的聚合操作或者聚合嵌套很深;
- 包含極其耗費資源的查詢,舉例:script 查詢、fuzzy 查詢、regexp 查詢、prefix 查詢、wildcard 查詢、text 或 keyword 上的 range 查詢。
為避免復雜查詢,常規措施如下:
- 限制:index.max_result_window 的大小。
PUT _settings
{
"index.max_result_window": 5000
}
- 設置 search.max_buckets cluster 以限制分桶值大小。
PUT _cluster/settings
{
"persistent": {
"search.max_buckets": 20000,
}
}
- 設置 search.allow_expensive_queries 直接禁用耗費資源的查詢。
PUT _cluster/settings
{
"persistent": {
"search.allow_expensive_queries": false
}
}
避免 Mapping “爆炸”
定義過多的字段或嵌套過深的字段會導致使用大量內存,出現“Mapping 爆炸" 現象。
為防止“Mapping 爆炸“,使用映射限制設置來限制字段映射的數量。
PUT my_index_001/_settings
{
"index.mapping.total_fields.limit": 100
}
分散批量請求
批量請求雖然比單個請求更有效,但大批量寫入(以 bulk 操作為代表)或多搜索請求(以 _msearch 為代表)仍然會產生較高的 JVM 內存壓力。
如果可能,提交較小(小是個相對值,需要根據集群性能測算出適合自己集群的經驗值)的請求並在它們之間留出更多時間時隔。
升級節點內存
繁重的寫入操作和搜索負載過重均會導致高 JVM 內存壓力。
為了更好地處理繁重的工作負載,在其他方法都不靈的情況下,可以考慮通過為節點內存擴容以達到升級節點目的。
這是無法之法,這是萬能之法。
第五篇:Elasticsearch 出現 “429 rejected” 報錯
常見的“429拒絕請求”錯誤
線上報錯描述:
問題 1:“我們目前節點還是有很多 reject 429,用了一些方法,比如增加Thread_pool 好像效果不大,還會load增高。還是很多堆積和reject。現在想咨詢一下,是否只能增加服務器節點,如果增加,應該怎么樣評估,更加合理?因為沒有多余機器來做壓測,只能根據現有的監控數據評估,能不能給些建議,重點來看哪些參數?”
問題2:“es集群,寫入經常reject 429,同時經常會出現 request retries exceeded max retry timeout [60000] 超時的情況。想問下,一般都有什么辦法緩解這種問題。現在數據堆積kafka的很多,消費不過來,會丟失一部分數據。目前節點的thread_pool 是200,調高了部分節點到300,效果不是特別明顯。”
如上兩個問題都和 “reject 429” 錯誤緊密結合在一起。
“429 拒絕請求”原因解讀
當 Elasticsearch 拒絕請求時,它會停止操作並返回帶有 429 響應碼的錯誤。被拒絕的請求通常由以下原因引起:
原因1:線程池資源耗盡。
檢索線程池或者寫入線程池資源耗盡,會出現:TOO_MANY_REQUESTS 錯誤消息。
原因2:斷路器報錯,也就是內存出現熔斷現象。
原因3:超過限制的寫入壓力。
主要原因在於:將文檔寫入到 Elasticsearch 會以內存和 CPU 負載的形式導致系統負載升高。如果在存在過多頻繁的寫入操作,集群可能會變得飽和。這可能會對其他操作產生不利影響,例如搜索、集群協調和后台處理。
為了防止這些問題,Elasticsearch 在內部監控索引負載。當負載超過一定限度時,新的請求將會被拒絕。
寫入請求最高內存上限 indexing_pressure.memory.limit 設置為堆內存的 10%。
此外, “429 拒絕錯誤“可以作為衡量是否達到性能瓶頸的依據——做壓力測試時可以不斷增加並發,觀察CPU使用率、磁盤IO使用率,當 Elasticsearch 返回 429 錯誤碼時,可以認為 Elastic 集群達到負載極限。
如何檢查 “429 拒絕請求”錯誤
要檢查每個線程池的拒絕任務數,可以使用如下的 cat 線程池 API。被拒絕任務與已完成任務的比例很高,尤其是在搜索和寫入線程池中,這意味着 Elasticsearch 會定期拒絕請求。
執行如下命令,可以查看 rejected 拒絕情況。
GET /_cat/thread_pool?v=true&h=id,name,active,rejected,completed
如何阻止或提前預防“429 拒絕請求”錯誤
方案一:修復高CPU和高內存使用率問題。
如果 Elasticsearch 經常出現拒絕請求,則你所管理集群可能具有高 CPU 使用率或高 JVM 內存壓力。
方案二:避免出現內存熔斷。
如果你的業務環境經常觸發斷路器錯誤或者內存熔斷,請參閱斷路器錯誤以獲取有關診斷和預防錯誤的提示。
第六篇:Elasticsearch 集群狀態變成黃色或者紅色
集群健康狀態之紅色或黃色含義
紅色或黃色集群狀態表示一個或多個分片丟失或未分配。這些未分配的分片會增加數據丟失的風險,並會降低集群性能。
集群健康狀態診斷
檢測集群健康狀態
命令行方式
GET _cluster/health?filter_path=status,*_shards
可視化方式 - head 插件可視化
kibana 可視化監控
查看未分配的分片
GET _cat/shards?v=true&h=index,shard,prirep,state,node,unassigned.reason&s=state
幾個參數解釋如下:
- v=true, 代表顯示字段含義;否則首行內容不顯示。
- h=*,代表列名;
- s=state,代表基於state方式排序。等價於:s=state:asc,默認升序方式排序。
- prirep,代表分片類型。p:代表主分片;r:代表副本分片。
如上截圖代表:order_info、test_data等索引包含未分配的副本分片,這點和集群健康狀態“黃色”一致。
查看未分配的分片的原因
上面的返回結果:unassigned.reason 已經基本包含了未分配的原因。但想得到更為詳細的解釋,需要使用如下的命令。
GET _cluster/allocation/explain?filter_path=index,node_allocation_decisions.node_name,node_allocation_decisions.deciders.*
{
"index": "order_info",
"shard": 0,
"primary": false
}
上面的幾個參數解釋如下:
- index:索引名稱,建議結合前一步指定。
- shard:分片序號。從 0 開始計數。
- primary:是否主分片;true 代表是;false 代表否。
返回結果如下:
explanation 就是根本原因。如下 head 插件和 Kibana 都能看的更為明顯。
本質原因就是:只有一個節點,但是設置了副本,導致了主分片可以分片正常,副本分片無法分配。進而導致:集群健康狀態是黃色。
修復非健康集群狀態方案匯總
重新啟用分片分配
適用場景:節點重啟過或者設置過禁用分片分配,但之后忘記設置重新分配策略,Elasticsearch 將無法分配分片。
需要手動更新集群設置才可以實現重新分配。
PUT _cluster/settings
{
"persistent" : {
"cluster.routing.allocation.enable" : null
}
}
調整節點下線時分片分配控制策略
當數據節點下線或特定原因宕機導致離開集群時,分片通常會變成未分配狀態。造成這種情況的原因很多,比如:連接問題;比如:硬件故障問題等。
當這些故障解決后,下線節點重新加入集群,然后,Elasaticsearch 將自動分配之前因節點下線等原因導致的未分配的分片。
為了避免在上述問題上浪費資源,Elasticsearch 默認將分配延遲一分鍾。根據業務實際需要,比如:因升級內存而下線數據節點的場景,可以將該延時值調大。
參考命令行如下:
PUT _all/_settings
{
"settings": {
"index.unassigned.node_left.delayed_timeout": "5m"
}
}
如果已恢復節點並且不想等待延遲期,則可以調用不帶參數的集群 reroute API 來啟動分配過程。該進程在后台異步運行。
POST _cluster/reroute
分片分配設置層面修復
分片分配設置錯誤可能會導致主分片無法分配。這些設置包括但不限於:
索引層面的分片分配設置;
集群層面的分片分配設置;
集群層面的感知(awareness)分片分配設置。
為了獲取分片分配的細節設置,推薦使用如下兩個 API:
GET order_info/_settings?flat_settings=true&include_defaults=true
GET _cluster/settings?flat_settings=true&include_defaults=true
注意:
- flat_settings 標志會影響設置列表的呈現。當 flat_settings 標志為 true 時,相關設置以平面格式返回,如上圖所示。
- include_defaults 默認值是 false,如果為 true,則代表返回集群所有缺省值。
更多參數設置,推薦閱讀:https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html
減少副本設置
為了防止硬件故障,Elasticsearch 不會將副本分配給與其主分片相同的節點。
如果沒有其他數據節點可用於分配副本分片,則該副本分片保持未分配狀態。如開篇截圖的黃色集群狀態,本質就是這個原因。要解決此問題,你可以:
- 添加相同角色的數據節點。
- 通過更新 index.number_of_replicas 索引設置減少每個主分片的副本數。
為了保證集群線上業務的高可用性,建議每個主節點至少保留一個副本。
如下是集群層面的設置,設置后對整個集群生效。
PUT _settings
{
"index.number_of_replicas": 0
}
釋放或增加磁盤空間
Elasticsearch 使用 low disk watermark 低磁盤警戒水位線來確保數據節點有足夠的磁盤空間來接收分片。
默認情況下,Elasticsearch 不會將分片分配給磁盤使用率超過 85% 的節點。要檢查節點的當前磁盤空間,請使用 cat allocation API。
GET _cat/allocation?v=true&h=node,shards,disk.*
如果你的節點磁盤空間不足,你通常有如下四個細化方案:
方案 1:升級節點以增加磁盤空間。
方案 2:刪除不需要的索引以釋放空間。
(1)如果你使用 ILM 索引生命周期管理,則可以更新生命周期策略以使用可搜索快照或添加刪除階段。
(2)如果你不再需要搜索數據,可以使用快照將其歷史數據存儲在集群外。
PS:這里強調的刪除索引,delete 操作,不是刪除數據的 delete_by_query 操作,切記!
方案 3:如果你不再寫入索引,請使用強制合並 API( force merge API ) 或 ILM 的強制合並操作將其段合並為更大的段。
POST order_info/_forcemerge
方案 4:如果索引是只讀的,請使用 shrink index API 或 ILM 的 shrink action 來減少其主分片數。
PUT order_index_ext
{
"settings": {
"number_of_shards": 5,
"number_of_replicas": 0
}
}
POST order_index_ext/_bulk
{"index":{"_id":1}}
{"title":"just testing..."}
{"index":{"_id":2}}
{"title":"just testing..."}
{"index":{"_id":3}}
{"title":"just testing..."}
PUT order_index_ext/_settings
{
"index.blocks.write":"true"
}
POST order_index_ext/_shrink/order_shrink_index
方案 5:如果你的節點具有較大的磁盤容量,你可以調大低磁盤警戒水位線的值或將其設置為顯式字節值。
具體設置,參考如下:
PUT _cluster/settings
{
"persistent": {
"cluster.routing.allocation.disk.watermark.low": "30gb"
}
}
減少 JVM 堆內存壓力
分片分配需要 JVM 堆內存。高 JVM 內存壓力可能會觸發停止分片分配並使分片未分配的斷路器(出現內存熔斷現象)。
主分片丟失情況的恢復策略
如果包含主分片的節點因故障或其他原因下線,Elasticsearch 通常可以使用另一個節點上的副本替換它。
如果包含主分片的節點無法恢復或其副本不存在或無法恢復(這是比較極端的情況),則需要從快照或原始數據源重新添加丟失的數據。
僅當節點不再可能成功恢復時才使用此選項。因為:此過程分配一個空的主分片。如果節點稍后重新加入集群,Elasticsearch 將用這個較新的空分片中的數據覆蓋其主分片,從而導致數據丟失。
使用集群重新路由 reroute API 手動將未分配的主分片分配給同一角色中的另一個數據節點。將參數 accept_data_loss 設置為 true。
POST _cluster/reroute
{
"commands": [
{
"allocate_empty_primary": {
"index": "order_info",
"shard": 0,
"node": "node-1",
"accept_data_loss": "true"
}
}
]
}