半天河
网易游戏高级运维工程师,主要负责云存储的运维;一个既希望跟业务聊又喜欢能够默默在后面忙活的普通运维人。

背景故障现场故障恢复故障恢复分析第一种方式:物理磁盘对拷第二种方式:服务启动时跳过故障扇区来避免异常退出解决方案恢复流程找到故障扇区处的文件移走故障扇区的文件总结

背景

对于 ceph 运维而言,硬件故障导致的 ceph 存储故障是占比最高的一个故障源,小到单个磁盘故障大到机器故障,每天都在上演,ceph 的多副本、故障域等机制已经能够保证绝大部分的硬件故障不影响整个 ceph 集群的可用性,比如:

  • 多副本能够确保只要还有一个副本在,数据就不会丢失,业务依然可用
  • 故障域的划分能够确保一个故障域内的机器或者机柜故障时,数据不会丢失,业务依然可用
  • 有需要时还可以将故障服务踢出集群,触发数据迁移到故障域内其他硬盘,缩短副本数不达标的时间,降低二次故障的影响

但是在日常实际场景中,概率低不代表不会发生,我们必须对这种虽然概率低但是影响可能很大的故障做好预案,确保一旦发生故障能够快速恢复服务。

故障现场

这里先简单介绍一下整个故障现场:

  • ceph 的版本是Hammer 0.94.5
  • 故障域是 host,副本数是 2(即同一个业务的数据会写两份,落在不同 host 的各一个硬盘上)
  • 一台服务器的一块硬盘故障
  • 更换磁盘,同步数据
  • 另一台服务器上又有一块硬盘故障
  • 数据两个副本存放在这两块硬盘上的所有业务请求被 block 住
  • 集群状态关键信息如下:
    2 pgs down; 2 pgs peering;
    57 requests are blocked > 32 sec;
    recovery 4292086/381750087 objects degraded (1.124%);
    recovery 7/137511185 unfound (0.000%);
    21/967 in osds are down;

    • down 表示有部分数据的两个副本都不在线
    • 有 57 个客户端的请求被 block 超过 32 秒
    • 注意这里是 7 个对象的状态是 unfound

故障恢复

故障恢复分析

目前数据层的影响面及恢复分析如下:

  • 毫无疑问,第一要务是先拉回所有存储服务
  • 服务都在线后才能明确两块硬盘先后故障是否有数据丢失
  • 根据数据实际情况再决定后续恢复操作

目前是因为磁盘有坏道,读取坏道数据出错导致服务无法启动。

第一种方式:物理磁盘对拷

最先想到也是操作最简单的一种方法就是将故障盘数据全量拷贝到一块新的硬盘上,忽略其中的故障扇区读取错误,方法如下:

  • 在同机房找到一台空闲服务器,插上新硬盘,格式化分区
  • 通过 dd+nc 的方式将故障盘数据 dd 到准备的新盘
    # 备用机器,新硬盘
    nc -lp {port} | dd of=/dev/sde1
    # 故障机器
    dd if=/dev/sdX conv=noerror | nc -q 10 {backup ip} {nc port}
  • 拷贝完成后将新盘替换掉故障盘启动服务即可
  • 这种方法是可行的,尤其是对于较大范围的磁盘硬件故障这是一个相对稳妥且节省人力的方法
  • 但是由于故障 SAS 盘读写速度也就 200MB/s 的峰值,即使保持这个速度,1.2TB 的盘同步完成也需要接近两小时,线上业务坐等两小时是无计可施的保底方法。

第二种方式:服务启动时跳过故障扇区来避免异常退出

解决方案

回过头仔细分析本次故障的信息及规避方法汇总如下:

  • 磁盘故障范围小,虽然 dmesg 很多报错信息,但是都集中在同一个扇区
    Sep 26 16:09:33 cld-XXXX-XX kernel: [51720946.582063] end_request: critical medium error, dev sdd, sector 49382788
    ...
    Sep 26 16:23:02 cld-XXXX-XX kernel: [51721756.747154] end_request: critical medium error, dev sdd, sector 49382788
  • 存储服务启动时的报错信息是读写错误,尝试启动一次上面的 dmesg 信息就会再刷一些通用的日志:
    FAILED assert(0 == "Input/output error")
  • 找到故障扇区所在的文件,移走该文件,移走文件并不会变更该扇区所在的文件,以确保故障扇区依然被占用而不会分配给其他文件使用
  • osd 启动时就不会读取故障扇区所在文件,就不会抛异常退出

恢复流程

经过上述分析后,恢复流程就比较清晰而且简单了:

找到故障扇区处的文件

  • 在配置文件中调大 osd 服务的 debug_filestore 日志级别到 20/20
  • 启动故障盘的存储服务,从日志中可以看到故障扇区的文件,如下
    7f08ae8ee700 10 filestore(/home/ceph/var/lib/osd/ceph-387) FileStore::read(28.7cb_head/b7e767cb/rb.0.8e1ad1d.238e1f29.00000000a418/head//28) pread error: (5) Input/output error
  • 得到关键信息:PG 是 28.7cb ,目录结构是b7e767cb,故障扇区所在文件是 rb.0.8e1ad1d.238e1f29.00000000a418
  • 根据 filestore 的存储规则定位到该对象在磁盘上的绝对路径如下:
    /home/ceph/var/lib/osd/ceph-387/current/28.7cb_head/DIR_B/DIR_C/DIR_7/DIR_6/rb.0.8e1ad1d.238e1f29.00000000a418__head_B7E767CB__1c

TIPS:filestore 是以文件的形式存储,同时为了避免单目录下文件数过多影响性能,osd 会将这些对象分多级目录存储,从前面的日志中可以看到对象路径是<pg_id>/b7e767cb/<object_name>,这里面的b7e767cb就是用来分子目录时的目录名,根据当前目录层级是 4(由当前 pool 的总对象数和各层文件数决定),可知道这个 object 存储在磁盘上的路径是:<pg_id>/DIR_B/DIR_C/DIR_7/DIR_6/<object_name>

移走故障扇区的文件

这时候通过 cat 尝试查看这个文件可以看到中途会卡住,dmesg 也会继续刷上面的扇区错误,进一步实锤了磁盘坏道所在文件即为rb.0.8e1ad1d.238e1f29.00000000a418__head_B7E767CB__1c

  • 移动故障对象
    mv /home/ceph/var/lib/osd/ceph-387/current/28.7cb_head/DIR_B/DIR_C/DIR_7/DIR_6/rb.0.8e1ad1d.238e1f29.00000000a418__head_B7E767CB__1c /home/ceph/var/lib/osd/ceph-387
  • 拉起服务,成功运行,一段时间后集群状态如下这个 object 状态仍然是 unfound:
    1 requests are blocked > 32 sec;
    recovery 1/137522689 unfound (0.000%);
  • 注意这里的recovery 1/137524092 unfound (0.000%),前面服务没有拉起来时 ceph 提示有 7 个对象处于 unfound,现在只剩下一个了,这个对象的 osd 的日志提示如下:
    # 从名字上看也恰好是故障扇区的那个文件
    28.7cb missing primary copy of b7e767cb/rb.0.8e1ad1d.238e1f29.00000000a418/head//28, unfound

TIPS:ceph 的对象包括三个部分的数据,一个是纯数据部分,一个是文件系统扩展属性提供的元数据,一个 ceph 自己实现的 omap 元数据,这里的 unfound 表示 ceph 在本地没有找到跟元数据中记录的版本一致的对象,unfound 数量变少,说明经过版本比对,其他 6 个对象的版本和其他副本的版本是一致的。

  • 这时候只能用以下命令通过 ceph 将这个 pg 下的 object 回滚到另一个副本上的版本了
    ceph pg 28.7cb mark_unfound_lost revert

TIPS:因为第一块盘故障离线期间 ceph 是还可以继续使用的,这期间有对象发生数据更新,而更新的这部分数据就只在第二块故障盘上有,因此就造成了这个对象有两个版本,新的版本不可用,因此使用 revert 来告诉 ceph 使用较老版本;如果两个副本同时不可用,只能使用 lost 来标记对象丢失来恢复服务。

至此,集群完全恢复,后续的步骤就是根据这个故障对象名找到 rbd,继而找到所属的虚拟机,请求业务确认影响面并检查虚拟机。

总结

以上就是我们针对双副本对象的两个副本因为故障先后离线这种极端情况下进行数据抢救的过程。针对故障、抢救过程以及后续优化总结如下:

  • 单个磁盘故障可能会导致整个机器的 raid 卡控制器 reset
  • 在一个副本故障期间,又有新的磁盘硬件故障,就导致了本问描述的严重故障,三副本能大大减少本次故障概率
  • 如果硬盘故障,在完全恢复前不要删除数据或者格式化硬盘,以免碰到另一个副本也故障时,连回滚来版本的机会也没有了
  • 抢救的根本方法是找到问题症结,如本次故障中采用移走故障文件的方式就可以解决无法启动问题
  • ceph 故障都会有比较详细的日志提示,根据提示结合 ceph 的结构特点做针对性的处理即可
  • 双副本发生二次故障的概率更高,尤其是使用年限较高深圳过保的老集群
  • 对于关掉了 deep-scrub 的集群,需要手动不定期去触发 deep-scrub,防止一些可能隐藏的磁盘故障。

往期精彩

那些年,CDN踩过的坑

智能监控中的时间序列预测

使用 d3.js 绘制资源拓扑图

运维里的人工智能

CI构建环境下的docker build最佳实践

sleep期间读取所有_ceph部分数据所有副本先后故障的抢救相关推荐

  1. ceph部分数据所有副本先后故障的抢救

    半天河 网易游戏高级运维工程师,主要负责云存储的运维:一个既希望跟业务聊又喜欢能够默默在后面忙活的普通运维人. 背景故障现场故障恢复故障恢复分析第一种方式:物理磁盘对拷第二种方式:服务启动时跳过故障扇 ...

  2. python文件读取方法read(size)的含义是_在Python中可使用read([size])来读取文件中的数据,如果参数size省略,则读取文件中的()。...

    [单选题]李明在他所属的公司工作五年,每天都很认真地处理繁杂的事情,同事们都夸他认真,但是依然没有建树,这是因为: [多选题]品牌标志的作用表现在 [单选题]新产品开发的第一个阶段是_______. ...

  3. pandas使用read_csv函数读取文件时指定数据列的数据类型、pandas使用read_csv函数读取文件时通过keep_default_na参数设置缺失值替换为空字符串

    pandas使用read_csv函数读取文件时指定数据列的数据类型.pandas使用read_csv函数读取文件时通过keep_default_na参数设置缺失值替换为空字符串 目录

  4. pandas使用read_csv函数读取文件最后N行数据并保留表头、pandas使用read_csv函数读取网络url链接数据

    pandas使用read_csv函数读取文件最后N行数据并保留表头.pandas使用read_csv函数读取网络url链接数据 目录

  5. 读取txt里面的数据进行计算

    双在论坛上找到一个问题,有关读取txt里面的数据进行计算的问题. 尝试解决这个问题,获取每一行的X和Y的浮点数据即可. 读取文本文件每一行,判断是否为空行,是否符以分隔符号(,)分隔的两个数值.每个数 ...

  6. Apache POI和EasyExcel 第五集:Apache POI的Excel读取不同类型的数据

    Apache POI和EasyExcel 第五集:Apache POI的Excel读取不同类型的数据 一.资源 什么是Apache POI Apache POI 不同类型的数据的表格(xls) 链接: ...

  7. Spark读取Hive中的数据加载为DataFrame

    首先要告诉SparkSql,Hive在哪.然后读取Hive中的数据,必须开启enableHiveSupport. val spark = SparkSession.builder().appName( ...

  8. Spark读取MySQL中的数据为DataFrame

    Spark读取JDBC中的数据(以MySQL为例)为DataFrame,有两种方式. //聚合的时候默认分区是200,可以在此设置 val spark = SparkSession.builder() ...

  9. python如何读取excel数据-使用Python读取电子表格中的数据

    Python 是最流行.功能最强大的编程语言之一.由于它是自由开源的,因此每个人都可以使用.大多数 Fedora 系统都已安装了该语言.Python 可用于多种任务,其中包括处理逗号分隔值(CSV)数 ...

最新文章

  1. 独家 | PyCaret 2.1横空出世-有什么新的内容?
  2. 树的Prufer 编码和最小生成树计数
  3. 韦东山衔接班——4.4_构建根文件系统之构建根文件系统
  4. ARM指令 LDR 和 ADR的一些区别
  5. 浅析NVR主流芯片方案
  6. PNG免扣素材,快速提升你的画面设计感!
  7. composer安装扩展包异常
  8. c语言中专业英文词汇的意思,c语言常见专业英语词汇
  9. 【笔记】人工智能 一种现代方法 人工智能 一种现代方法 第6章 用搜索树对问题求解
  10. MYSQL选修课的心得体会_选修课心得体会【优秀篇】
  11. Referrer 还是 Referer?
  12. RK系列SDK -- Android HFP蓝牙通话音频处理(蓝牙音箱方案)
  13. 查询宇宙生命的家谱--TaxonKit工具详解
  14. QT编译时查找不到GL /usr/bin/ld cannot find -lGL
  15. 大学学python用记笔记吗_python笔记(1)-关于我们应不应该继续学习
  16. pl/sql完全破解
  17. cocos2d中getasynckeystate android,分析Cocos2d-x横版ACT手游源代码 4、场景
  18. 第55篇 Chrome扩展USB开发(一)及PHP研究 Saturday
  19. switch两个账号合并_Switch如何绑定任天堂网络ID?
  20. PTA 7-51 生化危机 (25分) dfs

热门文章

  1. Mobiscroll的介绍【一款兼容PC和移动设备的滑动插件】
  2. Exception from HRESULT: 0x800A03EC
  3. oracle 9i从入门到精通读书笔记2
  4. C、CPP const 详解
  5. 【Breadth-first Search 】专题3
  6. [Leedcode][JAVA][第139题][单词拆分][递归][记忆优化][动态规划]
  7. HDU - 5441 Travel 离线处理+并查集
  8. python中math库最大值_python-math库解析
  9. 用批处理实现文本文件中指定字符串的替换 zz
  10. 51单片机基本刷屏测试实验_基于单片机的发动机振动速度、位移和加速度测量方法...