Elasticsearch 最佳实践!

Stella981
• 阅读 495

Elasticsearch 最佳实践!

Java技术栈

www.javastack.cn

关注阅读更多优质文章

[

](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzI3ODcxMzQzMw%3D%3D%26mid%3D2247486559%26idx%3D2%26sn%3D0eebf45617fb7be5727712e22aac7fb6%26scene%3D21%23wechat_redirect)

作者:散尽浮华

原文:cnblogs.com/kevingrace/p/10671063.html

之前在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.cn10.0.8.44 10.0.8.44           26          54 0.09 d         m      elk-node01.kevin.cn10.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/health1554792912 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.sizegreen  open   10.0.61.24-vfc-intf-ent-deposit.log-2019.03.15       5   1        159            0    324.9kb        162.4kbgreen  open   10.0.61.24-vfc-intf-ent-login.log-2019.03.04         5   1       3247            0      3.4mb          1.6mbgreen  open   10.0.61.24-vfc-intf-ent-login.log-2019.03.05         5   1       1663            0      2.6mb          1.3mbgreen  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 相关概念

  • Elasticsearch集群与节点

节点(node)是你运行的Elasticsearch实例。一个集群(cluster)是一组具有相同cluster.name的节点集合,它们协同工作,共享数据并提供故障转移和扩展功能,当有新的节点加入或者删除节点,集群就会感知到并平衡数据。集群中一个节点会被选举为主节点(master),它用来管理集群中的一些变更,例如新建或删除索引、增加或移除节点等;当然一个节点也可以组成一个集群。

  • Elasticsearch节点通信

可以与集群中的任何节点通信,包括主节点。任何一个节点互相知道文档存在于哪个节点上,它们可以转发请求到我们需要数据所在的节点上。我们通信的节点负责收集各节点返回的数据,最后一起返回给客户端。这一切都由Elasticsearch透明的管理。

  • Elasticsearch集群生态

    1、同集群中节点之间可以扩容缩容;2、主分片的数量会在其索引创建完成后修正,但是副本分片的数量会随时变化; 3、相同的分片不会放在同一个节点上;

  • 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)操作,它们必须在主分片上成功完成才能复制到相关的复制分片上,下面我们罗列在主分片和复制分片上成功新建、索引或删除一个文档必要的顺序步骤:

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现象:

Elasticsearch 最佳实践!

这里的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}
  • 方案三:allocate重新分配分片

    如果方案二仍然未解决,可以考虑重新分配分片。可能的原因:1) 节点在重新启动时可能遇到问题。正常情况下,当一个节点恢复与群集的连接时,它会将有关其分片的信息转发给主节点,然后主节点将这分片从“未分配”转换为 已分配/已启动。2) 当由于某种原因 (例如节点的存储已被损坏) 导致该进程失败时,分片可能保持未分配状态。

在这种情况下,必须决定如何继续: 尝试让原始节点恢复并重新加入集群(并且不要强制分配主分片);  或者强制使用Reroute API分配分片并重新索引缺少的数据原始数据源或备份。如果你决定分配未分配的主分片,请确保将allow_primary:true标志添加到请求中。

Elasticsearch5.X使用脚本如下:

#!/bin/bashNODE=YOUR NODE NAMEIFS=$'\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.cn10.0.8.44 10.0.8.44           16          55 0.27 d         m      elk-node01.kevin.cn10.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_percent1554689492 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 elasticsearchroot      7066  3032  0 16:46 pts/0    00:00:00 grep --color=auto elasticsearchelastic+ 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_percent1554691187 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_percent1554691187 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_percent1554692772 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%, 但不要操作31gES_HEAP_SIZE=8g

然后重启elasticsearch服务即可。京东把 Elasticsearch 用的真牛逼!这篇推荐看下。

  • 错误4: ERROR: [3] bootstrap checks failed

原因:虚拟机限制用户的执行内存

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

[root@elk-node03 ~]# vim /etc/security/limits.confelasticsearch       hard        nofile        65536elasticsearch       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/health1554864073 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 commandscommand = 'curl 10.0.8.47:9200/_cat/health'(a, b) = commands.getstatusoutput(command)status= b.split(' ')[157]if status=='red':    healthy=0else:    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 = truenode.data = falsediscovery.zen.minimum_master_nodes = 2

修改其他节点配置,将其设置为DataNode,最后依次重启

node.master = falsenode.data = true

Elasticsearch 最佳实践!

Elasticsearch 最佳实践!

Elasticsearch 最佳实践!

Elasticsearch 最佳实践!

Elasticsearch 最佳实践!

Elasticsearch 最佳实践!

Elasticsearch 最佳实践!

关注Java技术栈看更多干货

Elasticsearch 最佳实践!

Elasticsearch 最佳实践!

戳原文,获取精选面试题!

本文分享自微信公众号 - Java技术栈(javastack)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
Java获得今日零时零分零秒的时间(Date型)
publicDatezeroTime()throwsParseException{    DatetimenewDate();    SimpleDateFormatsimpnewSimpleDateFormat("yyyyMMdd00:00:00");    SimpleDateFormatsimp2newS
Wesley13 Wesley13
3年前
MySQL 的慢 SQL 怎么优化?
!(https://oscimg.oschina.net/oscnet/7b00ec583b5e42cc80e8c56c6556c082.jpg)Java技术栈www.javastack.cn关注阅读更多优质文章(https://www.oschina.net/action/GoToLink?urlhttp
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这