之前在IDC机房线上环境部署了一套ELK日志集中分析系统, 这里简单总结下ELK中Elasticsearch健康状态相关问题, Elasticsearch的索引状态和集群状态传达着不同的意思。

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

一.  Elasticsearch 集群健康状态

查看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

正常情况下,Elasticsearch 集群健康状态分为三种:
green      最健康得状态,说明所有的分片包括备份都可用;
yellow    基本的分片可用,但是备份不可用(或者是没有备份);
red          部分的分片可用,表明分片有一部分损坏。此时执行查询部分数据仍然可以查到,遇到这种情况,还是赶快解决比较好;

二.  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与集群的健康状态解释是一样的!

三.  状态为yellow的解决办法

分片与副本分片
分片用于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集群的一些概念

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

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

六.  分享一个ELK中ElasticSearch集群状态为red的问题

线上环境部署的ELK日志集中分析系统, 过了一段时间后, 发现Kibana展示里没有日志, 查看head插件索引情况, 发现一直打不开! 这是因为如果不对es索引定期做处理, 则随着日志收集数据量的不断增大, es内存消耗不断增量, 索引数量也会随之暴增, 那么elk就会出现问题, 比如elk页面展示超时, 访问http://10.0.8.47:9200/_plugin/head/ 一直卡顿等; es集群状态异常(出现red的status)等!

解决办法:
1) 增大es内存设置, 默认是2g;
2) 定期删除es索引, 比如只保留最近一个月的索引数据;
3) 如果es主节点重启, 则主节点在转移到其他节点过程中, 分片分片也会转移过去; 如果分片比较多, 数据量比较大, 则需要耗费一定的时间, 在此过程中, elk集群的状态是yellow; 查看elk集群状态, shards分片会不断增加, unassign会不断减少,直至unassign减到0时, 表明分片已经完全转移到新的主节点上, 则此时查看elk的健康状态就是green了;
4) 如果所有es节点都重启, 则需要先启动一个节点作为master主节点, 然后再启动其他节点;

修改ElasticSearch的内存配置

先修改/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

然后重启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

 

 

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄