ELK|ES管理之又见 UNASSIGNED SHARD

微信扫一扫,分享到朋友圈

ELK|ES管理之又见 UNASSIGNED SHARD

在ES集群管理过程中,分区(shard)出现unassigned是遇到了比较多的情况了.原因很多常见的两个:节点意外重启(NODE_LEFT),磁盘空间不足(No space left on device).而我最近遇到的情况:操之过急或者说重启节点姿势不正确,造成主分区挂掉,日志无法写入,以至于拖慢整个index.比较宝贵的实战经验记录一下

本文相关版本信息

elasticsearch:6.0.0

kibana:6.0.0

以下操作在 kibana 自带的DevTools进行

查看集群状态

一般出现分区未分配的时候,整个集群的状态都会变成RED

GET _cluster/health
{
"cluster_name": "cluster_name",
"status": "green",
"timed_out": false,
"number_of_nodes": 5,
"number_of_data_nodes": 5,
"active_primary_shards": 89,
"active_shards": 109,
"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
}

当然现在状态是正常的,如果不正常的话”status”不是”green”

"status": "green",
"active_shards_percent_as_number": 100

“active_shards_percent_as_number”不会是100,以下三个指标也会各有数字

"relocating_shards": 0,
"initializing_shards": 0,
"unassigned_shards": 0,
"delayed_unassigned_shards": 0,

应对异常

查询shard异常

GET _cat/shards?v&s=state&h=index,shard,prirep,state,unassigned.reason
index                         shard prirep state   unassigned.reason
zzzlog-2020.11.05             1     p      STARTED
zzzlog-2020.11.05             2     p      STARTED
zzzlog-2020.11.05             3     p      STARTED
syslog-2020.11.05             2     r      STARTED
syslog-2020.11.05             1     p      STARTED
syslog-2020.11.05             3     r      STARTED

上面只是示例一下,有异常的话,unassigned.reason那列会有相应的显示

当然,也可以查询指定的index

GET _cat/shards?v&s=state&h=index,shard,prirep,state,unassigned.reason&index=syslog*
index             shard prirep state   unassigned.reason
syslog-2020.11.05 1     p      STARTED
syslog-2020.11.05 3     p      STARTED
syslog-2020.11.05 2     p      STARTED

查询具体原因

GET /_cluster/allocation/explain?pretty
{
"error": {
"root_cause": [
{
"type": "remote_transport_exception",
"reason": "[sys-es-001][xx.xx.xx.xx:9300][cluster:monitor/allocation/explain]"
}
],
"type": "illegal_argument_exception",
"reason": "unable to find any unassigned shards to explain [ClusterAllocationExplainRequest[useAnyUnassignedShard=true,includeYesDecisions?=false]"
},
"status": 400
}

如果是磁盘不足,或者是节点意外重启,经过上面两步基本就可以看出来了.

节点重启的话,一般起来以后,ES集群是自动再同步一次数据,很快未分配的分区就会消失

磁盘不足自然需要手动扩容或添加磁盘,相应的,重启以后也会有很大的概率自动恢复

当然这里有一个失败次数最大五次的概念,达到次数了,再手动触发一下就好了.

POST /_cluster/reroute?retry_failed=true

对了,有时候直接查询集群分配失败原因 /_cluster/allocation/explain 并查不到任何东西.我们通过 _cat/shards 已经知道具体哪个index有问题了,这时候可以直接查询指定的索引

GET /_cluster/allocation/explain?pretty
{
"index": "syslog-2020.11.04",
"shard": 2,
"primary": true
}

一般的感冒发烧,到这里就结束了,如果是重症再继续往下看喽

疑难杂症

同样的症状可能原因有很多,以下几招是我运维ES集群两年的经验结晶了.

分区重建之修改索引副本数

有时候分区unassigned状态始终恢复不了,可以尝试调整一下分区的副本数,或增加或减少,大概率会管用

PUT syslog-2020.11.03/_settings
{
"settings": {
"index.number_of_replicas": "1"
}
}

number_of_replicas只要与当前不一致即可.什么不知道当前副本数?查之

GET syslog-2020.11.03/_settings?filter_path=**.number_of_replicas
{
"syslog-2020.11.03": {
"settings": {
"index": {
"number_of_replicas": "3"
}
}
}
}

哦,对,上面这个filter_path也是个好东西,数据量大时绝对好用

分区重建之手动修改分区节点

既然在这个节点上一直失败,咱换个节点好了

POST _cluster/reroute
{
"commands": [
{
"move": {
"index": "syslog-2020.08.04",
"shard": 2,
"from_node": "es2-master",
"to_node": "es3-master"
}
}
]
}

当然,这一招的正经用法是ES集群磁盘分布不匀,手动将磁盘使用过度的分区调到空闲节点

分区重建之创建空分区

分区失败也有可能,是因为里面的数据乱了,丢弃一部分,换来集群正常也是值得的

POST _cluster/reroute
{
"commands": [
{
"allocate_empty_primary": {
"index": "syslog-2020.08.17",
"shard": 7,
"node": "es5-data",
"accept_data_loss":true
}
}
]
}

两害相较取其轻,放弃分区数据相对整个索引数据要好接受不少

分区重建绝招之放弃数据

既然放弃分区的数据不行,那便放弃这个index之前写入的所有数据,毕竟后面还有不少要写入不是

DELETE syslog-2020.08.17

这一招算是釜底抽薪了,需要接受数据丢失带来的风险

分区重建绝招之放弃节点

这招是头两天的意外发现,因为那天确实日志量大采集不进来,但是又出了几个线上问题,急需查日志,当时的念头就是无论如果,不能放弃数据.因为只有一个index的一个分区有问题,其它日志还在正常写,但是日志量又大,很快把这个节点的磁盘写满了,想着反正es一会儿也得自动均衡磁盘,直接手动标记这个节点下线算了.

PUT _cluster/settings
{
"transient": {
"cluster.routing.allocation.exclude._ip": "xx.xx.xx.xx"
}
}

意外的,竟然发现不能创建的那个index的分区自动创建了.谢天谢地!

集群正常了,可以再考虑把这个节点加回来

PUT _cluster/settings
{
"transient": {
"cluster.routing.allocation.exclude._ip": null
}
}

这个问题的表现是state:INITIALIZING,unassigned.reason: ALLOCATION_FAILED,又一个主分区,还是0副本.当时的查询记录还有:

GET /_cluster/allocation/explain?pretty
{
"index": "syslog-2020.11.04",
"shard": 2,
"primary": true
}
{
"index": "syslog-2020.11.04",
"shard": 2,
"primary": true,
"current_state": "initializing",
"unassigned_info": {
"reason": "ALLOCATION_FAILED",
"at": "2020-11-04T14:34:03.022Z",
"failed_allocation_attempts": 5,
"details": "failed recovery, failure RecoveryFailedException[[syslog-2020.11.04][2]: Recovery failed on {es-005}{zVzh5mpxSam4dGTFkgh3FA}{ZzWZcNLGT_SgS6tTdguBtQ}{xx.xx.xx.xx}{xx.xx.xx.xx:9300}{box_type=hot}]; nested: IndexShardRecoveryException[failed to recover from gateway]; nested: EngineException[failed to recover from translog]; nested: AlreadyClosedException[this IndexWriter is closed]; nested: IOException[No space left on device]; ",
"last_allocation_status": "no"
},
"current_node": {
"id": "zVzh5mpxSam4dGTFkgh3af",
"name": "es-005",
"transport_address": "xx.xx.xx.xx:9300",
"attributes": {
"box_type": "hot"
}
},
"explanation": "the shard is in the process of initializing on node [es-005], wait until initialization has completed"
}

后话

最后还是想提一下敬畏之心.

大数据,什么是大数据呢.一天几百G,历史数据十几T.虽然是日志系统,这么大的数据量,任何一个小的操作都要谨慎谨慎再谨慎.因为你的一个小失误,都是大量的数据或移动或消失或产生,影响都是很难承受的.像前面说的增加副本数 number_of_shards ,直接的结果就是主机CPU飙升,磁盘疯狂读写,内网网卡几百兆带宽以支撑这么大量的数据交换

最后一句送给自己:es集群很优秀,几十亿条数据毫秒级查询,如果你感觉es搜索慢,99.99%的原因是因为你自己不优秀,没发挥出来es的价值

转载请注明: 转自Rainbird的个人博客    本文链接: ELK|ES管理之又见 UNASSIGNED SHARD

相关博文

  • Python|windows下运行selenium提示DevTools listening on ws://127.0.0.1
  • Android|MIUI10 当前设备已被临时限制3-1
  • Python|openpyxl单元格设置超链接及读取
  • Python|介绍一下我的新伙伴fastapi(一)
  • Python|fastapi从入门到不放弃(二)

微信扫一扫,分享到朋友圈

ELK|ES管理之又见 UNASSIGNED SHARD

下月停止支持:微软开始强制Win10 1903用户升级

上一篇

中国电信发布首款5G云手机天翼1号:支持超级SIM卡 内置云服务

下一篇

你也可能喜欢

ELK|ES管理之又见 UNASSIGNED SHARD

长按储存图像,分享给朋友