likes
comments
collection
share

啥?删库?我和同事把线上 Es Index 删了,记录一次线上删库应急

作者站长头像
站长
· 阅读数 10

记录一次真实事故案例以及应急过程。

事件背景

某天下班前线上客户暴了一个问题,A功能列表刷不出来了。。。经过n个小时排查(同事家里网差),原因是早上B服务重启造成了3条脏数据数据。怎么办?时间比较晚将近11点了,这会儿处理数据有风险,先写SQL 明早跟客户和测试沟通再处理数据,必须等客户同意删除数据。

时间来到第二天早上,呵、代码还没写两行,同事提交了一条”SQL 审批“删除 mongodb 数据,因为在测试环境验证了直接点同意;接着提交了第二条删除 ES 数据审批,没收到审批通知,我直接帮忙提交。

我点点点,一路执行畅通无阻,原本以为客户恢复正常了,一切都在掌握中。没想到我还是太天真了,紧接着噩耗来了,售后工单群直接炸了,客户一顿喷。 啥?删库?我和同事把线上 Es Index 删了,记录一次线上删库应急

what ???我泪崩啊此刻心情。。。如下表情包 啥?删库?我和同事把线上 Es Index 删了,记录一次线上删库应急

问题定位

日志系统采集错误日志,下面这条日志非常频繁。

Elasticsearch exception [type=search_phase_execution_exception, reason=all shards failed

一开始并没有怀疑索引被删除,因为业务持续有数据产生。向 Es 写入数据时,如果指定的索引不存在,Es 会自动创建该索引,检查了发现 index 还在。

另外对同事写的删除数据脚本非常信任,怀疑是数据损坏了。赶紧写个脚本检索数据发现测试公司数据没了,应该是索引被删除了。

排查已执行删除数据脚本,发现下图资源缺了一部分被转化成了删除索引的脚本。 啥?删库?我和同事把线上 Es Index 删了,记录一次线上删库应急

转换后 CRUL 如下:

curl --location --request DELETE 'http://localhhost:9200/index_test' \
--header 'Content-Type: application/json' \
--data '{
  "query": {
    "bool": {
      "must": [
        {
          "terms": {
            "id": ["your_value"]
          }
        }
      ]
    }
  }
}'

实锤了不是数据问题,Index 被我们执行的脚本删了。工作了七八年,没想到删表在我身上发生了,这是多低级错误一口老血喷出。 啥?删库?我和同事把线上 Es Index 删了,记录一次线上删库应急

正确的删除姿势应该是

POST /your_index_name/_delete_by_query
{
  "query": {
    "match": {
      "your_field": "your_value"
    }
  }
}

DELETE /your_index_name/_doc/your_document_id

解决方案

怎么办?同事有点慌,删除数据库没想到在发生在自己身上。经过和运维同事沟通,索引和数据已删除没办法恢复,只能另想办法。

刚好又是早高峰必须抓紧决策方案,多浪费一分钟客户就多承担一分钟代价。

第一步 创建索引

果断决策先创建索引,列表报错客户根本没法使用,系统都进不到,另外依赖的系统还不少这部分流量怎们办?创建索引只能停服,停服影响范围?最终决策先停服务创建索引,保证客户增量业务正常「后来证实方案是正确的,增量业务正常了一部分客户问题解决了」。

出现问题--->定位.....-->保证增量数据正常,耗时26分钟。

第二步 存量数据修复方案

先确定是否有完整数据源用于恢复Es数据,还好mongodb 主库有全量数据,简直救我老命。es 可以理解为读模型用于检索业务。存量数据尤其是最近几周产生数据才是最重要的,客户非常着急,如果没有恢复数据客户工作展开不了。

确认有可靠数据源,接下就是数据同步方案了,现写脚本肯定赶不上,脚本开发+自测+测试验证+上线没有1小时搞不定。经过讨论有一个链路可行,当前业务具备一个能力从kafka消费数据写入Es,只要把数据写入kafka,就可以自动消费数据同步es。

数据怎么写入 Kafka?最容易想到的方案是采集mongodb 日志 oplog 写入Kafka,我们有现成的工具。整个链路可以打通了,如下图 啥?删库?我和同事把线上 Es Index 删了,记录一次线上删库应急

第三步 优先处理头部客户

待同步Es数据量大,我们直接将全量数据导入Kafka,本以为等数据同步完就好了。经过验证数据同步至少3小时「最终同步完时间差异不大,预估是准确的」。

刚同步几分钟很多头部客户闹过来了。肯定不能一把抓,租户也有优先级,故障对于头部租户影响最大,头部爸爸服务不好你可能就下岗了。

先把Kafka数据丢弃,最常见是拨偏移量,但要停服放弃了;同事建议新建topic改配置重启服务「采用了这种方案」。收集头部客户将头部客户数据投递Kafka中。

确认头部客户方案简单。

1、  联系售后,遇到故障头部租户比你还着急。

2、  统计数据,不展开细说懂得都懂。

第四步 通道隔离

消费Kafka写入Es是线上逻辑,用该通道同步存量数据线上数据实时性保障不了,增量数据受影响。

经过分析和讨论,可以紧急开辟一条通道和现通道并存。紧急优化代码新增通道,同步存量数据与线上通道隔离。

经过几小时同步,数同步完成。

总结

1、  线上数据删除一定要非常谨慎,脚本或SQL开发者一定要自测到位「自测环境和线上环境保持一致,这次故障就是因为操作线上用内部工具和线下是有差异的」,对于审批者是最后的守门员,一定要自己把好关,可以慢但一定要严谨。

2、  故障已发生没办法避免,一定要冷静应对,思考对策。严重故障就是在抢时间一定要快。

3、  问题处理不要胡乱抓,优先处理头部客户。头部客户才是受影响最广、最严重、最需要处理的。

4、  完成止血后,应该思考更完善方案加速问题处理,减少腰部客户和尾部客户损失。比如我列的通道隔离方案。

5、  客户选择你是对你的信任。系统稳定性、易用性、客户数据安全性一定要得到保障,才是客户留下的根本。每一步操作对客户有影响都要慎重、慎重。

真是惊心动魄一天,经过几小时奋斗,数据问题已经恢复了。也给我们留下了深刻印象,问题本可以避免的,真是血淋淋教训啊。

转载自:https://juejin.cn/post/7341275822153170984
评论
请登录