ceph是目前开源分布式存储里面最好的一个,但是在高负载下会有很多异常的情况会发生,有些问题无法完全避免,但是可以进行一定的控制,比如:在虚拟化场景下,重启osd会让虚拟机挂起的情况

重新启动osd会给这个osd进程所在的磁盘带来额外的负载,随着前面业务的需求的增长,会增加对存储的I/O的需求,虽然这个对于整个业务系统来说是好事,但是在某些情况下,会越来越接近存储吞吐量的极限,通常情况下没有异常发生的时候,都是正常的,一旦发生异常,集群超过了临界值,性能会变得剧烈的抖动

对于这种情况,一般会升级硬件来避免集群从一个高负载的集群变成一个过载的集群。本章节的重点在重启osd进程这个问题

问题分析

OSD重启是需要重视的,这个地方是ceph的一个设计的弱点。ceph集群有很多的OSD进程,OSD管理对磁盘上的对象的访问,磁盘的对象被分布到PG组当中,对象有相同的分布,副本会在相同的PG当中存在,如果不理解可以看看(ceph概览

当集群OSD进程出现down的情况,会被mon认为 "OUT" 了,这个 "OUT" 不是触发迁移的那个 "OUT",是不服务的 "OUT" ,这个OSD上受影响的PG的I/O请求会被其他拥有这个PG的OSD接管,当OSD重新启动的时候,OSD会被加入进来,将会检查PG,看是否有在down的期间错过东西,然后进行更新,这里问题就来了,启动之后会访问磁盘检查PG是否有缺失的东西进行更新,会进行一定量的数据恢复,同时会开始接受新的IO的请求,如果本来磁盘就只剩很少的余量,那么一旦请求发送到这个OSD上,那么性能将会开始下降

如果去看ceph的邮件列表,在极端情况下,这种效应会让整个集群停机,这发生在OSD太忙了,连心跳都无法回复,然后mon就会把它标记为down,这个时候OSD的进程都还在的,这个时候客户端的请求会导入到其他的OSD上,然后负载小了,OSD又会自己进来,然后又开始响应请求了,然后之前没有受影响的OSD节点,需要把新写入的数据同步过来,这个又增加了其他的OSD的负载了,一旦集群接近I/O的限制,也会让其他的OSD无法响应了,结果就是整个集群的OSD在反复的"in"和"out"状态之间变化了,集群在这种情况下,就无法接收客户端的请求了,如果不人工干预甚至无法恢复正常,这个在高负载下是很好复现出来的;另外一种较轻的情况,在OSD重启过程,I/O可能会hung住,影响性能.如果不能避免,至少能想办法去降低这个影响

我们能做些什么?在ceph开发者列表当中有开发者提出了这个设计上需要修复,这个估计需要等很久以后的事情了,我们能做什么来降低这个的影响?最明显的一点是要保证集群有足够的I/O的余量,另一种思路就是减少关键过程启动检查和接收I/O的竞争

减少OSD启动过程当中的IO

OSD在启动的时候可以预测到磁盘的访问的模式。我们可以了解这个访问模式,然后提前将文件读取到内核的缓存当中。这样这些文件在启动的时候就不需要再次访问磁盘了,意味着更少的磁盘消耗和更好的性能

现在来定位下OSD启动过程中做了哪些事情,使用性能大师 Brendan Gregg 的 opensnoop 工具,一个OSD启动的过程如下:

OSD启动过程

[root@lab8106 ~]# opensnoop ceph-7
Tracing open()s for filenames containing "ceph-7". Ctrl-C to end.
COMM PID FD FILE
ceph osd 0x3 /var/lib/ceph/osd/ceph-7/
ceph osd 0x4 /var/lib/ceph/osd/ceph-7/type
ceph osd 0x4 /var/lib/ceph/osd/ceph-7/magic
ceph osd 0x4 /var/lib/ceph/osd/ceph-7/whoami
ceph osd 0x4 /var/lib/ceph/osd/ceph-7/ceph_fsid
ceph osd 0x4 /var/lib/ceph/osd/ceph-7/fsid
ceph osd 0xb /var/lib/ceph/osd/ceph-7/fsid
ceph osd 0xb /var/lib/ceph/osd/ceph-7/fsid
ceph osd 0xc /var/lib/ceph/osd/ceph-7/store_version
ceph osd 0xc /var/lib/ceph/osd/ceph-7/superblock
ceph osd 0xc /var/lib/ceph/osd/ceph-7
ceph osd 0xd /var/lib/ceph/osd/ceph-7/fiemap_test
ceph osd 0xd /var/lib/ceph/osd/ceph-7/xattr_test
ceph osd 0xd /var/lib/ceph/osd/ceph-7/current
ceph osd 0xe /var/lib/ceph/osd/ceph-7/current/commit_op_seq
ceph osd 0xf /var/lib/ceph/osd/ceph-7/current/omap/LOCK
ceph osd 0x10 /var/lib/ceph/osd/ceph-7/current/omap/CURRENT
ceph osd 0x10 /var/lib/ceph/osd/ceph-7/current/omap/MANIFEST-000135

开始的时候,OSD读取了很多元数据文件,没有什么特别的

下面读取omap的数据库文件,读取了一部分的osdmap文件

ceph             osd    0x10 /var/lib/ceph/osd/ceph-7/current/omap/000137.log
ceph osd 0x11 /var/lib/ceph/osd/ceph-7/current/omap/000143.sst
ceph osd 0x11 /var/lib/ceph/osd/ceph-7/current/omap/000143.sst
ceph osd 0x10 /var/lib/ceph/osd/ceph-7/current/omap/000144.log
ceph osd 0x11 /var/lib/ceph/osd/ceph-7/current/omap/MANIFEST-000142
ceph osd 0x12 /var/lib/ceph/osd/ceph-7/current/omap/000142.dbtmp
ceph osd 0x12 /var/lib/ceph/osd/ceph-7/current/omap/000138.sst
ceph osd 0x12 /var/lib/ceph/osd/ceph-7/journal
ceph osd 0x12 /var/lib/ceph/osd/ceph-7/journal
ceph osd 0x13 /var/lib/ceph/osd/ceph-7/store_version
ceph osd 0x13 /var/lib/ceph/osd/ceph-7/current/meta/osd\usuperblock__0_23C2FCDE__none
ceph osd 0x14 /var/lib/ceph/osd/ceph-7/current/meta/DIR_5/osdmap.298__0_AC96EE75__none
ceph osd 0x15 /var/lib/ceph/osd/ceph-7/current/0.3b_head
ceph osd 0x15 /var/lib/ceph/osd/ceph-7/current/meta/DIR_5/osdmap.297__0_AC96EEA5__none
ceph osd 0x16 /var/lib/ceph/osd/ceph-7/current/0.7_head
ceph osd 0x16 /var/lib/ceph/osd/ceph-7/current/0.34_head
ceph osd 0x16 /var/lib/ceph/osd/ceph-7/current/0.20_head
ceph osd 0x16 /var/lib/ceph/osd/ceph-7/current/0.22_head

可以看到读取一个sst后,就会继续读取pg的目录

ceph             osd    0x16 /var/lib/ceph/osd/ceph-7/current/omap/000139.sst
ceph osd 0x16 /var/lib/ceph/osd/ceph-7/current/0.ec_head
ceph osd 0x16 /var/lib/ceph/osd/ceph-7/current/0.7e_head
ceph osd 0x16 /var/lib/ceph/osd/ceph-7/current/0.14b_head
[···]
ceph osd 0x16 /var/lib/ceph/osd/ceph-7/current/omap/000141.sst
ceph osd 0x16 /var/lib/ceph/osd/ceph-7/current/0.2fb_head
ceph osd 0x16 /var/lib/ceph/osd/ceph-7/current/0.cf_head
ceph osd 0x16 /var/lib/ceph/osd/ceph-7/current/0.10f_head
[···]
ceph osd 0x16 /var/lib/ceph/osd/ceph-7/current/omap/000140.sst
ceph osd 0x16 /var/lib/ceph/osd/ceph-7/current/0.8f_head
ceph osd 0x16 /var/lib/ceph/osd/ceph-7/current/0.10c_head
ceph osd 0x16 /var/lib/ceph/osd/ceph-7/current/0.14e_head
[···]

然后会读取每个pg里面的_head_文件

tp_fstore_op     23688  0x17 /var/lib/ceph/osd/ceph-7/current/0.23a_head/__head_0000023A__0
tp_fstore_op 23688 0x18 /var/lib/ceph/osd/ceph-7/current/0.1a2_head/DIR_2/DIR_A/DIR_1/__head_000001A2__0
<...> 23689 0x19 /var/lib/ceph/osd/ceph-7/current/0.2ea_head/__head_000002EA__0
[···]

然后会进行osdmap文件的操作

tp_fstore_op     23688  0x3a /var/lib/ceph/osd/ceph-7/current/meta/DIR_2/inc\uosdmap.299__0_C67CF872__none
tp_fstore_op 23688 0x4e /var/lib/ceph/osd/ceph-7/current/meta/DIR_5/osdmap.299__0_AC96EF05__none
tp_fstore_op 23688 0x14 /var/lib/ceph/osd/ceph-7/current/meta/DIR_2/inc\uosdmap.300__0_C67CF142__none
tp_fstore_op 23688 0x4f /var/lib/ceph/osd/ceph-7/current/meta/DIR_5/osdmap.300__0_AC96E415__none
tp_fstore_op 23688 0x15 /var/lib/ceph/osd/ceph-7/current/meta/osd\usuperblock__0_23C2FCDE__none
tp_fstore_op 23689 0x6e /var/lib/ceph/osd/ceph-7/current/meta/DIR_2/inc\uosdmap.301__0_C67CF612__none
tp_fstore_op 23689 0x55 /var/lib/ceph/osd/ceph-7/current/meta/DIR_5/osdmap.301__0_AC96E5A5__none
tp_fstore_op 23689 0xbf /var/lib/ceph/osd/ceph-7/current/meta/DIR_2/inc\uosdmap.302__0_C67CF7A2__none
tp_fstore_op 23689 0x60 /var/lib/ceph/osd/ceph-7/current/meta/DIR_5/osdmap.302__0_AC96E575__none
tp_fstore_op 23688 0x86 /var/lib/ceph/osd/ceph-7/current/meta/DIR_2/inc\uosdmap.303__0_C67CF772__none
tp_fstore_op 23688 0x6a /var/lib/ceph/osd/ceph-7/current/meta/DIR_5/osdmap.303__0_AC96FA05__none
s

我们无法确定哪些对象将需要读取,单我们知道,所有的OMAP和元数据文件将会打开,_head_文件将会打开

使用vmtouch进行预读取

下面将进入 vmtouch ,这个小工具能够读取文件并锁定到内存当中,这样后续的I/O请求能够从缓存当中读取它们,这样就减少了对磁盘的访问请求

在这里我们的访问模式是这样的:

[root@lab8106 ceph-7]# vmtouch -t /var/lib/ceph/osd/ceph-7/current/meta/ /var/lib/ceph/osd/ceph-7/current/omap/
Files: 618
Directories: 6
Touched Pages: 3972 (15M)
Elapsed: 0.009621 seconds

关于这个vmtouch很好使用也很强大,可以使用 vmtouch -L 将数据锁定到内存当中去,这里用 -t 也可以,使用 -v 参数能打印更多详细的信息,这个效果有多大?这个原作者的效果很好,我的环境太小,看不出太多的效果,但是从原理上看,应该是会有用的,我的读取过程跟原作者的读取过程有一定的差别,作者的数据库文件是 ldb ,我的环境是 sst,并且作者的压力应该是很大的情况下的,我的环境较小

判断是否有作用

一个很好的衡量的方法就是看启动过程当中的 peering 的阶段的长度, peering 状态是osd做相互的协调的,PG的请求在这个时候是无法响应的,理想状况下这个过程会很快,无法察觉,如果集群集群处于高负载或者过载状态,这个持续的时间就会很久,然后关闭一个OSD,然后等待一分钟,以便让一部分写入只写到了其他OSD,在down掉的OSD启动后,需要从其他OSD恢复一些数据,然后重新打开,从日志当中,绘制一段时间的 peering 状态PG的数目,score是统计的所有时间线上 peering 状态的计数的总和

为了验证这个vmtouch将会减少 peering 的状态,将负载压到略小于集群满载情况

第一个实验是OSD重启(无vmtouch)



可以看到超过30s时,大量的pg是peering状态,导致集群出现缓慢

第二个实验中使用vmtouch预读取OMAP的数据库文件



这些 peering 状态并没有消失,但是可以看到有很大的改善 peering 会更早的开始(OMAP已经加载),总体的score也要小很多,这个是一个很不错的结果

结论

根据之前监测到的读取数据的情况,预读取文件,能够有不错的改善,虽然不是完整的解决方案,但是能够帮助改善一个痛点,从长远来看,希望ceph能改进设计,是这个情况消失

总结

本章节里面介绍了两个工具

opensnoop

这个工具已经存在了很久很久了,也是到现在才看到的,一个用于监控文件的操作,是Gregg 大师的作品,仅仅是一个shell脚本就能实现监控,关键还在于其对操作系统的了解

vmtouch

这个是将数据加载到内存的,以前关注的是清理内存,其实在某些场景下,能够预加载到内存将会解决很多问题,关键看怎么去用了

参考文章

Improving Ceph OSD start-up behaviour with vmtouch

opensnoop

vmtouch

变更记录

Why Who When
创建 武汉-运维-磨渣 2016-06-07

加速OSD的启动的更多相关文章

  1. 利用BLCR加速android的启动(zygote加入checkpoint支持)

    目前基于android4.2.2基线代码的blcr扩展,编译和启动是没有问题了,但是一重启就挂了. 弄这个有段时间了,很纠结,没有个可靠的结果,但是研究到现在,又舍不得放弃. 我想除了shuaiwen ...

  2. 利用BLCR加速android的启动(android4.2)

    BOSS要求提高安卓系统的启动速度,优化bootloader和kernel后,发现还是达不到要求,没办法才打起zygote的注意. ================================== ...

  3. ceph存储osd启动异常处理和正常启停操作

    机器角色:cloudstack虚拟机的宿主机:ceph存储机器. 事件:ceph存储的物理机器由于内存异常,需要停机更换,仅仅是把该物理机上面的虚拟机迁移走,同时启动了停机维护,然后就直接关机.结果造 ...

  4. 掉电后osdmap丢失无法启动osd的解决方案

    前言 本篇讲述的是一个比较极端的故障的恢复场景,在整个集群全部服务器突然掉电的时候,osd里面的osdmap可能会出现没刷到磁盘上的情况,这个时候osdmap的最新版本为空或者为没有这个文件 还有一种 ...

  5. 重启osd服务失败:Start request repeated too quickly

    背景 OS:Ubuntu 16.04 修改了osd的一些配置,修改后,需要重启osd服务才能生效.第一次重启后,配置立刻生效.再改了一些配置,重启osd服务后,配置却不再生效了.ps命令查看进程,发现 ...

  6. Ceph OSD服务失效自动启动控制

    前言 服务器上面的服务会因为各种各样的原因失败,磁盘故障,权限问题,或者是服务过载引起超时,这些都可能引起 这个在ceph里面systemctl unit 默认有个on-fail restart,默认 ...

  7. 为什么关不掉所有的OSD

    前言 碰到一个cepher问了一个问题: 为什么我的OSD关闭到最后有92个OSD无法关闭,总共的OSD有300个左右 想起来在很久以前帮人处理过一次问题,当时环境是遇上了一个BUG,需要升级到新版本 ...

  8. Ceph recover的速度控制

    前言 磁盘损坏对于一个大集群来说,可以说是必然发生的事情,即使再小的概率,磁盘量上去,总会坏那么几块盘,这个时候就会触发内部的修复过程,修复就是让不满足副本要求的PG,恢复到满足的情况 一般是踢掉坏盘 ...

  9. 理解 OpenStack + Ceph (9): Ceph 的size/min_size/choose/chooseleaf/scrubbing/repair 等概念

    本系列文章会深入研究 Ceph 以及 Ceph 和 OpenStack 的集成: (1)安装和部署 (2)Ceph RBD 接口和工具 (3)Ceph 物理和逻辑结构 (4)Ceph 的基础数据结构 ...

随机推荐

  1. 你不知道的MySQL,以及MariaDB初体验

    MySQL 是一个跨世纪的伟大产品,它最早诞生于 1979 年,距今已经有 40 多年的历史了,而如今比较主流的 Java 语言也只是 1991 年才诞生的,也就是说 MySQL 要比 Java 的诞 ...

  2. asp.net web 定时执行任务 定时器 Global.asax

    web网站里面,需要每隔1分钟,执行一个任务,并且一直保持这个定时执行状态,可以用如下一个方法: 以下代码是 Global.asax.cs 的全部代码. using System; using Sys ...

  3. swagger使用随笔

    2020-10-21 在一技术群里看到有个大佬想用 swagger 实现个功能:基础 Api 项目中写好通用的接口,配置好 swagger .上级项目直接引用项目,就能访问 swagger 起来用.相 ...

  4. python- pyqt5 一个存疑问题

    首先 我的问题是 自定义的方法中 无法给窗体中增加控件 我们直接看例子 这是一个图书管理系统的窗口 我们给他加上菜单(menuBar) 加上工具栏(QAction) 程序变成了这样 这个界面是这样的( ...

  5. spring cloud oauth2 实现用户认证登录

    spring-cloud-oauth2 实现用户认证及单点登录 需求 ​ 在微服务架构中,我们有很多业务模块,每个模块都需要有用户认证,权限校验.有时候也会接入来自第三方厂商的应用.要求是只登录一次, ...

  6. Libevent库基础(2)

    带缓冲区的事件 bufferevent #include <event2/bufferevent.h> read/write 两个缓冲. 借助 队列. 创建.销毁bufferevent: ...

  7. 微信小程序日历签到

    近日做了一个项目需要用到日历插件,在网上找了一部分感觉跟项目不对口,所以就查考了其他的日历插件做了一个. 需求: 如图: 代码如下: index.wxml: <!--pages/pictrues ...

  8. array_walk_recursive 地址引用报错的问题

    今天看十八哥的视频,学习array_walk_recursive的用法,发现一直报错: PHP版本:5.6.19 代码界面: 报错界面: 查了很长时间,不知道什么问题,后来在网上终于找到原因所在: + ...

  9. 活动可视化搭建系统——你的KPI被我承包了

    前言 对于C端业务偏多的公司来说,在增长.运营等各方同学的摧残下永远绕不过去的一个坑就是大量的H5页面开发,它可能是一个下载.需求告知.产品介绍.营销活动等页面.此类需求都有几个明显的缺点: •开发性 ...

  10. 删除指定路径下指定天数之前(以文件的最后修改日期为准)的文件:BAT + VBS

    代码如下: @echo off ::演示:删除指定路径下指定天数之前(以文件的最后修改日期为准)的文件. ::如果演示结果无误,把del前面的echo去掉,即可实现真正删除. ::本例调用了临时VBS ...