AIOps 一场颠覆传统运维的盛筵
985
2022-10-21
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.reasonindex shard prirep state unassigned.reasonsyslog-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.reasonsyslog-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的价值
考虑到近期会有大量ELK相关的文章出没,建了一个交流群,欢迎感兴趣的小伙伴加入交流
长按下图可以关注哟~
发表评论
暂时没有评论,来抢沙发吧~