解决Elasticsearch索引只读
现象
添加索引时发现kibana添加索引不生效,页面也没有报错,没有创建成功只是一闪而过。另外发现各项目日志与当前时间差异很大,filebeat一直报错io timeout具体报错如下: filebeat无法给logstash传输数。ip使用x代替
logstash/async.go:235 Failed to publish events caused by: read tcp 172.17.x.x:39092->172.17.x.x:5044: i/o timeout
logstash报错如下,logstash无法给es传输数据,es一直在拒绝所有的请求
[INFO ][logstash.outputs.elasticsearch] Retrying individual bulk actions that failed or were rejected by the previous bulk request. {:count=>1}[INFO ][logstash.outputs.elasticsearch] retrying failed action with response code: 403 ({"type"=>"cluster_block_exception", "reason"=>"blocked by: [FORBIDDEN/12/index read-only / allow delete (api)];"})
报错索引只读index read-only / allow delete (api)];"} es报错,es报错也是索引只读
解决办法1
在kibana开发控制台执行下面语句即可
PUT _settings
{"index": {"blocks": {"read_only_allow_delete": "false"}}}
解决方法2
如果kibana无法执行命令,可以使用下面命令解决
curl -XPUT -H "Content-Type: application/json" http://localhost:9200/_all/_settings -d '{"index.blocks.read_only_allow_delete": null}'
一旦在存储超过95%的磁盘中的节点上分配了一个或多个分片的任何索引,该索引将被强制进入只读模式
处理Elasticsearch集群yellow和red状态RED
原因
red表示不是所有的主分片都可用,通常时由于某个索引的住分片为分片unassigned,只要找出这个索引的分片,手工分配即可处理
curl GET http://{ESIP}:9200/_cluster/health?level=indices
查看所有索引信息,查看下是哪个索引的status是red导致了集群都red了(集群索引多的时候一眼看不出来,直接把结果拷出来,搜red关键字就跟踪到索引和分片了)
- 如果这个索引不是很重要,直接delete掉省事,集群状态马上恢复green完事~
- 通过reroute强制分配该分片(见下文)
YELLOW原因yellow表示所有主分片可用,但不是所有副本分片都可用,最常见的情景是单节点时,由于es默认是有1个副本,主分片和副本不能在同一个节点上,所以副本就是未分配unassigned处理
过滤查看所有未分配索引的方式, curl -s "http://10.19.22.142:9200/_cat/shards" | grep UNASSIGNED结果如下,第一列表示索引名,第二列表示分片编号,第三列p是主分片,r是副本
curl -s "http://{ESIP}:9200/_cat/shards" | grep UNASSIGNED
eslog1 3 p UNASSIGNED
eslog1 3 r UNASSIGNED
eslog1 1 p UNASSIGNED
eslog1 1 r UNASSIGNED
分配分片 知道哪个索引的哪个分片就开始手动修复,通过reroute的allocate分配
curl -XPOST 'http://10.99.249.58:9200/_cluster/reroute' -H "Content-Type: application/json" -d '{"commands" : [ {"allocate_replica" : {"index" : "logstash-2019.10.24","shard" : 4,"node" : "es-elasticsearch-data-0"}}]}'
[NO(the node is above the low watermark cluster setting [cluster.routing.allocation.disk.watermark.low=85%], using more disk space than the maximum allowed [85.0%], actual free: [13.14245440482006%])]
清理之后正常 es_clean.shes_clean.sh
#!/bin/bash
###################################
#删除早于十天的ES集群的索引
###################################
function delete_indices() {
comp_date=`date -d "10 day ago" +"%Y-%m-%d"`
date1="$1 00:00:00"
date2="$comp_date 00:00:00"
t1=`date -d "$date1" +%s`
t2=`date -d "$date2" +%s`
if [ $t1 -le $t2 ]; then
echo "$1时间早于$comp_date,进行索引删除"
#转换一下格式,将类似2017-10-01格式转化为2017.10.01
format_date=`echo $1| sed 's/-/\./g'`
echo "curl -XDELETE http://10.99.249.58:9200/*$format_date"
curl -XDELETE http://10.99.249.58:9200/*$format_date
fi
}
curl -XGET http://10.99.249.58:9200/_cat/indices | awk -F" " '{print $3}' | awk -F"-" '{print $NF}' | egrep "[0-9]*\.[0-9]*\.[0-9]*" | sort | uniq | sed 's/\./-/g' | while read LINE
do
#调用索引删除函数
delete_indices $LINE
done
分配时可能遇到的坑,需要注意的地方
- 分配副本时必须要带参数"allow_primary" : true, 不然会报错
- 当集群中es版本不同时,如果这个未分配的分片是高版本生成的,不能分配到低版本节点上,反过来低版本的分片可以分配给高版本,如果遇到了,只要升级低版本节点的ES版本即可
- (升级ES版本详见官方详细文档,我是ubuntu系统apt安装的,直接apt-get install elasticsearch升级的,elasticsearch.yml配置文件没变不用修改,但是/usr/share/elasticsearch/bin/elasticsearch文件中有个内存配置ES_HEAP_SIZE=6G需要再手动加一下&重启es)