一. Elasticsearch 集群健康狀態(tài)
一個(gè) Elasticsearch 集群至少包括一個(gè)節(jié)點(diǎn)和一個(gè)索引。或者它 可能有一百個(gè)數(shù)據(jù)節(jié)點(diǎn)、三個(gè)單獨(dú)的主節(jié)點(diǎn),以及一小打客戶端節(jié)點(diǎn)——這些共同操作一千個(gè)索引(以及上萬個(gè)分片)。但是不管集群擴(kuò)展到多大規(guī)模,你都會(huì)想要一個(gè)快速獲取集群狀態(tài)的途徑。Cluster Health API 充當(dāng)?shù)木褪沁@個(gè)角色。你可以把它想象成是在一萬英尺的高度鳥瞰集群。它可以告訴你安心吧一切都好,或者警告你集群某個(gè)地方有問題。Elasticsearch 里其他 API 一樣,cluster-health 會(huì)返回一個(gè) JSON 響應(yīng)。這對(duì)自動(dòng)化和告警系統(tǒng)來說,非常便于解析。響應(yīng)中包含了和你集群有關(guān)的一些關(guān)鍵信息:
查看Elasticsearch健康狀態(tài) (*表示ES集群的master主節(jié)點(diǎn))
[root@elk-node03 ~]# curl -XGET 'http://10.0.8.47:9200/_cat/nodes?v'
host ip heap.percent ram.percent load node.role master name
10.0.8.47 10.0.8.47 53 85 0.16 d * elk-node03.kevin.cn
10.0.8.44 10.0.8.44 26 54 0.09 d m elk-node01.kevin.cn
10.0.8.45 10.0.8.45 71 81 0.02 d m elk-node02.kevin.cn

下面兩條shell命令都可以監(jiān)控到Elasticsearch健康狀態(tài)
[root@elk-node03 ~]# curl 10.0.8.47:9200/_cat/health
1554792912 14:55:12 kevin-elk green 3 3 4478 2239 0 0 0 0 - 100.0%
[root@elk-node03 ~]# curl -X GET 'http://10.0.8.47:9200/_cluster/health?pretty'
{
cluster_name : kevin-elk, #集群名稱
status : green, #為 green 則代表健康沒問題,如果是 yellow 或者 red 則是集群有問題
timed_out : false, #是否有超時(shí)
number_of_nodes : 3, #集群中的節(jié)點(diǎn)數(shù)量
number_of_data_nodes : 3,
active_primary_shards : 2234,
active_shards : 4468,
relocating_shards : 0,
initializing_shards : 0,
unassigned_shards : 0,
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 : 100.0 #集群分片的可用性百分比,如果為0則表示不可用
}

正常情況下,Elasticsearch 集群健康狀態(tài)分為三種:
green:最健康得狀態(tài),說明所有的分片包括備份都可用; 這種情況Elasticsearch集群所有的主分片和副本分片都已分配, Elasticsearch集群是 100% 可用的。
yellow :基本的分片可用,但是備份不可用(或者是沒有備份); 這種情況Elasticsearch集群所有的主分片已經(jīng)分片了,但至少還有一個(gè)副本是缺失的。不會(huì)有數(shù)據(jù)丟失,所以搜索結(jié)果依然是完整的。不過,你的高可用性在某種程度上被弱化。如果 更多的 分片消失,你就會(huì)丟數(shù)據(jù)了。把 yellow 想象成一個(gè)需要及時(shí)調(diào)查的警告。
red:部分的分片可用,表明分片有一部分損壞。此時(shí)執(zhí)行查詢部分?jǐn)?shù)據(jù)仍然可以查到,遇到這種情況,還是趕快解決比較好; 這種情況Elasticsearch集群至少一個(gè)主分片(以及它的全部副本)都在缺失中。這意味著你在缺少數(shù)據(jù):搜索只能返回部分?jǐn)?shù)據(jù),而分配到這個(gè)分片上的寫入請(qǐng)求會(huì)返回一個(gè)異常。
Elasticsearch 集群不健康時(shí)的排查思路
首先確保 es 主節(jié)點(diǎn)最先啟動(dòng),隨后啟動(dòng)數(shù)據(jù)節(jié)點(diǎn);
允許 selinux(非必要),關(guān)閉 iptables;
確保數(shù)據(jù)節(jié)點(diǎn)的elasticsearch配置文件正確;
系統(tǒng)最大打開文件描述符數(shù)是否夠用;
elasticsearch設(shè)置的內(nèi)存是否夠用 (ES_HEAP_SIZE內(nèi)存設(shè)置 和 indices.fielddata.cache.size上限設(shè)置);
elasticsearch的索引數(shù)量暴增 , 刪除一部分索引(尤其是不需要的索引);
二. Elasticsearch索引狀態(tài)
查看Elasticsearch 索引狀態(tài) (*表示ES集群的master主節(jié)點(diǎn))
[root@elk-node03 ~]# curl -XGET 'http://10.0.8.47:9200/_cat/indices?v'
health status index pri rep docs.count docs.deleted store.size pri.store.size
green open 10.0.61.24-vfc-intf-ent-deposit.log-2019.03.15 5 1 159 0 324.9kb 162.4kb
green open 10.0.61.24-vfc-intf-ent-login.log-2019.03.04 5 1 3247 0 3.4mb 1.6mb
green open 10.0.61.24-vfc-intf-ent-login.log-2019.03.05 5 1 1663 0 2.6mb 1.3mb
green open 10.0.61.24-vfc-intf-ent-deposit.log-2019.03.19 5 1 14 0 81.1kb 40.5kb
.................
.................

Elasticsearch 索引的健康狀態(tài)也有三種,即yellow、green、red與集群的健康狀態(tài)解釋是一樣的!
三. Elasticsearch 相關(guān)概念
- Elasticsearch集群與節(jié)點(diǎn)
節(jié)點(diǎn)(node)是你運(yùn)行的Elasticsearch實(shí)例。一個(gè)集群(cluster)是一組具有相同cluster.name的節(jié)點(diǎn)集合,它們協(xié)同工作,共享數(shù)據(jù)并提供故障轉(zhuǎn)移和擴(kuò)展功能,當(dāng)有新的節(jié)點(diǎn)加入或者刪除節(jié)點(diǎn),集群就會(huì)感知到并平衡數(shù)據(jù)。集群中一個(gè)節(jié)點(diǎn)會(huì)被選舉為主節(jié)點(diǎn)(master),它用來管理集群中的一些變更,例如新建或刪除索引、增加或移除節(jié)點(diǎn)等;當(dāng)然一個(gè)節(jié)點(diǎn)也可以組成一個(gè)集群。
- Elasticsearch節(jié)點(diǎn)通信
可以與集群中的任何節(jié)點(diǎn)通信,包括主節(jié)點(diǎn)。任何一個(gè)節(jié)點(diǎn)互相知道文檔存在于哪個(gè)節(jié)點(diǎn)上,它們可以轉(zhuǎn)發(fā)請(qǐng)求到我們需要數(shù)據(jù)所在的節(jié)點(diǎn)上。我們通信的節(jié)點(diǎn)負(fù)責(zé)收集各節(jié)點(diǎn)返回的數(shù)據(jù),最后一起返回給客戶端。這一切都由Elasticsearch透明的管理。
- Elasticsearch集群生態(tài)
1、同集群中節(jié)點(diǎn)之間可以擴(kuò)容縮容;
2、主分片的數(shù)量會(huì)在其索引創(chuàng)建完成后修正,但是副本分片的數(shù)量會(huì)隨時(shí)變化;
3、相同的分片不會(huì)放在同一個(gè)節(jié)點(diǎn)上;

Elasticsearch分片與副本分片 分片用于Elasticsearch在集群中分配數(shù)據(jù), 可以想象把分片當(dāng)作數(shù)據(jù)的容器, 文檔存儲(chǔ)在分片中,然后分片分配給你集群中的節(jié)點(diǎn)上。當(dāng)集群擴(kuò)容或縮小,Elasticsearch將會(huì)自動(dòng)在節(jié)點(diǎn)間遷移分片,以使集群保持平衡。一個(gè)分片(shard)是一個(gè)最小級(jí)別的“工作單元(worker unit)”,它只是保存索引中所有數(shù)據(jù)的一小片.我們的文檔存儲(chǔ)和被索引在分片中,但是我們的程序不知道如何直接與它們通信。取而代之的是,它們直接與索引通信.Elasticsearch中的分片分為主分片和副本分片,復(fù)制分片只是主分片的一個(gè)副本,它用于提供數(shù)據(jù)的冗余副本,在硬件故障之后提供數(shù)據(jù)保護(hù),同時(shí)服務(wù)于像搜索和檢索等只讀請(qǐng)求,主分片的數(shù)量和復(fù)制分片的數(shù)量都可以通過配置文件配置。但是主切片的數(shù)量只能在創(chuàng)建索引時(shí)定義且不能修改.相同的分片不會(huì)放在同一個(gè)節(jié)點(diǎn)上。
Elasticsearch分片算法
shard = hash(routing) % number_of_primary_shards

routing值是一個(gè)任意字符串,它默認(rèn)是_id但也可以自定義,這個(gè)routing字符串通過哈希函數(shù)生成一個(gè)數(shù)字,然后除以主切片的數(shù)量得到一個(gè)余數(shù)(remainder),余數(shù)的范圍永遠(yuǎn)是0到number_of_primary_shards - 1,這個(gè)數(shù)字就是特定文檔所在的分片。這也解釋了為什么主切片的數(shù)量只能在創(chuàng)建索引時(shí)定義且不能修改:如果主切片的數(shù)量在未來改變了,所有先前的路由值就失效了,文檔也就永遠(yuǎn)找不到了。所有的文檔API(get、index、delete、bulk、update、mget)都接收一個(gè)routing參數(shù),它用來自定義文檔到分片的映射。自定義路由值可以確保所有相關(guān)文檔.比如用戶的文章,按照用戶賬號(hào)路由,就可以實(shí)現(xiàn)屬于同一用戶的文檔被保存在同一分片上。
- Elasticsearch分片與副本交互
新建、索引和刪除請(qǐng)求都是寫(write)操作,它們必須在主分片上成功完成才能復(fù)制到相關(guān)的復(fù)制分片上,下面我們羅列在主分片和復(fù)制分片上成功新建、索引或刪除一個(gè)文檔必要的順序步驟:
1、客戶端給Node 1發(fā)送新建、索引或刪除請(qǐng)求。
2、節(jié)點(diǎn)使用文檔的_id確定文檔屬于分片0。它轉(zhuǎn)發(fā)請(qǐng)求到Node 3,分片0位于這個(gè)節(jié)點(diǎn)上。
3、Node 3在主分片上執(zhí)行請(qǐng)求,如果成功,它轉(zhuǎn)發(fā)請(qǐng)求到相應(yīng)的位于Node 1和Node 2的復(fù)制節(jié)點(diǎn)上。當(dāng)所有的復(fù)制節(jié)點(diǎn)報(bào)告成功,Node 3報(bào)告成功到請(qǐng)求的節(jié)點(diǎn),請(qǐng)求的節(jié)點(diǎn)再報(bào)告給客戶端。 客戶端接收到成功響應(yīng)的時(shí)候,文檔的修改已經(jīng)被應(yīng)用于主分片和所有的復(fù)制分片。你的修改生效了

- 查看分片狀態(tài)
[root@elk-node03 ~]# curl -X GET 'http://10.0.8.47:9200/_cluster/health?pretty'
{
cluster_name : kevin-elk,
status : green,
timed_out : false,
number_of_nodes : 3,
number_of_data_nodes : 3,
active_primary_shards : 2214,
active_shards : 4428,
relocating_shards : 0,
initializing_shards : 0,
unassigned_shards : 0,
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 : 100.0
}

這里需要注意: 如下是單點(diǎn)單節(jié)點(diǎn)部署Elasticsearch, 集群狀態(tài)可能為yellow, 因?yàn)閱吸c(diǎn)部署Elasticsearch, 默認(rèn)的分片副本數(shù)目配置為1,而相同的分片不能在一個(gè)節(jié)點(diǎn)上,所以就存在副本分片指定不明確的問題,所以顯示為yellow,可以通過在Elasticsearch集群上添加一個(gè)節(jié)點(diǎn)來解決問題,如果不想這么做,可以刪除那些指定不明確的副本分片(當(dāng)然這不是一個(gè)好辦法)但是作為測(cè)試和解決辦法還是可以嘗試的,下面試一下刪除副本分片的辦法:
[root@elk-server ~]# curl -X GET 'http://localhost:9200/_cluster/health?pretty'
{
cluster_name : elasticsearch,
status : yellow,
timed_out : false,
number_of_nodes : 1,
number_of_data_nodes : 1,
active_primary_shards : 931,
active_shards : 931,
relocating_shards : 0,
initializing_shards : 0,
unassigned_shards : 930,
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 : 50.02686727565825
}
[root@elk-server ~]# curl -XPUT http://localhost:9200/_settings -d' { number_of_replicas : 0 } '
{acknowledged:true}

這個(gè)時(shí)候再次查看集群的狀態(tài)狀態(tài)變成了green
[root@elk-server ~]# curl -X GET 'http://localhost:9200/_cluster/health?pretty'
{
cluster_name : elasticsearch,
status : green,
timed_out : false,
number_of_nodes : 1,
number_of_data_nodes : 1,
active_primary_shards : 931,
active_shards : 931,
relocating_shards : 0,
initializing_shards : 0,
unassigned_shards : 0,
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 : 100.0
}

- Elasticsearch索引的unssigned問題
如下, 訪問http://10.0.8.47:9200/_plugin/head/, 發(fā)現(xiàn)有unssigned現(xiàn)象:


?
這里的unssigned就是未分配副本分片的問題,接下來執(zhí)行settings中刪除副本分片的命令后, 這個(gè)問題就解決了:
[root@elk-node03 ~]# curl -XPUT http://10.0.8.47:9200/_settings -d' { number_of_replicas : 0 } '
{acknowledged:true}

四. Elasticsearch集群健康狀態(tài)為red現(xiàn)象的排查分析
通過Elasticsearch的Head插件訪問, 發(fā)現(xiàn)Elasticsearch集群的健康值為red, 則說明至少一個(gè)主分片分配失敗, 這將導(dǎo)致一些數(shù)據(jù)以及索引的某些部分不再可用。head插件會(huì)以不同的顏色顯示, 綠色表示最健康的狀態(tài),代表所有的主分片和副本分片都可用;黃色表示所有的主分片可用,但是部分副本分片不可用;紅色表示部分主分片不可用. (此時(shí)執(zhí)行查詢部分?jǐn)?shù)據(jù)仍然可以查到,遇到這種情況,還是趕快解決比較好)
接著查看Elasticsearch啟動(dòng)日志會(huì)發(fā)現(xiàn)集群服務(wù)超時(shí)連接的情況:
timeout notification from cluster service. timeout setting [1m], time since start [1m]

unassigned 分片問題可能的原因?
INDEX_CREATED: 由于創(chuàng)建索引的API導(dǎo)致未分配。
CLUSTER_RECOVERED: 由于完全集群恢復(fù)導(dǎo)致未分配。
INDEX_REOPENED: 由于打開open或關(guān)閉close一個(gè)索引導(dǎo)致未分配。
DANGLING_INDEX_IMPORTED: 由于導(dǎo)入dangling索引的結(jié)果導(dǎo)致未分配。
NEW_INDEX_RESTORED: 由于恢復(fù)到新索引導(dǎo)致未分配。
EXISTING_INDEX_RESTORED: 由于恢復(fù)到已關(guān)閉的索引導(dǎo)致未分配。
REPLICA_ADDED: 由于顯式添加副本分片導(dǎo)致未分配。
ALLOCATION_FAILED: 由于分片分配失敗導(dǎo)致未分配。
NODE_LEFT: 由于承載該分片的節(jié)點(diǎn)離開集群導(dǎo)致未分配。
REINITIALIZED: 由于當(dāng)分片從開始移動(dòng)到初始化時(shí)導(dǎo)致未分配(例如,使用影子shadow副本分片)。
REROUTE_CANCELLED: 作為顯式取消重新路由命令的結(jié)果取消分配。
REALLOCATED_REPLICA: 確定更好的副本位置被標(biāo)定使用,導(dǎo)致現(xiàn)有的副本分配被取消,出現(xiàn)未分配。
Elasticsearch集群狀態(tài)紅色如何排查?
癥狀:集群健康值紅色;
日志:集群服務(wù)連接超時(shí);
可能原因:集群中部分節(jié)點(diǎn)的主分片未分配。
接下來的解決方案主要圍繞:使主分片unsigned 分片完成再分配展開。
如何解決 unassigned 分片問題?
- 方案一:極端情況——這個(gè)分片數(shù)據(jù)已經(jīng)不可用,直接刪除該分片 (即刪除索引) Elasticsearch中沒有直接刪除分片的接口,除非整個(gè)節(jié)點(diǎn)數(shù)據(jù)已不再使用,刪除節(jié)點(diǎn)。
刪除索引命令curl -XDELETE http://10.0.8.44:9200/索引名

- 方案二:集群中節(jié)點(diǎn)數(shù)量 >= 集群中所有索引的最大副本數(shù)量 +1
N > = R + 1
其中:
N——集群中節(jié)點(diǎn)的數(shù)目;
R——集群中所有索引的最大副本數(shù)目。

注意事項(xiàng):當(dāng)節(jié)點(diǎn)加入和離開集群時(shí),主節(jié)點(diǎn)會(huì)自動(dòng)重新分配分片,以確保分片的多個(gè)副本不會(huì)分配給同一個(gè)節(jié)點(diǎn)。換句話說,主節(jié)點(diǎn)不會(huì)將主分片分配給與其副本相同的節(jié)點(diǎn),也不會(huì)將同一分片的兩個(gè)副本分配給同一個(gè)節(jié)點(diǎn)。如果沒有足夠的節(jié)點(diǎn)相應(yīng)地分配分片,則分片可能會(huì)處于未分配狀態(tài)。
如果Elasticsearch集群就一個(gè)節(jié)點(diǎn),即N=1;所以R=0,才能滿足公式。這樣問題就轉(zhuǎn)嫁為:
1) 添加節(jié)點(diǎn)處理,即N增大;
2) 刪除副本分片,即R置為0。
#R置為0的方式,可以通過如下命令行實(shí)現(xiàn):
[root@elk-node03 ~]# curl -XPUT http://10.0.8.47:9200/_settings -d' { number_of_replicas : 0 } '
{acknowledged:true}

- 方案三:allocate重新分配分片
如果方案二仍然未解決,可以考慮重新分配分片??赡艿脑颍?1) 節(jié)點(diǎn)在重新啟動(dòng)時(shí)可能遇到問題。正常情況下,當(dāng)一個(gè)節(jié)點(diǎn)恢復(fù)與群集的連接時(shí),它會(huì)將有關(guān)其分片的信息轉(zhuǎn)發(fā)給主節(jié)點(diǎn),然后主節(jié)點(diǎn)將這分片從“未分配”轉(zhuǎn)換為 已分配/已啟動(dòng)。
2) 當(dāng)由于某種原因 (例如節(jié)點(diǎn)的存儲(chǔ)已被損壞) 導(dǎo)致該進(jìn)程失敗時(shí),分片可能保持未分配狀態(tài)。

在這種情況下,必須決定如何繼續(xù): 嘗試讓原始節(jié)點(diǎn)恢復(fù)并重新加入集群(并且不要強(qiáng)制分配主分片); 或者強(qiáng)制使用Reroute API分配分片并重新索引缺少的數(shù)據(jù)原始數(shù)據(jù)源或備份。如果你決定分配未分配的主分片,請(qǐng)確保將allow_primary:true標(biāo)志添加到請(qǐng)求中。
Elasticsearch5.X使用腳本如下:
#!/bin/bash
NODE=YOUR NODE NAME
IFS=$'\n'
for line in $(curl -s '10.0.8.47:9200/_cat/shards' | fgrep UNASSIGNED); do
INDEX=$(echo $line | (awk '{print $1}'))
SHARD=$(echo $line | (awk '{print $2}'))
curl -XPOST '10.0.8.47:9200/_cluster/reroute' -d '{
commands: [
{
allocate_replica : {
index: '$INDEX',
shard: '$SHARD',
node: '$NODE',
allow_primary: true
}
}
]
}'
done
#Elasticsearch2.X及早期版本,只需將上面腳本中的allocate_replica改為 allocate,其他不變。

五. 案例: ELK中ElasticSearch集群狀態(tài)異常問題
[root@elk-node03 ~]# curl -XGET 'http://10.0.8.47:9200/_cat/nodes?v'
host ip heap.percent ram.percent load node.role master name
10.0.8.47 10.0.8.47 31 78 0.92 d * elk-node03.kevin.cn
10.0.8.44 10.0.8.44 16 55 0.27 d m elk-node01.kevin.cn
10.0.8.45 10.0.8.45 61 78 0.11 d m elk-node02.kevin.cn

查詢集群的健康狀態(tài)(一共三種狀態(tài):green、yellow,red;其中g(shù)reen表示健康)
[root@elk-node03 ~]# curl -XGET 'http://10.0.8.47:9200/_cat/health?v'
epoch timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1554689492 10:11:32 kevin-elk red 3 3 3587 3447 0 6 5555 567 11.1m 39.2%

解決辦法:
1) 調(diào)優(yōu)集群的穩(wěn)定性
-> 增大系統(tǒng)最大打開文件描述符數(shù),即65535;
-> 關(guān)閉swap,鎖定進(jìn)程地址空間,防止內(nèi)存swap;
-> JVM調(diào)優(yōu), 增大es內(nèi)存設(shè)置, 默認(rèn)是2g (Heap Size不超過物理內(nèi)存的一半,且小于32G);
2) 定期刪除es索引或刪除不可用的索引, 比如只保留最近一個(gè)月的索引數(shù)據(jù) (可寫腳本定期執(zhí)行, 具體可參考: https://www.cnblogs.com/kevingrace/p/9994178.html);
3) 如果es主節(jié)點(diǎn)重啟, 則主節(jié)點(diǎn)在轉(zhuǎn)移到其他節(jié)點(diǎn)過程中, 分片分片也會(huì)轉(zhuǎn)移過去; 如果分片比較多, 數(shù)據(jù)量比較大, 則需要耗費(fèi)一定的時(shí)間, 在此過程中, elk集群的狀態(tài)是yellow; 查看elk集群狀態(tài), shards分片會(huì)不斷增加, unassign會(huì)不斷減少,直至unassign減到0時(shí), 表明分片已經(jīng)完全轉(zhuǎn)移到新的主節(jié)點(diǎn)上, 則此時(shí)查看elk的健康狀態(tài)就是green了;
4) 如果所有es節(jié)點(diǎn)都重啟, 則需要先啟動(dòng)一個(gè)節(jié)點(diǎn)作為master主節(jié)點(diǎn), 然后再啟動(dòng)其他節(jié)點(diǎn);

注意, 這里記錄下修改ElasticSearch的內(nèi)存配置操作 (ES_HEAP_SIZE內(nèi)存設(shè)置 和 indices.fielddata.cache.size上限設(shè)置)
先修改/etc/sysconfig/elasticsearch 文件里的ES_HEAP_SIZE參數(shù)值, 默認(rèn)為2g
[root@elk-node03 ~]# vim /etc/sysconfig/elasticsearch
.............
ES_HEAP_SIZE=8g

接著修改elasticsearch配置文件
[root@elk-node03 ~]# vim /etc/elasticsearch/elasticsearch.yml
.............
bootstrap.mlockall: true #默認(rèn)為false. 表示鎖住內(nèi)存.當(dāng)JVM進(jìn)行內(nèi)存轉(zhuǎn)換時(shí),es性能會(huì)降低, 設(shè)置此參數(shù)值為true即可鎖住內(nèi)存.

注意: 這個(gè)時(shí)候最好在elasticsearch.yml配置文件里設(shè)置下indices.fielddata.cache.size , 此參數(shù)表示控制有多少堆內(nèi)存是分配給fielddata 因?yàn)閑lasticsearch在查詢時(shí),fielddata緩存的數(shù)據(jù)越來越多造成的(默認(rèn)是不自動(dòng)清理的)
[root@elk-node03 ~]# vim /etc/elasticsearch/elasticsearch.yml
..............
indices.fielddata.cache.size: 40%

上面設(shè)置了限制fielddata 上限, 表示讓字段數(shù)據(jù)緩存的內(nèi)存大小達(dá)到heap 40% (也就是上面設(shè)置的8g的40%)的時(shí)候就起用自動(dòng)清理舊的緩存數(shù)據(jù)
然后重啟elasticsearch
[root@elk-node03 ~]# systemctl restart elasticsearch

查看啟動(dòng)的elasticsearch, 發(fā)現(xiàn)內(nèi)存已經(jīng)調(diào)整到8g了
[root@elk-node03 ~]# ps -ef|grep elasticsearch
root 7066 3032 0 16:46 pts/0 00:00:00 grep --color=auto elasticsearch
elastic+ 15586 1 22 10:33 ? 01:22:00 /bin/java -Xms8g -Xmx8g -Djava.awt.headless=true -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+HeapDumpOnOutOfMemoryError -XX:+DisableExplicitGC -Dfile.encoding=UTF-8 -Djna.nosys=true -Des.path.home=/usr/share/elasticsearch -cp /usr/share/elasticsearch/lib/elasticsearch-2.4.6.jar:/usr/share/elasticsearch/lib/* org.elasticsearch.bootstrap.Elasticsearch start -Des.pidfile=/var/run/elasticsearch/elasticsearch.pid -Des.default.path.home=/usr/share/elasticsearch -Des.default.path.logs=/var/log/elasticsearch -Des.default.path.data=/var/lib/elasticsearch -Des.default.path.conf=/etc/elasticsearch

如上, 在進(jìn)行一系列修復(fù)操作 (增大系統(tǒng)最大打開文件描述符數(shù)65535, 關(guān)閉swap,鎖定進(jìn)程地址空間,防止內(nèi)存swap, 增大ES內(nèi)存, 刪除不用或異常索引, 重啟各節(jié)點(diǎn)的ES服務(wù)) 后, 再次查看ES集群狀態(tài), 發(fā)現(xiàn)此時(shí)仍然是red狀態(tài). 這是因?yàn)閑s主節(jié)點(diǎn)重啟, 則主節(jié)點(diǎn)在轉(zhuǎn)移到其他節(jié)點(diǎn)過程中, 分片分片也會(huì)轉(zhuǎn)移過去; 如果分片比較多, 數(shù)據(jù)量比較大, 則需要耗費(fèi)一定的時(shí)間. 需要等到unassign減到0時(shí), 表明分片已經(jīng)完全轉(zhuǎn)移到新的主節(jié)點(diǎn)上, 則此時(shí)查看elk的健康狀態(tài)就是green了.
[root@elk-node02 system]# curl -XGET 'http://10.0.8.47:9200/_cat/health?v'
epoch timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1554691187 10:39:47 kevin-elk red 3 3 4460 3878 0 8 4660 935 5.7m 48.9%
[root@elk-node02 system]# curl -XGET 'http://10.0.8.47:9200/_cat/health?v'
epoch timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1554691187 10:39:47 kevin-elk red 3 3 4466 3882 0 8 4654 944 5.7m 48.9%
................
................
#等到unassign數(shù)值為0時(shí), 再次查看es狀態(tài)
[root@elk-node03 ~]# curl -XGET 'http://10.0.8.47:9200/_cat/health?v'
epoch timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1554692772 11:06:12 kevin-elk green 3 3 9118 4559 0 0 0 0 - 100.0%

如果es狀態(tài)此時(shí)還是red, 則需要找出red狀態(tài)的索引并且刪除 (這個(gè)時(shí)候的red狀態(tài)的索引應(yīng)該是少部分)
[root@elk-node02 system]# curl -XGET http://10.0.8.45:9200/_cat/indices?v|grep -w red

比如找出的red狀態(tài)的索引名為10.0.61.24-vfc-intf-ent-order.log-2019.03.04, 刪除它即可
[root@elk-node02 system]# curl -XDELETE http://10.0.8.44:9200/10.0.61.24-vfc-intf-ent-order.log-2019.03.04

需要特別注意: 如果elasticSearch集群節(jié)點(diǎn)中es數(shù)據(jù)所在的磁盤使用率超過了一定比例(比如85%), 則就會(huì)出現(xiàn)無法再為副分片分片的情況, 這也會(huì)導(dǎo)致elasticSearch集群監(jiān)控狀態(tài)也會(huì)出現(xiàn)red情況!!! 這個(gè)時(shí)候只需要增大這塊磁盤的空間, 磁盤空間夠用了, elasticSearch就會(huì)自動(dòng)恢復(fù)數(shù)據(jù)!!!
六. Elasticsearch常見錯(cuò)誤
- 錯(cuò)誤1: Exception in thread main SettingsException[Failed to load settings from [elasticsearch.yml]]; nested: ElasticsearchParseException[malformed, expected settings to start with 'object', instead was [VALUE_STRING]];
原因:elasticsearch.yml文件配置錯(cuò)誤導(dǎo)致
解決:參數(shù)與參數(shù)值(等號(hào))間需要空格
[root@elk-node03 ~]# vim /etc/elasticsearch/elasticsearch.yml
...............
#node.name:elk-node03.kevin.cn #錯(cuò)誤
node.name: elk-node03.kevin.cn #正確
#或者如下配置
#node.name =elk-node03.kevin.cn #錯(cuò)誤
#node.name = elk-node03.kevin.cn #正確

然后重啟elasticsearch服務(wù)
- 錯(cuò)誤2: org.elasticsearch.bootstrap.StartupException: java.lang.RuntimeException: can not run elasticsearch as root
原因:處于對(duì)root用戶的安全保護(hù),需要使用其他用戶組進(jìn)行授權(quán)啟動(dòng)
解決:用戶組進(jìn)行授權(quán)啟動(dòng)
[root@elk-node03 ~]# groupadd elasticsearch
[root@elk-node03 ~]# useradd elasticsearch -g elasticsearch -p elasticsearch
[root@elk-node03 ~]# chown -R elasticsearch.elasticsearch /data/es-data #給es的數(shù)據(jù)目錄授權(quán), 否則es服務(wù)啟動(dòng)報(bào)錯(cuò)
[root@elk-node03 ~]# chown -R elasticsearch.elasticsearch/var/log/elasticsearch #給es的日志目錄授權(quán), 否則es服務(wù)啟動(dòng)報(bào)錯(cuò)
#以上是yum安裝elasticsearch情況, 需要給elasticsearch的數(shù)據(jù)目錄和日志目錄授權(quán), 如果elasticsearch是編譯安裝, 則需要給它的安裝目錄也授權(quán)

接著重啟elasticsearch服務(wù)即可
- 錯(cuò)誤3: OpenJDK 64-Bit Server VM warning: INFO: os::commit_memory(0x0000000085330000, 2060255232, 0) failed; error='Cannot a ...'(errno=12);
原因:jvm要分配最大內(nèi)存超出系統(tǒng)內(nèi)存
解決:適當(dāng)調(diào)整指定jvm內(nèi)存, 編輯elasticsearch 的jvm配置文件
# vim /data/elasticsearch/config/jvm.options
-Xms8g
-Xmx8g

如果是yum安裝的elasticsearch, 則修改如下配置文件
[root@elk-node03 ~]# vim /etc/sysconfig/elasticsearch
# Heap size defaults to 256m min, 1g max #最小為1g
# Set ES_HEAP_SIZE to 50% of available RAM, but no more than 31g #設(shè)置為物理內(nèi)存的50%, 但不要操作31g
ES_HEAP_SIZE=8g

然后重啟elasticsearch服務(wù)即可。京東把 Elasticsearch 用的真牛逼!這篇推薦看下。
- 錯(cuò)誤4: ERROR: [3] bootstrap checks failed
原因:虛擬機(jī)限制用戶的執(zhí)行內(nèi)存
解決:修改安全限制配置文件 (使用root最高權(quán)限 修改安全配置 在文件末尾加入)
[root@elk-node03 ~]# vim /etc/security/limits.conf
elasticsearch hard nofile 65536
elasticsearch soft nofile 65536
* soft nproc 4096
* hard nproc 4096

修改系統(tǒng)配置文件
[3]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
[root@elk-node03 ~]# /etc/sysctl.conf #注意下面的參數(shù)值大于錯(cuò)誤提示值
vm.max_map_count = 655360

然后重啟elasticsearch服務(wù)即可
七. Elasticsearch集群監(jiān)控狀態(tài)監(jiān)控
- 通過簡(jiǎn)單shell命令監(jiān)控elasticsearch集群狀態(tài)
原理:使用curl命令模擬訪問任意一個(gè)elasticsearch集群, 就可以反饋出elasticsearch集群狀態(tài),集群的狀態(tài)需要為green。
[root@elk-node03 ~]# curl -XGET 'http://10.0.8.47:9200/_cluster/stats?human&pretty'
{
timestamp : 1554792101956,
cluster_name : kevin-elk,
status : green,
indices : {
count : 451,
shards : {
total : 4478,
primaries : 2239,
replication : 1.0,
index : {
shards : {
min : 2,
max : 10,
avg : 9.929046563192905
},
primaries : {
min : 1,
max : 5,
avg : 4.964523281596453
},
replication : {
min : 1.0,
max : 1.0,
avg : 1.0
}
}
},
docs : {
count : 10448854,
deleted : 3
},
store : {
size : 5gb,
size_in_bytes : 5467367887,
throttle_time : 0s,
throttle_time_in_millis : 0
},
fielddata : {
memory_size : 0b,
memory_size_in_bytes : 0,
evictions : 0
},
query_cache : {
memory_size : 0b,
memory_size_in_bytes : 0,
total_count : 364053,
hit_count : 0,
miss_count : 364053,
cache_size : 0,
cache_count : 0,
evictions : 0
},
completion : {
size : 0b,
size_in_bytes : 0
},
segments : {
count : 16635,
memory : 83.6mb,
memory_in_bytes : 87662804,
terms_memory : 64.5mb,
terms_memory_in_bytes : 67635408,
stored_fields_memory : 6.3mb,
stored_fields_memory_in_bytes : 6624464,
term_vectors_memory : 0b,
term_vectors_memory_in_bytes : 0,
norms_memory : 6.1mb,
norms_memory_in_bytes : 6478656,
doc_values_memory : 6.6mb,
doc_values_memory_in_bytes : 6924276,
index_writer_memory : 448.1kb,
index_writer_memory_in_bytes : 458896,
index_writer_max_memory : 4.5gb,
index_writer_max_memory_in_bytes : 4914063972,
version_map_memory : 338b,
version_map_memory_in_bytes : 338,
fixed_bit_set : 0b,
fixed_bit_set_memory_in_bytes : 0
},
percolate : {
total : 0,
time : 0s,
time_in_millis : 0,
current : 0,
memory_size_in_bytes : -1,
memory_size : -1b,
queries : 0
}
},
nodes : {
count : {
total : 3,
master_only : 0,
data_only : 0,
master_data : 3,
client : 0
},
versions : [ 2.4.6 ],
os : {
available_processors : 24,
allocated_processors : 24,
mem : {
total : 13.8gb,
total_in_bytes : 14859091968
},
names : [ {
name : Linux,
count : 3
} ]
},
process : {
cpu : {
percent : 1
},
open_file_descriptors : {
min : 9817,
max : 9920,
avg : 9866
}
},
jvm : {
max_uptime : 1.1d,
max_uptime_in_millis : 101282315,
versions : [ {
version : 1.8.0_131,
vm_name : Java HotSpot(TM) 64-Bit Server VM,
vm_version : 25.131-b11,
vm_vendor : Oracle Corporation,
count : 3
} ],
mem : {
heap_used : 7.2gb,
heap_used_in_bytes : 7800334800,
heap_max : 23.8gb,
heap_max_in_bytes : 25560612864
},
threads : 359
},
fs : {
total : 1.1tb,
total_in_bytes : 1241247670272,
free : 1tb,
free_in_bytes : 1206666141696,
available : 1tb,
available_in_bytes : 1143543336960
},
plugins : [ {
name : bigdesk,
version : master,
description : bigdesk -- Live charts and statistics for Elasticsearch cluster ,
url : /_plugin/bigdesk/,
jvm : false,
site : true
}, {
name : head,
version : master,
description : head - A web front end for an elastic search cluster,
url : /_plugin/head/,
jvm : false,
site : true
}, {
name : kopf,
version : 2.0.1,
description : kopf - simple web administration tool for Elasticsearch,
url : /_plugin/kopf/,
jvm : false,
site : true
} ]
}
}

以上監(jiān)控命令打印的集群統(tǒng)計(jì)信息包含: Elasticsearch集群的分片數(shù),文檔數(shù),存儲(chǔ)空間,緩存信息,內(nèi)存作用率,插件內(nèi)容,文件系統(tǒng)內(nèi)容,JVM 作用狀況,系統(tǒng) CPU,OS 信息,段信息。
- 利用腳本監(jiān)控elasticSearch集群健康值green yellow red狀態(tài)
[root@elk-node03 ~]# curl 10.0.8.47:9200/_cat/health
1554864073 10:41:13 qwkg-elk green 3 3 4478 2239 0 0 0 0 - 100.0%

編寫python腳本, 監(jiān)控elasticsearch的健康狀態(tài)
[root@elk-node03 ~]# vim /opt/es_health_monit.py
import commands
command = 'curl 10.0.8.47:9200/_cat/health'
(a, b) = commands.getstatusoutput(command)
status= b.split(' ')[157]
if status=='red':
healthy=0
else:
healthy=1
print healthy

手動(dòng)執(zhí)行腳本, 打印出elasticsearch健康狀態(tài)
[root@elk-node03 ~]# chmod 755 /opt/es_health_monit.py
[root@elk-node03 ~]# python /opt/es_health_monit.py

然后在腳本中結(jié)合sendemail進(jìn)行郵件報(bào)警 或者 添加到zabbix監(jiān)控里.
八. Elasticsearch配置中防止腦裂的配置
Master和DataNode未分離,導(dǎo)致集群不穩(wěn)定。
在ES集群中,節(jié)點(diǎn)分為Master、DataNode、Client等幾種角色,任何一個(gè)節(jié)點(diǎn)都可以同時(shí)具備以上所有角色,其中比較重要的角色為Master和DataNode:
Master主要管理集群信息、primary分片和replica分片信息、維護(hù)index信息。
DataNode用來存儲(chǔ)數(shù)據(jù),維護(hù)倒排索引,提供數(shù)據(jù)檢索等。
可以看到元信息都在Master上面,如果Master掛掉了,該Master含有的所有Index都無法訪問,文檔中說,為了保證Master穩(wěn)定,需要將Master和Node分離。而構(gòu)建master集群可能會(huì)產(chǎn)生一種叫做腦裂的問題,為了防止腦裂,需要設(shè)置最小master的節(jié)點(diǎn)數(shù)為eligible_master_number/2 + 1
根據(jù)以上理論,可以對(duì)集群做了如下更改,額外選取三個(gè)獨(dú)立的機(jī)器作為Master節(jié)點(diǎn),修改elasticsearch.yml配置
node.master = true
node.data = false
discovery.zen.minimum_master_nodes = 2

修改其他節(jié)點(diǎn)配置,將其設(shè)置為DataNode,最后依次重啟
node.master = false
node.data = true