记一次线上环境 ES 主分片为分配故障

故障前提

ElasticSearch 版本:5.2
集群节点数:5
索引主分片数:5
索引分片副本数:1

线上环境ES存储的数据量很大,当天由于存储故障,导致一时间 5个节点的 ES 集群,同时有两个节点离线,一个节点磁盘只读(机房小哥不会处理,无奈只有清空数据重新安装系统),一个节点重启后,ES集群报个别索引分片分配异常,ES索引出于保证数据一致性的考虑,并没有把重启节点上的副本分片提升为主分片,所以该索引处于 不可写入 状态(索引分片 red)。

处理方案

在网上找了找类似的处理方案,分为以下几个。

  1. 利用 _reroute API 进行分片路由。

    pass: 分片都启不来,按照网上的操作执行失败。

  2. 利用 _reindex API 进行现有数据重新复制到新索引,然后把旧索引删除,新索引建立别名为老索引名称。

    优点:因为如图分片 0 出于只读状态,所以数据是可以访问的,所以利用_reindex可以把副本分片的数据进行复制迁移到新索引,最大保证数据的安全性。
    缺点:因为涉及的数据量比较大,而且_reindex效率很低,220G 的索引数据,大概要3-4天的时间才能写入完毕。线上环境等不了这么久。
    也找了许多提升_reindex效率的方法,设置新索引的副本数为 0,禁用刷新 等等。提升效果都很小。

  3. 线上环境能够接受该索引部分数据的丢失,但求尽快恢复服务。

找了下官方文档,找到了如下方法。

[[email protected]***es4 ~]# curl ‘http://localhost:9201/s2*******r201908/_shard_stores?pretty‘
{
  "indices" : {
    "s2********201908" : {
      "shards" : {
        "0" : {
          "stores" : [
            {
              "kgEDY2A4TBKK6lFzqsurnQ" : {
                "name" : "es3",
                "ephemeral_id" : "72HkjNj5S-qyl6gmVkbWeg",
                "transport_address" : "10.2.97.130:9300",
                "attributes" : { }
              },
              "allocation_id" : "B4G1nHTgQieomyy-KME1ug",
              "allocation" : "unused"
            },
            {
              "d3WYyXhBQvqYbZieXzfCNw" : {
                "name" : "es5",
                "ephemeral_id" : "deBE6DjyRJ-kXdj0XU7FzQ",
                "transport_address" : "10.2.101.116:9300",
                "attributes" : { }
              },
              "allocation_id" : "svMhSywPSROQa7MnbvKB-g",
              "allocation" : "unused",
              "store_exception" : {
                "type" : "corrupt_index_exception",
                "reason" : "failed engine (reason: [corrupt file (source: [index])]) (resource=preexisting_corruption)",
                "caused_by" : {
                  "type" : "i_o_exception",
                  "reason" : "failed engine (reason: [corrupt file (source: [index])])",
                  "caused_by" : {
                    "type" : "corrupt_index_exception",
                    "reason" : "checksum failed (hardware problem?) : expected=24fb23d3 actual=66004bad (resource=BufferedChecksumIndexInput(MMapIndexInput(path=\"/var/lib/elasticsearch/nodes/0/indices/oC_7CtFfS2-pa3OoBDAlDA/0/index/_1fjsf.cfs\") [slice=_1fjsf_Lucene50_0.pos]))"
                  }
                }
              }
            }
          ]
        }
      }
    }
  }
}

利用 _shard_stores 接口,查看故障索引的分片异常原因。
(es5 节点上,我调用接口设置了副本数从1 变为 0,所以该只读索引还保存有原有分片 0 的副本分片节点信息,可忽略)

我们看到该索引的 0 主分片(故障主分片)以前是存在于 es3 节点上的。ES 由于数据安全性保证,在两个节点都有离线的情况下,锁住了 0 主分片的写入,导致索引也出于只读状态。


[[email protected]*******es4 ~]# curl -XPOST ‘http://localhost:9201/_cluster/reroute?master_timeout=5m&pretty‘ -d ‘
{
    "commands": [
        {
            "allocate_stale_primary": {
                "index": "s2-********201908",
                "shard": 0,
                "node": "es3",
                "accept_data_loss": true
            }
        }
    ]
}‘

我们可以手动调用集群的 reroute 接口,在接受部分数据丢失的情况下,我们可以把 es3 节点上的原有副本,强制提升为索引的主分片。

官方文档 说明。

此外,/_cluster/reroute 接口还能够接受手动分配一个空的主分片到已有索引分配之中。谨慎使用

[[email protected]*******es4 ~]# curl -XPOST ‘http://localhost:9201/_cluster/reroute?master_timeout=5m&pretty‘ -d ‘
{
    "commands": [
        {
            "allocate_empty_primary": {
                "index": "s2-********201908",
                "shard": 0,
                "node": "es3",
                "accept_data_loss": true
            }
        }
    ]
}‘

这种更残暴,直接把分片数据清空,强制拉上线。 但是这也不失为一种处理方法。

最终,该索引恢复正常。

原文地址:https://blog.51cto.com/professor/2432102

时间: 2024-08-28 23:31:27

记一次线上环境 ES 主分片为分配故障的相关文章

[Nginx笔记]关于线上环境CLOSE_WAIT和TIME_WAIT过高

运维的同学和Team里面的一个同学分别遇到过Nginx在线上环境使用中会遇到TIME_WAIT过高或者CLOSE_WAIT过高的状态 先从原因分析一下为什么,问题就迎刃而解了. 首先是TIME_WAIT: 理解一下TIME_WAIT状态产生的原因,这个问题已经被很多很多的书说烂了,但是为什么很多人还是不能解决,究其原因还是因为 大多数都是学术派,并没有真正的遇到过这样的问题,因为TIME_WAIT大量产生很多都发生在实际应用环境中. TIME_WAIT产生的原因还是因为在通讯过程中服务端主动关闭

使用Fabric批量部署上线和线上环境监控

本文讲述如何使用fabric进行批量部署上线的功能 这个功能对于小应用,可以避免开发部署上线的平台,或者使用linux expect开发不优雅的代码. 前提条件: 1.运行fabric脚本的机器和其他机器tcp_port=22端口通 2.ssh可以登录,你有账号密码 一.先说批量部署上线 先上代码,再仔细讲解,脚本如下 # -*- coding:utf-8 -*- from fabric.colors import * from fabric.api import * from contextl

系统上线那点事 - 记一次线上系统故障

该项目是一个微信转盘游戏抽奖营销项目.因为运营营销时间要求紧迫.开发測试部署上线用了10天不到,有些准备工作并没有到位,如: 1.因为总体开发在上线前2天才完毕,測试了解这个项目需求是在开发的第二周,并没有充足的时间进行完好的功能,UI机型适配,系统压力測试. 2.技术上因为合作方的公众号密钥并不适合直接给出,所以由对方封装微信接口获取所需功能,对方封装的微信接口给出比較迟,在预定開始时间前三天: 微信的网页接口授权回调域名仅仅有一个.这个回调域名还有其它应用在使用,不能直接简单的改为我们部署应

Nginx、Tomcat线上环境优化配置

 Nginx.Tomcat线上环境优化配置 Nginx优化: Nginx安全方面的优化: 1. nginx安全优化,在nginx配置文件http标签段内添加"server_tokens  off"即可隐藏访问或者报错时提示web版本号信息. 2. server_tokens参数可以在http,server,location的位置添加 3. 还可以修改nginx的3个源码文件 4. 如还需要安全优化更改端口.用户. nginx 性能优化: 对于nginx配置文件中对优化比较有作用的一般为

线上环境的回滚机制

[场景描述]你是否遇到过这种情况,在正常运行的线上环境下要要重新发布一个项目, [正常的操作如下]: 1.先把tomcat关掉: 2.删掉tomcat下的项目文件(按需备份),把war包放在tomcat对应正确路径下解压: 3.重启tomcat,重启后发现部署失败代码有问题则执行4,否则结束. 4.部署出错,赶紧关闭tomcat,把上一个版本/备份拷回来,再重启tomcat,结束.... 是不是觉得太low?这里tomcat关闭重启的时间太长了,并且有可能要来回拷贝解压两次~!不能忍,来巧妙使用

简要的线上环境部署概览

谈到线上环境,一般开发同学,不太容易接触到.即使接触到,也只是其中的冰山一角! 所以,其实说起线上环境的部署,咱们好像都有点懂,但是又都不一定完全懂!网上的知识无穷无尽,但往往都是各司一职,对于普通同学,很难窥其全貌! 所以,我今天就来说说,一些普通的线上环境的部署步骤,和一些脚本小技巧吧.只希望通过这篇文章,能够让大家有一个运维的全局! 我将会分几条线来整理咱们的运维思路! 一.从理论上讲,我们应该怎么做? 1. 针对的是什么样的用户群体,体量大量会有多少? 这是一个部署规划的前题.为啥呢?

【微信小程序】---线上环境搭建

一.前言 通常我们在本地电脑上开发微信小程序,调用和访问小程序会有很多问题.特别是在配有自己后端的情况下,我们通过真机访问我们的小程序会出现不可访问的问题 二.线上环境搭建 在这里我们主要以腾讯云给大家做演示 1.注册并登陆腾讯云   https://cloud.tencent.com/ 2.上传代码 a.把客户端代码和服务端代码放置在微信小程序目录下 b.将客户端代码放置到client文件加中,服务端代码放置在server文件加中 c.把原微信小程序project.config.js文件转移到

express框架开发接口部署线上环境PM2

1.PM2介绍 PM2是一个线上环境下,用于启动nodejs进程守护的工具,用来保证服务的稳定及分摊服务器进程和压力. 2.下载安装 npm install pm2 -g  => pm2 --version  => 在package.json scripts中配置 "prd": "cross-env NODE_ENV=production pm2 start app.js" =>  npm run prd运行,运行结果如下图: 3.常用命令 启动:

Docker + node(koa) + nginx + mysql 线上环境部署

在上一篇 Docker + node(koa) + nginx + mysql 开发环境搭建,我们进行了本地开发环境搭建 现在我们就来开始线上环境部署 如果本地环境搭建没有什么问题,那么线上部署的配置也就很简单了 我所使用的环境,Linux Mint,命令有不同可以适当更改 目录结构 - compose 新建,线上环境配置 - data - conf - node_modules - static - docker-compose.yml - docker-compose-prod.yml 新建