赞
踩
Elasticsearch 是一个实时的、分布式的可扩展的搜索引擎,允许进行全文、结构化搜索,它通常用于索引和搜索大量日志数据,也可用于搜索许多不同类型的文档。
Beats 是数据采集的得力工具。将 Beats 和您的容器一起置于服务器上,或者将 Beats 作为函数加以部署,然后便可在 Elastisearch 中集中处理数据。如果需要更加强大的处理性能,Beats 还能将数据输送到 Logstash 进行转换和解析。
Kibana 核心产品搭载了一批经典功能:柱状图、线状图、饼图、旭日图,等等。不仅如此,您还可以使用 Vega 语法来设计独属于您自己的可视化图形。所有这些都利用 Elasticsearch 的完整聚合功能。
Elasticsearch 通常与 Kibana 一起部署,Kibana 是 Elasticsearch 的一个功能强大的数据可视化 Dashboard,Kibana 允许你通过 web 界面来浏览 Elasticsearch 日志数据。
将ulimit 值添加到/etc/profile文件中(适用于有root权限登录的系统)
为了每次系统重新启动时,都可以获取更大的ulimit值,将ulimit 加入到/etc/profile 文件底部。
echo ulimit -n 65535 >>/etc/profile
source /etc/profile #加载修改后的profile
ulimit -n #显示65535,修改完毕!
更改主机名,配置域名解析,安装环境编译包,查看Java版本
node1和node2的配置相同,这里就不重复介绍了
1234567
ntpdate time1.aliyun.com
1
[root@SERVER 10 ~]# hostnamectl set-hostname node1
[root@SERVER 10 ~]# su
修改hosts
[root@node1 ~]# vim /etc/hosts
192.168.100.10 node2
192.168.100.9 node1
~
[root@node1 ~]# scp /etc/hosts root@192.168.100.10:/etc/hosts
12345678
测试节点通信
[root@node1 ~]#
[root@node1 ~]# ping node2
PING node2 (192.168.100.10) 56(84) bytes of data.
64 bytes from node2 (192.168.100.11): icmp_seq=1 ttl=64 time=0.753 ms
查看JAVA插件
[root@node1 ~]# java -version
openjdk version "1.8.0_181"
OpenJDK Runtime Environment (build 1.8.0_181-b13)
OpenJDK 64-Bit Server VM (build 25.181-b13, mixed mode)
关闭防火墙
systemctl stop firewalld
setenforce 0
iptables -F
12345678910111213
安装软件
rpm -ivh elasticsearch-5.5.0.rpm
加载系统服务
[root@node2 opt]# systemctl daemon-reload
[root@node2 opt]# systemctl enable elasticsearch.service
Created symlink from /etc/systemd/system/multi-user.target.wants/elasticsearch.serviceto /usr/lib/systemd/system/elasticsearch.service.
[root@node2 opt]#
123456
配置文件
备份 cp /etc/elasticsearch/elasticsearch.yml /etc/elasticsearch/elasticsearch.yml.bak 修改配置文件 vim /etc/elasticsearch/elasticsearch.yml 12345 [root@node2 opt]# grep -v "^#" /etc/elasticsearch/elasticsearch.yml cluster.name: sha node.name: node2 path.data: /path/elk_data path.logs: /var/log/elasticsearch/ bootstrap.memory_lock: flase network.host: 0.0.0.0 http.port: 9200 discovery.zen.ping.unicast.hosts: ["node1", "node2"] [root@node2 opt]# [root@node1 opt]# grep -v "^#" /etc/elasticsearch/elasticsearch.yml cluster.name: sha node.name: node1 path.data: /path/elk_data path.logs: /var/log/elasticsearch/ bootstrap.memory_lock: flase network.host: 0.0.0.0 http.port: 9200 discovery.zen.ping.unicast.hosts: ["node1", "node2"] [root@node1 opt]# 123456789101112131415161718192021
创建日志文件路径
[root@node1 opt]# mkdir -p /data/elk_data
1
增加权限属组属主
[root@node1 opt]# chown elasticsearch:elasticsearch /data/elk_data/
[root@node2 opt]# systemctl start elasticsearch.service
1234
加载系统服务
[root@node2 opt]# systemctl daemon-reload
[root@node2 opt]# systemctl enable elasticsearch.service
Created symlink from /etc/systemd/system/multi-user.target.wants/elasticsearch.serviceto /usr/lib/systemd/system/elasticsearch.service.
[root@server-9 log]# netstat -ntap | grep 9200
tcp6 0 0 :::9200 :::* LISTEN 8720/java
[root@SERVER 10 opt]# netstat -ntap | grep 9200
tcp6 0 0 :::9200 :::* LISTEN 17219/java
[root@SERVER 10 opt]#
123456789
访问节点测试,查看参数
#直接访问
192.168.100.9:9200
192.168.100.10:9200
#查看node1和node2的健康信息
192.168.100.9:9200/_cluster/health?pretty
192.168.100.10:9200/_cluster/health?pretty
#查看集群状态信息
192.168.100.9:9200/_cluster/state?pretty
192.168.100.10:9200/_cluster/state?pretty
1234567891011
编译安装node组件依赖包##耗时比较长
yum install gcc gcc-c++ make -y
[root@node1 elk]# tar xzvf node-v8.2.1.tar.gz -C /opt
[root@node1 elk]# cd /opt/node-v8.2.1/
[root@node1 node-v8.2.1]# ./configure
[root@node1 node-v8.2.1]# make -j4 //此处根据计算机性能选择
[root@node1 node-v8.2.1]# make install
12345678
安装phantomjs(前段框架显示)
tar xjvf phantomjs-2.1.1-linux-x86_64.tar.bz2 -C /usr/local/src
[root@node1 opt]# cd /usr/local/src
[root@node1 src]# ls
phantomjs-2.1.1-linux-x86_64
[root@node1 src]# cd phantomjs-2.1.1-linux-x86_64/bin
[root@node1 bin]# cp phantomjs /usr/local/bin
1234567
安装elasticsearch-head(支持插件视图化管理集群)
[root@node1 opt]# tar xzvf elasticsearch-head.tar.gz -C /usr/local/src
[root@node1 opt]# cd /usr/local/src/
[root@node1 src]# cd elasticsearch-head/
[root@node1 elasticsearch-head]# npm install
1234
#####修改主配置文件###
[root@node2 elasticsearch-head]# vi /etc/elasticsearch/elasticsearch.yml
####下面配置文件,插末尾##
http.cors.enabled: true
http.cors.allow-origin: "*"
[root@node2 elasticsearch-head]# systemctl restart elasticsearch
12345
####启动elasticsearch-head 启动服务器####
[root@node2 elasticsearch-head]# cd /usr/local/src/elasticsearch-head/
[root@node2 elasticsearch-head]# npm run start &
[1] 65545
[root@node2 elasticsearch-head]#
> elasticsearch-head@0.0.0 start /usr/local/src/elasticsearch-head
> grunt server
Running "connect:server" (connect) task
Waiting forever...
Started connect web server on http://localhost:9100
[root@node2 elasticsearch-head]# netstat -lnupt | grep 9100
tcp 0 0 0.0.0.0:9100 0.0.0.0:* LISTEN 65555/grunt
[root@node2 elasticsearch-head]# netstat -lnupt | grep 9200
tcp6 0 0 :::9200 :::* LISTEN 65453/java
1234567891011121314
测试9100页面 http://192.168.100.9:9100/ “可以看见群集很健康是绿色,如果是红色就报错了” 进入后连接两台9200的地址 http://192.168.100.10:9100/ 创建索引的两种方式 第一种,直接在页面创建 第二种 : 命令创建 [root@node1 elasticsearch-head]# curl -XPUT 'localhost:9200/index-demo/test/1?pretty&pretty' -H 'content-Type: application/json' -d '{"user":"zhangsan","mesg":"hello world"}'{ "_index" : "index-demo", "_type" : "test", "_id" : "1", "_version" : 1, "result" : "created", "_shards" : { "total" : 2, "successful" : 2, "failed" : 0 }, "created" : true } 1234567891011121314151617181920212223
[root@node1 opt]# rpm -ivh kibana-5.5.1-x86_64.rpm
警告:kibana-5.5.1-x86_64.rpm: 头V4 RSA/SHA512 Signature, 密钥 ID d88e42b4: NOKEY
准备中... ################################# [100%]
正在升级/安装...
1:kibana-5.5.1-1 ################################# [100%]
[root@node1 opt]# cd /etc/kibana/
[root@node1 kibana]# cp kibana.yml kibana.yml.bak
[root@node1 kibana]# vi kibana.yml
在物理机上访问elasticsearch集群是否记录这个日志
12345678910
部署apache服务,以及安装filebeat
[root@pc-8 ~]# ntpdate time1.aliyun.com
[root@pc-8 ~]# yum install httpd
[root@pc-8 opt]# ls
filebeat-5.6.3-x86_64.rpm rh
[root@pc-8 opt]# rpm -ivh filebeat-5.6.3-x86_64.rpm
警告:filebeat-5.6.3-x86_64.rpm: 头V4 RSA/SHA512 Signature,密钥 ID d88e42b4: NOKEY
准备中... ################################# [100%]
正在升级/安装...
1:filebeat-5.6.3-1 ################################# [100%]
123456789101112
在 202 行下 插入 LogFormat "{ \ \"@timestamp\": \"%{%Y-%m-%dT%H:%M:%S%z}t\", \ \"@version\": \"1\", \ \"tags\":[\"apache\"], \ \"message\": \"%h %l %u %t \\\"%r\\\" %>s %b\", \ \"clientip\": \"%a\", \ \"duration\": %D, \ \"status\": %>s, \ \"request\": \"%U%q\", \ \"urlpath\": \"%U\", \ \"urlquery\": \"%q\", \ \"bytes\": %B, \ \"method\": \"%m\", \ \"site\": \"%{Host}i\", \ \"referer\": \"%{Referer}i\", \ \"useragent\": \"%{User-agent}i\" \ }" apache_json 2)修改CustomLog "logs/access_log" combined为CustomLog "logs/access_log" apache_json (把原来默认的combined换成apache_json,原文件大概在217行的位置) 将原来的access.log清空,并重启httpd服务 1234567891011121314151617181920212223242526
[root@pc-8 filebeat]# vim /etc/filebeat/filebeat.yml
1
正常情况下,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集群与节点
节点(node)是你运行的Elasticsearch实例。一个集群(cluster)是一组具有相同cluster.name的节点集合,它们协同工作,共享数据并提供故障转移和扩展功能,当有新的节点加入或者删除节点,集群就会感知到并平衡数据。集群中一个节点会被选举为主节点(master),它用来管理集群中的一些变更,例如新建或删除索引、增加或移除节点等;当然一个节点也可以组成一个集群。
- Elasticsearch节点通信
可以与集群中的任何节点通信,包括主节点。任何一个节点互相知道文档存在于哪个节点上,它们可以转发请求到我们需要数据所在的节点上。我们通信的节点负责收集各节点返回的数据,最后一起返回给客户端。这一切都由Elasticsearch透明的管理。
- Elasticsearch集群生态
-> 同集群中节点之间可以扩容缩容;
-> 主分片的数量会在其索引创建完成后修正,但是副本分片的数量会随时变化;
-> 相同的分片不会放在同一个节点上;
- Elasticsearch分片与副本分片
分片用于Elasticsearch在集群中分配数据, 可以想象把分片当作数据的容器, 文档存储在分片中,然后分片分配给你集群中的节点上。 当集群扩容或缩小,Elasticsearch将会自动在节点间迁移分片,以使集群保持平衡。 一个分片(shard)是一个最小级别的“工作单元(worker unit)”,它只是保存索引中所有数据的一小片.我们的文档存储和被索引在分片中,但是我们的程序不知道如何直接与它们通信。取而代之的是,它们直接与索引通信.Elasticsearch中的分片分为主分片和副本分片,复制分片只是主分片的一个副本,它用于提供数据的冗余副本,在硬件故障之后提供数据保护,同时服务于像搜索和检索等只读请求,主分片的数量和复制分片的数量都可以通过配置文件配置。但是主切片的数量只能在创建索引时定义且不能修改.相同的分片不会放在同一个节点上。
- 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参数,它用来自定义文档到分片的映射。自定义路由值可以确保所有相关文档.比如用户的文章,按照用户账号路由,就可以实现属于同一用户的文档被保存在同一分片上。
- Elasticsearch分片与副本交互
新建、索引和删除请求都是写(write)操作,它们必须在主分片上成功完成才能复制到相关的复制分片上,下面我们罗列在主分片和复制分片上成功新建、索引或删除一个文档必要的顺序步骤:
-> 客户端给Node 1发送新建、索引或删除请求。
-> 节点使用文档的_id确定文档属于分片0。它转发请求到Node 3,分片0位于这个节点上。
-> Node 3在主分片上执行请求,如果成功,它转发请求到相应的位于Node 1和Node 2的复制节点上。当所有的复制节点报告成功,Node 3报告成功到请求的节点,请求的节点再报告给客户端。 客户端接收到成功响应的时候,文档的修改已经被应用于主分片和所有的复制分片。你的修改生效了
这里需要注意: 如下是单点单节点部署Elasticsearch, 集群状态可能为yellow, 因为单点部署Elasticsearch, 默认的分片副本数目配置为1,而相同的分片不能在一个节点上,所以就存在副本分片指定不明确的问题,所以显示为yellow,可以通过在Elasticsearch集群上添加一个节点来解决问题,如果不想这么做,可以删除那些指定不明确的副本分片(当然这不是一个好办法)但是作为测试和解决办法还是可以尝试的,下面试一下删除副本分片的办法:
出现unassigned 分片后的症状?
head插件查看会:Elasticsearch启动N长时候后,某一个或几个分片仍持续为灰色。
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,才能满足公式。这样问题就转嫁为:
[root@elk-node03 ~]``# curl -XPUT "http://10.0.8.47:9200/_settings" -d' { "number_of_replicas" : 0 } '``{``"acknowledged"``:``true``}
方案三:allocate重新分配分片
如果方案二仍然未解决,可以考虑重新分配分片。可能的原因:
在这种情况下,必须决定如何继续: 尝试让原始节点恢复并重新加入集群(并且不要强制分配主分片); 或者强制使用Reroute API分配分片并重新索引缺少的数据原始数据源或备份。 如果你决定分配未分配的主分片,请确保将"allow_primary":"true"标志添加到请求中。
#!/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,其他不变。
上面脚本解读:
**步骤1:**定位 UNASSIGNED 的节点和分片
curl -s ``'10.0.8.47:9200/_cat/shards'` `| ``fgrep` `UNASSIGNED
步骤2:通过 allocate_replica 将 UNASSIGNED的分片重新分配。
allocate分配原理
分配unassigned的分片到一个节点。将未分配的分片分配给节点。接受索引和分片的索引名称和分片号,以及将分片分配给它的节点。它还接受allow_primary标志来明确指定允许显式分配主分片(可能导致数据丢失)。
五. 分享一个案例: 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%
解决办法:
注意, 这里记录下修改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
详细报错: [INFO ][o.e.b.BootstrapChecks ] [SUcoFrg] bound or publishing to a non-loopback address, enforcing bootstrap checks ERROR: [3] bootstrap checks failed [1]: max file descriptors [4096] for elasticsearch process is too low, increase to at least [65536] [2]: max number of threads [3802] for user [elsearch] is too low, increase to at least [4096] [3]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144] [2019-02-20T02:35:47,170][INFO ][o.e.n.Node ] [SUcoFrg] stopping ... [2019-02-20T02:35:47,316][INFO ][o.e.n.Node ] [SUcoFrg] stopped [2019-02-20T02:35:47,316][INFO ][o.e.n.Node ] [SUcoFrg] closing ... [2019-02-20T02:35:47,336][INFO ][o.e.n.Node ] [SUcoFrg] closed 原因:虚拟机限制用户的执行内存 解决: [1]: max file descriptors [4096] for elasticsearch process is too low, increase to at least [65536] [2]: max number of threads [3802] for user [elasticsearch] is too low, increase to at least [4096] 修改安全限制配置文件 (使用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服务即可
错误5: org.elasticsearch.bootstrap.StartupException: java.lang.IllegalStateException: failed to obtain node locks, tried [[/home/elasticsearch-6.3.0/data/elasticsearch]] with lock id [0]; maybe these locations are not writable or multiple nodes were started without increasing [node.max_local_storage_nodes] (was [1])?
详细报错: [2019-02-20T04:23:25,003][WARN ][o.e.b.ElasticsearchUncaughtExceptionHandler] [] uncaught exception in thread [main] org.elasticsearch.bootstrap.StartupException: java.lang.IllegalStateException: failed to obtain node locks, tried [[/home/elasticsearch-6.3.0/data/elasticsearch]] with lock id [0]; maybe these locations are not writable or multiple nodes were started without increasing [node.max_local_storage_nodes] (was [1])? at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:140) ~[elasticsearch-6.3.0.jar:6.3.0] at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:127) ~[elasticsearch-6.3.0.jar:6.3.0] at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86) ~[elasticsearch-6.3.0.jar:6.3.0] at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:124) ~[elasticsearch-cli-6.3.0.jar:6.3.0] at org.elasticsearch.cli.Command.main(Command.java:90) ~[elasticsearch-cli-6.3.0.jar:6.3.0] at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:93) ~[elasticsearch-6.3.0.jar:6.3.0] at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:86) ~[elasticsearch-6.3.0.jar:6.3.0] Caused by: java.lang.IllegalStateException: failed to obtain node locks, tried [[/home/elasticsearch-6.3.0/data/elasticsearch]] with lock id [0]; maybe these locations are not writable or multiple nodes were started without increasing [node.max_local_storage_nodes] (was [1])? at org.elasticsearch.env.NodeEnvironment.<init>(NodeEnvironment.java:243) ~[elasticsearch-6.3.0.jar:6.3.0] at org.elasticsearch.node.Node.<init>(Node.java:270) ~[elasticsearch-6.3.0.jar:6.3.0] at org.elasticsearch.node.Node.<init>(Node.java:252) ~[elasticsearch-6.3.0.jar:6.3.0] at org.elasticsearch.bootstrap.Bootstrap$5.<init>(Bootstrap.java:213) ~[elasticsearch-6.3.0.jar:6.3.0] at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:213) ~[elasticsearch-6.3.0.jar:6.3.0] at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:326) ~[elasticsearch-6.3.0.jar:6.3.0] at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:136) ~[elasticsearch-6.3.0.jar:6.3.0] ... 6 more 原因:线程占用 解决:重新启动 [root@elk-node03 ~]# ps -ef|grep elasticsearch|awk -F" " '{print $2}'|xargs kill -9 [root@elk-node03 ~]# systemctl start elasticsearch [root@elk-node03 ~]# systemctl restart elasticsearch [root@elk-node03 ~]# ps -ef|grep -v grep|grep elasticsearch elastic+ 15586 1 11 Apr08 ? 03:06:12 /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 一定要确保elasticsearch是用非root账号启动的
错误6: [Godfrey Calthrop] All shards failed for phase: [query] [jr-2018.08.06][[jr-2018.08.06][2]] NoShardAvailableActionException[null]
详细报错: [2019-02-06 18:27:24,553][DEBUG][action.search ] [Godfrey Calthrop] All shards failed for phase: [query] [jr-2018.08.06][[jr-2018.08.06][2]] NoShardAvailableActionException[null] at org.elasticsearch.action.search.AbstractSearchAsyncAction.start(AbstractSearchAsyncAction.java:129) at org.elasticsearch.action.search.TransportSearchAction.doExecute(TransportSearchAction.java:115) at org.elasticsearch.action.search.TransportSearchAction.doExecute(TransportSearchAction.java:47) at org.elasticsearch.action.support.TransportAction.doExecute(TransportAction.java:149) at org.elasticsearch.action.support.TransportAction.execute(TransportAction.java:137) at org.elasticsearch.action.support.TransportAction.execute(TransportAction.java:85) at org.elasticsearch.client.node.NodeClient.doExecute(NodeClient.java:58) at org.elasticsearch.client.support.AbstractClient.execute(AbstractClient.java:359) at org.elasticsearch.client.FilterClient.doExecute(FilterClient.java:52) at org.elasticsearch.rest.BaseRestHandler$HeadersAndContextCopyClient.doExecute(BaseRestHandler.java:83) at org.elasticsearch.client.support.AbstractClient.execute(AbstractClient.java:359) at org.elasticsearch.client.support.AbstractClient.search(AbstractClient.java:582) at org.elasticsearch.rest.action.search.RestSearchAction.handleRequest(RestSearchAction.java:85) at org.elasticsearch.rest.BaseRestHandler.handleRequest(BaseRestHandler.java:54) at org.elasticsearch.rest.RestController.executeHandler(RestController.java:205) at org.elasticsearch.rest.RestController.dispatchRequest(RestController.java:166) at org.elasticsearch.http.HttpServer.internalDispatchRequest(HttpServer.java:128) at org.elasticsearch.http.HttpServer$Dispatcher.dispatchRequest(HttpServer.java:86) at org.elasticsearch.http.netty.NettyHttpServerTransport.dispatchRequest(NettyHttpServerTransport.java:449) at org.elasticsearch.http.netty.HttpRequestHandler.messageReceived(HttpRequestHandler.java:61)
问题解决
通过以上排查大概知道是历史索引数据处于 ``open` `状态过多,从而导致ES的CPU,内存占用过高导致的不可用。
关闭不需要的索引,减少内存占用
[root@elk-node03 ~]``# curl -XPOST "http://10.0.8.44:9200/index_name/_close"
如果发现在关闭非热点索引数据后,elasticSearch集群的健康值依然是``"red"``状态,这时候要想到: 可能索引的``"red"``状态可能会影响ES的状态.
接着查看elasticSearch索引健康状态, 发现果不其然
[root@elk-node03 ~]# curl GET http://10.0.8.44:9200/_cluster/health?level=indices { "cluster_name": "kevin-elk", "status": "red", "timed_out": false, "number_of_nodes": 3, "number_of_data_nodes": 3, "active_primary_shards": 660, "active_shards": 660, "relocating_shards": 0, "initializing_shards": 0, "unassigned_shards": 9, "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": 98.65470852017937, "indices": { "jr-2019.02.06": { "status": "red", "number_of_shards": 3, "number_of_replicas": 0, "active_primary_shards": 0, "active_shards": 0, "relocating_shards": 0, "initializing_shards": 0, "unassigned_shards": 3 } } } 解决方法,删除上面命令中查看的有问题的那条索引数据(这条数据是排查问题期间产生的脏数据,索引直接删除) [root@elk-node03 ~]# curl -XDELETE 'http://10.0.8.44:9200/jr-2019.02.06' 注意: 应注意elasticSearch的索引状态以及服务器的监控,及时清理或者关闭不必要的索引数据,避免这种情况发生。
七. Elasticsearch集群监控状态监控
1) 通过简单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 信息,段信息。
2) 利用脚本监控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 1 然后在脚本中结合sendemail进行邮件报警 或者 添加到zabbix监控里.
八. Elasticsearch配置中防止脑裂的配置
Master和DataNode未分离,导致集群不稳定
在ES集群中,节点分为Master、DataNode、Client等几种角色,任何一个节点都可以同时具备以上所有角色,其中比较重要的角色为Master和DataNode:
\1. Master主要管理集群信息、primary分片和replica分片信息、维护index信息。
\2. 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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。