搜尋引擎 Elasticsearch 最佳實踐!

2021-02-14 芋道源碼
四.  Elasticsearch集群健康狀態為red現象的排查分析五.  案例: ELK中ElasticSearch集群狀態異常問題七.  Elasticsearch集群監控狀態監控八.  Elasticsearch配置中防止腦裂的配置

之前在IDC機房環境部署了一套ELK日誌集中分析系統, 這裡簡單總結下ELK中Elasticsearch健康狀態相關問題, Elasticsearch的索引狀態和集群狀態傳達著不同的意思。

一.  Elasticsearch 集群健康狀態

一個 Elasticsearch 集群至少包括一個節點和一個索引。或者它 可能有一百個數據節點、三個單獨的主節點,以及一小打客戶端節點——這些共同操作一千個索引(以及上萬個分片)。但是不管集群擴展到多大規模,你都會想要一個快速獲取集群狀態的途徑。Cluster Health API 充當的就是這個角色。你可以把它想像成是在一萬英尺的高度鳥瞰集群。它可以告訴你安心吧一切都好,或者警告你集群某個地方有問題。Elasticsearch 裡其他 API 一樣,cluster-health 會返回一個 JSON 響應。這對自動化和告警系統來說,非常便於解析。響應中包含了和你集群有關的一些關鍵信息:

查看Elasticsearch健康狀態  (*表示ES集群的master主節點)

[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命令都可以監控到Elasticsearch健康狀態

[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,               #是否有超時
  number_of_nodes : 3,             #集群中的節點數量
  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 集群健康狀態分為三種:

green:最健康得狀態,說明所有的分片包括備份都可用; 這種情況Elasticsearch集群所有的主分片和副本分片都已分配, Elasticsearch集群是 100% 可用的。yellow :基本的分片可用,但是備份不可用(或者是沒有備份);  這種情況Elasticsearch集群所有的主分片已經分片了,但至少還有一個副本是缺失的。不會有數據丟失,所以搜索結果依然是完整的。不過,你的高可用性在某種程度上被弱化。如果 更多的 分片消失,你就會丟數據了。把 yellow 想像成一個需要及時調查的警告。red:部分的分片可用,表明分片有一部分損壞。此時執行查詢部分數據仍然可以查到,遇到這種情況,還是趕快解決比較好; 這種情況Elasticsearch集群至少一個主分片(以及它的全部副本)都在缺失中。這意味著你在缺少數據:搜索只能返回部分數據,而分配到這個分片上的寫入請求會返回一個異常。

Elasticsearch 集群不健康時的排查思路

首先確保 es 主節點最先啟動,隨後啟動數據節點;允許 selinux(非必要),關閉 iptables;確保數據節點的elasticsearch配置文件正確;elasticsearch設置的內存是否夠用 (ES_HEAP_SIZE內存設置 和 indices.fielddata.cache.size上限設置);elasticsearch的索引數量暴增 , 刪除一部分索引(尤其是不需要的索引);二.  Elasticsearch索引狀態

查看Elasticsearch 索引狀態  (*表示ES集群的master主節點)

[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 索引的健康狀態也有三種,即yellow、green、red與集群的健康狀態解釋是一樣的!

三.  Elasticsearch 相關概念

節點(node)是你運行的Elasticsearch實例。一個集群(cluster)是一組具有相同cluster.name的節點集合,它們協同工作,共享數據並提供故障轉移和擴展功能,當有新的節點加入或者刪除節點,集群就會感知到並平衡數據。集群中一個節點會被選舉為主節點(master),它用來管理集群中的一些變更,例如新建或刪除索引、增加或移除節點等;當然一個節點也可以組成一個集群。

可以與集群中的任何節點通信,包括主節點。任何一個節點互相知道文檔存在於哪個節點上,它們可以轉發請求到我們需要數據所在的節點上。我們通信的節點負責收集各節點返回的數據,最後一起返回給客戶端。這一切都由Elasticsearch透明的管理。

1、同集群中節點之間可以擴容縮容;
2、主分片的數量會在其索引創建完成後修正,但是副本分片的數量會隨時變化;
3、相同的分片不會放在同一個節點上;

Elasticsearch分片與副本分片 分片用於Elasticsearch在集群中分配數據, 可以想像把分片當作數據的容器, 文檔存儲在分片中,然後分片分配給你集群中的節點上。當集群擴容或縮小,Elasticsearch將會自動在節點間遷移分片,以使集群保持平衡。一個分片(shard)是一個最小級別的「工作單元(worker unit)」,它只是保存索引中所有數據的一小片.我們的文檔存儲和被索引在分片中,但是我們的程序不知道如何直接與它們通信。取而代之的是,它們直接與索引通信.Elasticsearch中的分片分為主分片和副本分片,複製分片只是主分片的一個副本,它用於提供數據的冗餘副本,在硬體故障之後提供數據保護,同時服務於像搜索和檢索等只讀請求,主分片的數量和複製分片的數量都可以通過配置文件配置。但是主切片的數量只能在創建索引時定義且不能修改.相同的分片不會放在同一個節點上。
shard = hash(routing) % number_of_primary_shards

routing值是一個任意字符串,它默認是_id但也可以自定義,這個routing字符串通過哈希函數生成一個數字,然後除以主切片的數量得到一個餘數(remainder),餘數的範圍永遠是0到number_of_primary_shards - 1,這個數字就是特定文檔所在的分片。這也解釋了為什麼主切片的數量只能在創建索引時定義且不能修改:如果主切片的數量在未來改變了,所有先前的路由值就失效了,文檔也就永遠找不到了。所有的文檔API(get、index、delete、bulk、update、mget)都接收一個routing參數,它用來自定義文檔到分片的映射。自定義路由值可以確保所有相關文檔.比如用戶的文章,按照用戶帳號路由,就可以實現屬於同一用戶的文檔被保存在同一分片上。

新建、索引和刪除請求都是寫(write)操作,它們必須在主分片上成功完成才能複製到相關的複製分片上,下面我們羅列在主分片和複製分片上成功新建、索引或刪除一個文檔必要的順序步驟:

1、客戶端給Node 1發送新建、索引或刪除請求。
2、節點使用文檔的_id確定文檔屬於分片0。它轉發請求到Node 3,分片0位於這個節點上。
3、Node 3在主分片上執行請求,如果成功,它轉發請求到相應的位於Node 1和Node 2的複製節點上。當所有的複製節點報告成功,Node 3報告成功到請求的節點,請求的節點再報告給客戶端。 客戶端接收到成功響應的時候,文檔的修改已經被應用於主分片和所有的複製分片。你的修改生效了

[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
}

這裡需要注意: 如下是單點單節點部署Elasticsearch, 集群狀態可能為yellow, 因為單點部署Elasticsearch, 默認的分片副本數目配置為1,而相同的分片不能在一個節點上,所以就存在副本分片指定不明確的問題,所以顯示為yellow,可以通過在Elasticsearch集群上添加一個節點來解決問題,如果不想這麼做,可以刪除那些指定不明確的副本分片(當然這不是一個好辦法)但是作為測試和解決辦法還是可以嘗試的,下面試一下刪除副本分片的辦法:

[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}

這個時候再次查看集群的狀態狀態變成了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/, 發現有unssigned現象:

這裡的unssigned就是未分配副本分片的問題,接下來執行settings中刪除副本分片的命令後, 這個問題就解決了:

[root@elk-node03 ~]# curl -XPUT http://10.0.8.47:9200/_settings -d' {  number_of_replicas : 0 } '
{acknowledged:true}

四.  Elasticsearch集群健康狀態為red現象的排查分析

通過Elasticsearch的Head插件訪問, 發現Elasticsearch集群的健康值為red, 則說明至少一個主分片分配失敗, 這將導致一些數據以及索引的某些部分不再可用。head插件會以不同的顏色顯示, 綠色表示最健康的狀態,代表所有的主分片和副本分片都可用;黃色表示所有的主分片可用,但是部分副本分片不可用;紅色表示部分主分片不可用. (此時執行查詢部分數據仍然可以查到,遇到這種情況,還是趕快解決比較好)

接著查看Elasticsearch啟動日誌會發現集群服務超時連接的情況:

timeout notification from cluster service. timeout setting [1m], time since start [1m]

unassigned 分片問題可能的原因?

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:  確定更好的副本位置被標定使用,導致現有的副本分配被取消,出現未分配。

Elasticsearch集群狀態紅色如何排查?

接下來的解決方案主要圍繞:使主分片unsigned 分片完成再分配展開。

如何解決 unassigned 分片問題?

方案一:極端情況——這個分片數據已經不可用,直接刪除該分片 (即刪除索引) Elasticsearch中沒有直接刪除分片的接口,除非整個節點數據已不再使用,刪除節點。
刪除索引命令curl -XDELETE  http://10.0.8.44:9200/索引名

方案二:集群中節點數量 >= 集群中所有索引的最大副本數量 +1
N > = R + 1
其中:
N——集群中節點的數目;
R——集群中所有索引的最大副本數目。

注意事項:當節點加入和離開集群時,主節點會自動重新分配分片,以確保分片的多個副本不會分配給同一個節點。換句話說,主節點不會將主分片分配給與其副本相同的節點,也不會將同一分片的兩個副本分配給同一個節點。如果沒有足夠的節點相應地分配分片,則分片可能會處於未分配狀態。

如果Elasticsearch集群就一個節點,即N=1;所以R=0,才能滿足公式。這樣問題就轉嫁為:

1) 添加節點處理,即N增大;
2) 刪除副本分片,即R置為0。

#R置為0的方式,可以通過如下命令行實現:
[root@elk-node03 ~]# curl -XPUT http://10.0.8.47:9200/_settings -d' {  number_of_replicas : 0 } '
{acknowledged:true}

如果方案二仍然未解決,可以考慮重新分配分片。可能的原因:
1) 節點在重新啟動時可能遇到問題。正常情況下,當一個節點恢復與群集的連接時,它會將有關其分片的信息轉發給主節點,然後主節點將這分片從「未分配」轉換為 已分配/已啟動。
2) 當由於某種原因 (例如節點的存儲已被損壞) 導致該進程失敗時,分片可能保持未分配狀態。

在這種情況下,必須決定如何繼續: 嘗試讓原始節點恢復並重新加入集群(並且不要強制分配主分片);  或者強制使用Reroute API分配分片並重新索引缺少的數據原始數據源或備份。如果你決定分配未分配的主分片,請確保將allow_primary:true標誌添加到請求中。

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集群狀態異常問題

線上環境部署的ELK日誌集中分析系統, 過了一段時間後, 發現Kibana展示裡沒有日誌, 查看head插件索引情況, 發現一直打不開! 這是因為如果不對es索引定期做處理, 則隨著日誌收集數據量的不斷增大, es內存消耗不斷增量, 索引數量也會隨之暴增, 那麼elk就會出現問題, 比如elk頁面展示超時, 訪問http://10.0.8.47:9200/_plugin/head/ 一直卡頓等; es集群狀態異常(出現red的status)等!

在任意一個node節點上執行下面命令查看es集群狀態 (url裡的ip地址可以是三個node中的任意一個), 如下可知, es集群當前master節點是10.0.8.47

[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

查詢集群的健康狀態(一共三種狀態:green、yellow,red;其中green表示健康)

[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) 調優集群的穩定性
-> 增大系統最大打開文件描述符數,即65535;
-> 關閉swap,鎖定進程地址空間,防止內存swap;
-> JVM調優, 增大es內存設置, 默認是2g (Heap Size不超過物理內存的一半,且小於32G);
2) 定期刪除es索引或刪除不可用的索引, 比如只保留最近一個月的索引數據 (可寫腳本定期執行, 具體可參考: https://www.cnblogs.com/kevingrace/p/9994178.html);
3) 如果es主節點重啟, 則主節點在轉移到其他節點過程中, 分片分片也會轉移過去; 如果分片比較多, 數據量比較大, 則需要耗費一定的時間, 在此過程中, elk集群的狀態是yellow; 查看elk集群狀態, shards分片會不斷增加, unassign會不斷減少,直至unassign減到0時, 表明分片已經完全轉移到新的主節點上, 則此時查看elk的健康狀態就是green了;
4) 如果所有es節點都重啟, 則需要先啟動一個節點作為master主節點, 然後再啟動其他節點;

注意, 這裡記錄下修改ElasticSearch的內存配置操作 (ES_HEAP_SIZE內存設置 和 indices.fielddata.cache.size上限設置)

先修改/etc/sysconfig/elasticsearch 文件裡的ES_HEAP_SIZE參數值, 默認為2g
[root@elk-node03 ~]# vim /etc/sysconfig/elasticsearch
...
ES_HEAP_SIZE=8g

接著修改elasticsearch配置文件

[root@elk-node03 ~]# vim /etc/elasticsearch/elasticsearch.yml
...
bootstrap.mlockall: true     #默認為false. 表示鎖住內存.當JVM進行內存轉換時,es性能會降低, 設置此參數值為true即可鎖住內存.

注意: 這個時候最好在elasticsearch.yml配置文件裡設置下indices.fielddata.cache.size , 此參數表示控制有多少堆內存是分配給fielddata 因為elasticsearch在查詢時,fielddata緩存的數據越來越多造成的(默認是不自動清理的)

[root@elk-node03 ~]# vim /etc/elasticsearch/elasticsearch.yml
....
indices.fielddata.cache.size: 40%

上面設置了限制fielddata 上限, 表示讓欄位數據緩存的內存大小達到heap 40% (也就是上面設置的8g的40%)的時候就起用自動清理舊的緩存數據

然後重啟elasticsearch

[root@elk-node03 ~]# systemctl restart elasticsearch

查看啟動的elasticsearch, 發現內存已經調整到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

如上, 在進行一系列修復操作 (增大系統最大打開文件描述符數65535, 關閉swap,鎖定進程地址空間,防止內存swap, 增大ES內存, 刪除不用或異常索引, 重啟各節點的ES服務) 後, 再次查看ES集群狀態, 發現此時仍然是red狀態. 這是因為es主節點重啟, 則主節點在轉移到其他節點過程中, 分片分片也會轉移過去; 如果分片比較多, 數據量比較大, 則需要耗費一定的時間. 需要等到unassign減到0時, 表明分片已經完全轉移到新的主節點上, 則此時查看elk的健康狀態就是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數值為0時, 再次查看es狀態
[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狀態此時還是red, 則需要找出red狀態的索引並且刪除 (這個時候的red狀態的索引應該是少部分)

[root@elk-node02 system]# curl -XGET   http://10.0.8.45:9200/_cat/indices?v|grep -w red

比如找出的red狀態的索引名為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集群節點中es數據所在的磁碟使用率超過了一定比例(比如85%), 則就會出現無法再為副分片分片的情況, 這也會導致elasticSearch集群監控狀態也會出現red情況!!!  這個時候只需要增大這塊磁碟的空間, 磁碟空間夠用了, elasticSearch就會自動恢復數據!!!

六.  Elasticsearch常見錯誤錯誤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文件配置錯誤導致

解決:參數與參數值(等號)間需要空格

[root@elk-node03 ~]# vim /etc/elasticsearch/elasticsearch.yml

#node.name:elk-node03.kevin.cn         #錯誤
node.name: elk-node03.kevin.cn           #正確

#或者如下配置
#node.name =elk-node03.kevin.cn    #錯誤
#node.name = elk-node03.kevin.cn   #正確

然後重啟elasticsearch服務

錯誤2: org.elasticsearch.bootstrap.StartupException: java.lang.RuntimeException: can not run elasticsearch as root

原因:處於對root用戶的安全保護,需要使用其他用戶組進行授權啟動

解決:用戶組進行授權啟動

[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的數據目錄授權, 否則es服務啟動報錯
[root@elk-node03 ~]# chown -R elasticsearch.elasticsearch/var/log/elasticsearch     #給es的日誌目錄授權, 否則es服務啟動報錯

#以上是yum安裝elasticsearch情況, 需要給elasticsearch的數據目錄和日誌目錄授權, 如果elasticsearch是編譯安裝, 則需要給它的安裝目錄也授權

接著重啟elasticsearch服務即可

錯誤3: OpenJDK 64-Bit Server VM warning: INFO: os::commit_memory(0x0000000085330000, 2060255232, 0) failed; error='Cannot a ...'(errno=12);

原因:jvm要分配最大內存超出系統內存

解決:適當調整指定jvm內存, 編輯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     #設置為物理內存的50%, 但不要操作31g
ES_HEAP_SIZE=8g

然後重啟elasticsearch服務即可。

錯誤4: ERROR: [3] bootstrap checks failed

原因:虛擬機限制用戶的執行內存

解決:修改安全限制配置文件 (使用root最高權限 修改安全配置 在文件末尾加入)

[root@elk-node03 ~]# vim /etc/security/limits.conf
elasticsearch       hard        nofile        65536
elasticsearch       soft        nofile        65536
*               soft       nproc         4096
*               hard      nproc          4096

修改系統配置文件

[3]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

[root@elk-node03 ~]# /etc/sysctl.conf        #注意下面的參數值大於錯誤提示值
vm.max_map_count = 655360

然後重啟elasticsearch服務即可

七.  Elasticsearch集群監控狀態監控通過簡單shell命令監控elasticsearch集群狀態

原理:使用curl命令模擬訪問任意一個elasticsearch集群, 就可以反饋出elasticsearch集群狀態,集群的狀態需要為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
    } ]
  }
}

以上監控命令列印的集群統計信息包含: Elasticsearch集群的分片數,文檔數,存儲空間,緩存信息,內存作用率,插件內容,文件系統內容,JVM 作用狀況,系統 CPU,OS 信息,段信息。

利用腳本監控elasticSearch集群健康值green yellow red狀態
[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腳本, 監控elasticsearch的健康狀態

[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

手動執行腳本, 列印出elasticsearch健康狀態

[root@elk-node03 ~]# chmod 755 /opt/es_health_monit.py
[root@elk-node03 ~]# python /opt/es_health_monit.py

然後在腳本中結合sendemail進行郵件報警 或者 添加到zabbix監控裡.

八.  Elasticsearch配置中防止腦裂的配置

Master和DataNode未分離,導致集群不穩定。

在ES集群中,節點分為Master、DataNode、Client等幾種角色,任何一個節點都可以同時具備以上所有角色,其中比較重要的角色為Master和DataNode:

Master主要管理集群信息、primary分片和replica分片信息、維護index信息。DataNode用來存儲數據,維護倒排索引,提供數據檢索等。

可以看到元信息都在Master上面,如果Master掛掉了,該Master含有的所有Index都無法訪問,文檔中說,為了保證Master穩定,需要將Master和Node分離。而構建master集群可能會產生一種叫做腦裂的問題,為了防止腦裂,需要設置最小master的節點數為eligible_master_number/2 + 1

腦裂的概念:如果有兩個Master候選節點,並設置最小Master節點數為1,則當網絡抖動或偶然斷開時,兩個Master都會認為另一個Master掛掉了,它們都被選舉為主Master,則此時集群中存在兩個主Master,即物理上一個集群變成了邏輯上的兩個集群,而當其中一個Master再次掛掉時,即便它恢復後回到了原有的集群,在它作為主Master期間寫入的數據都會丟失,因為它上面維護了Index信息。

根據以上理論,可以對集群做了如下更改,額外選取三個獨立的機器作為Master節點,修改elasticsearch.yml配置

node.master = true
node.data = false
discovery.zen.minimum_master_nodes = 2

修改其他節點配置,將其設置為DataNode,最後依次重啟

node.master = false
node.data = true

相關焦點

  • 全文搜尋引擎 Elasticsearch 入門
    如有好文章投稿,請點擊 → 這裡了解詳情全文搜索屬於最常見的需求,開源的 Elasticsearch (以下簡稱 Elastic)是目前全文搜尋引擎的首選。 $ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.5.1.zip $ unzip elasticsearch-5.5.1.zip $ cd elasticsearch-5.5.1/ 接著,進入解壓後的目錄,運行下面的命令,啟動 Elastic
  • 全文搜尋引擎 Elasticsearch 入門教程
    如有好文章投稿,請點擊 → 這裡了解詳情全文搜索屬於最常見的需求,開源的 Elasticsearch (以下簡稱 Elastic)是目前全文搜尋引擎的首選。 $ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.5.1.zip $ unzip elasticsearch-5.5.1.zip $ cd elasticsearch-5.5.1/ 接著,進入解壓後的目錄,運行下面的命令,啟動 Elastic
  • ElasticSearch安裝
    它提供了一個分布式多用戶能力的全文搜尋引擎[2],基於RESTful web接口。Elasticsearch是用Java語言開發的,並作為Apache許可條款下的開放源碼發布,是一種流行的企業級搜尋引擎。Elasticsearch用於雲計算[3]中,能夠達到實時搜索,穩定,可靠,快速,安裝使用方便。
  • 全文搜尋引擎 Elasticsearch 集群搭建入門教程
    它提供了一個分布式多用戶能力的全文搜尋引擎,基於 RESTful web 接口。Elasticsearch 是用 Java 開發的,並作為 Apache 許可條款下的開放源碼發布,是當前流行的企業級搜尋引擎。設計用於雲計算中,能夠達到實時搜索,穩定,可靠,快速,安裝使用方便。基百科、Stack Overflow、Github 都採用它。
  • Linxu安裝ElasticSearch
    它提供了一個分布式多用戶能力的全文搜尋引擎,基於RESTful web接口。Elasticsearch是用Java語言開發的,並作為Apache許可條款下的開放源碼發布,是一種流行的企業級搜尋引擎。Elasticsearch用於雲計算中,能夠達到實時搜索,穩定,可靠,快速,安裝使用方便。
  • spring data系列之elasticsearch
    上傳文件並解壓        rz   elasticsearch-5.6.8.tar.gz        tar -zxvfelasticserach-5.6.8.tar.gz4.         ik_smart :會做最粗粒度的拆分,比如會將「中華人民共和國人民大會堂」拆分為中 華人民共和國、人民大會堂        兩種分詞器使用的最佳實踐是:索引時用ik_max_word,在搜索時用ik_smart。即:索引時最大化的將文章內容分詞,搜索時更精確的搜索到想要的結果。
  • elasticsearch入門實戰
    1.介紹Elasticsearch 是一個高度可擴展的開源全文搜索和分析引擎。
  • Elasticsearch高級調優方法論之——根治慢查詢!
    是非常靈活且功能豐富的搜尋引擎,它提供了許多不同查詢數據的方法。https://www.elastic.co/cn/blog/how-many-shards-should-i-have-in-my-elasticsearch-clusterElasticsearch5.x冷熱架構實現https://www.elastic.co/cn/blog/hot-warm-architecture-in-elasticsearch-5-x容量規劃最佳實踐(必讀
  • Spring Boot系列(十)Spring Boot整合Elasticsearch全文搜尋引擎
    全文搜尋引擎,需要springboot實戰完整視頻教程的,點擊這裡!Spring Boot為Elasticsearch及Spring Data Elasticsearch提供的基於它的抽象提供了基本的配置。Spring Boot提供了一個用於聚集依賴的spring-boot-starter-data-elasticsearch 'StarterPOM'。
  • Spring Data ElasticSearch 使用
    http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd "> <!
  • Elasticsearch訪問日誌配置
    它提供了一個分布式多用戶能力的全文搜尋引擎,基於RESTful web接口。Elasticsearch是用Java語言開發的,並作為Apache許可條款下的開放源碼發布,是一種流行的企業級搜尋引擎。二、ELK1.ElasticSearch是一個搜尋引擎,用來搜索、分析、存儲日誌。它是分布式的,也就是說可以橫向擴容,可以自動發現,索引自動分片,總之很強大。
  • 全文搜尋引擎選 ElasticSearch 還是 Solr?
    強大,準確,高效的搜索算法:1、排名搜索:首先返回最佳結果。2、許多強大的查詢類型:短語查詢,通配符查詢,鄰近查詢,範圍查詢等。3、現場搜索(例如標題,作者,內容)。4、按任何欄位排序。5、使用合併結果進行多索引搜索。6、允許同時更新和搜索。7、靈活的分面,突出顯示,連接和結果分組。
  • Elasticsearch專題
    ,基於RESTful風格的全文搜尋引擎ES是分布式文檔資料庫。數據量擴展到很大級別(PB級數據)ES高可用和高可擴展而生https://www.elastic.co/cn/https://www.elastic.co/products/elasticsearch
  • Elastic App Search初體驗
    elasticsearch我們選擇的是使用rpm包的安裝方式,elasticsearch-7.9.0-x86_64.rpm,elastic7.9版本已經自帶打包了jdk,無需再獨立安裝jdk。CA,一路回車即可/usr/share/elasticsearch/bin/elasticsearch-certutil ca//然後使用ca進行證書的籤發,生成elastic-certificates.p12,一路回車即可/usr/share/elasticsearch/bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12
  • ElasticSearch 極簡教程
    它提供了一個分布式多用戶能力的全文搜尋引擎,基於RESTful web接口。Elasticsearch是用Java開發的,並作為Apache許可條款下的開放源碼發布,是當前流行的企業級搜尋引擎。設計用於雲計算中,能夠達到實時搜索,穩定,可靠,快速,安裝使用方便。ElasticSearch 架構
  • ElasticSearch性感體驗
    Elasticsearch是個開源分布式搜尋引擎,提供搜集、分析、存儲數據三大功能。它的特點有:分布式,零配置,自動發現,索引自動分片,索引副本機制,restful 風格接口,多數據源,自動搜索負載等。Kibana也是一個開源和免費的工具,Kibana可以為Logstash和ElasticSearch提供的日誌分析友好的Web界面,可以幫助匯總、分析和搜索重要數據日誌。
  • 搜尋引擎選開源的 ElasticSearch 還是商業的 Splunk
    它提供了一個分布式多用戶能力的全文搜尋引擎,基於RESTful web接口。Elasticsearch是用Java開發的,並作為Apache許可條款下的開放源碼發布,是當前流行的企業級搜尋引擎。設計用於雲計算中,能夠達到實時搜索,穩定,可靠,快速,安裝使用方便。
  • 搭建Elasticsearch集群
    高可用Elasticsearch 作為一個搜尋引擎,我們對它的基本要求就是存儲海量數據並且可以在非常短的時間內查詢到我們想要的信息。所以第一步我們需要保證的就是 Elasticsearch 的高可用性,什麼是高可用性呢?它通常是指,通過設計減少系統不能提供服務的時間。假設系統一直能夠提供服務,我們說系統的可用性是 100%。
  • 終於有人把elasticsearch原理講通了!
    【elasticsearch簡介】【elasticsearch基本概念】呂老師:之前我們說過,elasticsearch把操作都封裝成了http的api,我們只要給elasticsearch發送http請求就行。
  • SpringBoot+ ElasticSearch實現全文搜索功能
    >前端:html後端:springboot+ElasticSearchjdk:1.8及以上資料庫:沒有用到mysql (數據直接存到es表)掃碼關注回復【搜尋引擎;import org.elasticsearch.action.search.SearchResponse;import org.elasticsearch.client.RestClient;import org.elasticsearch.client.RestHighLevelClient;import org.elasticsearch.common.text.Text;import org.elasticsearch.index.query