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. 基于python实现顺序存储的栈

    """ 栈 sstack.py 栈模型的顺序存储 重点代码 思路总结: 1.列表是顺序存储,但功能多,不符合栈的模型特征 2.利用列表,将其封装,提供接口方法 " ...

  2. 什么是 C 和 C ++ 标准库?学编程的你应该知道这些知识!

    简要介绍编写C/C ++应用程序的领域,标准库的作用以及它是如何在各种操作系统中实现的. 我已经接触C++一段时间了,一开始就让我感到疑惑的是其内部结构:我所使用的内核函数和类从何而来? 谁发明了它们 ...

  3. 转 RabbitMQ 入门教程(PHP版) 使用rabbitmq-delayed-message-exchange插件实现延迟功能

    延迟任务应用场景 场景一:物联网系统经常会遇到向终端下发命令,如果命令一段时间没有应答,就需要设置成超时. 场景二:订单下单之后30分钟后,如果用户没有付钱,则系统自动取消订单. 场景三:过1分钟给新 ...

  4. spring boot:在项目中引入第三方外部jar包集成为本地jar包(spring boot 2.3.2)

    一,为什么要集成外部jar包? 不是所有的第三方库都会上传到mvnrepository, 这时我们如果想集成它的第三方库,则需要直接在项目中集成它们的jar包, 在操作上还是很简单的, 这里用luos ...

  5. Python中while循环初识

    基本结构 ​ while 条件: ​ 循环体 基本原理: ​ 1.先判断条件是否为True ​ 2.如果是True进入循环体 ​ 3.执行到循环体的底部 ​ 4.继续判断条件,条件为True,再次进入 ...

  6. 解决加密PDF文档无法复制文字的问题

    有的时候在网络上搜索到一篇心仪的PDF文档,想复制其中内容时提示无法复制. 如果只想摘抄其中部分文字内容,可以使用Firefox浏览器打开这篇加密文档. Firefox浏览器自带PDF插件,打开后即可 ...

  7. java 第一课 笔记

    java是一种解释型语言 Java提供了内存自动管理:不涉及指针:单继承. classpath:字节码文件的路径,执行java.exe时,会查找并解释*.class文件 set classpath=. ...

  8. openspiel 随笔 05.05

    现阶段的任务是向openspiel 中添加e一个自己的游戏 上次已经将大体的逻辑写完了,但运行时出了问题.state 为空. Incorrect number of characters in str ...

  9. Oracle一些常用操作语句

    --创建oracle登录用户 create user CHECKDATAUSER   identified by "bsoft"   default tablespace PBPG ...

  10. Redis---02Redis的Java客户端

    一.注意 连接Linux里面安装的Redis,需要执行以下步骤: ①禁用防火墙(CentOS 7):systemctl stop firewalld.service ②在redis.conf中注释掉 ...