http://www.zphj1987.com/2016/09/19/%E6%9B%BF%E6%8D%A2OSD%E6%93%8D%E4%BD%9C%E7%9A%84%E4%BC%98%E5%8C%96%E4%B8%8E%E5%88%86%E6%9E%90/

之前有写过一篇删除OSD的正确方式,里面只是简单的讲了下删除的方式怎样能减少迁移量,本篇属于一个扩展,讲述了 Ceph 运维当中经常出现的坏盘提换盘的步骤的优化

基础环境两台主机每台主机8个 OSD,一共 16 个 OSD,副本设置为2,PG 数设置为800,计算下来平均每个 OSD 上的 P G数目为100个,本篇将通过数据来分析不同的处理方法的差别

开始测试前先把环境设置为 noout,然后通过停止 OSD 来模拟 OSD 出现了异常,之后进行不同处理方法

测试三种方法

首先 out 一个 OSD,然后剔除 OSD,然后增加 OSD

  1. 停止指定 OSD 进程
  2. out 指定 OSD
  3. crush remove 指定 OSD
  4. 增加一个新的 OSD

一般生产环境会设置为 noout,当然不设置也可以,那就交给程序去控制节点的 out,默认是在进程停止后的五分钟,总之这个地方如果有 out 触发,不管是人为触发,还是自动触发数据流是一定的,我们这里为了便于测试,使用的是人为触发,上面提到的预制环境就是设置的 noout

开始测试前获取最原始的分布

[root@lab8106 ~]# ceph pg dump pgs|awk '{print $1,$15}'|grep -v pg   > pg1.txt

获取当前的 PG 分布,保存到文件pg1.txt,这个 PG 分布记录是 PG 所在的 OSD,记录下来,方便后面进行比较,从而得出需要迁移的数据

停止指定的 OSD 进程

[root@lab8106 ~]# systemctl stop ceph-osd@15

停止进程并不会触发迁移,只会引起 PG 状态的变化,比如原来主 PG 在停止的 OSD 上,那么停止掉 OSD 以后,原来的副本的那个 PG 就会角色升级为主 PG 了

out 掉一个 OSD

[root@lab8106 ~]# ceph osd out 15

在触发 out 以前,当前的 PG 状态应该有 active+undersized+degraded,触发 out 以后,所有的 PG 的状态应该会慢慢变成 active+clean,等待集群正常后,再次查询当前的 PG 分布状态

[root@lab8106 ~]# ceph pg dump pgs|awk '{print $1,$15}'|grep -v pg   > pg2.txt

保存当前的 PG 分布为pg2.txt
比较 out 前后的 PG 的变化情况,下面是比较具体的变化情况,只列出变化的部分

[root@lab8106 ~]# diff -y -W 100 pg1.txt pg2.txt  --suppress-common-lines

这里我们关心的是变动的数目,只统计变动的 PG 的数目

[root@lab8106 ~]# diff -y -W 100 pg1.txt pg2.txt  --suppress-common-lines|wc -l
102

第一次 out 以后有102个 PG 的变动,这个数字记住,后面的统计会用到

从 crush 里面删除 OSD

[root@lab8106 ~]# ceph osd crush remove osd.15

crush 删除以后同样会触发迁移,等待 PG 的均衡,也就是全部变成 active+clean 状态

[root@lab8106 ~]# ceph pg dump pgs|awk '{print $1,$15}'|grep -v pg   > pg3.txt

获取当前的 PG 分布的状态
现在来比较 crush remove 前后的 PG 变动

[root@lab8106 ~]# diff -y -W 100 pg2.txt pg3.txt  --suppress-common-lines|wc -l
137

我们重新加上新的 OSD

[root@lab8106 ~]# ceph-deploy osd prepare lab8107:/dev/sdi
[root@lab8106 ~]# ceph-deploy osd activate lab8107:/dev/sdi1

加完以后统计当前的新的 PG 状态

[root@lab8106 ~]# ceph pg dump pgs|awk '{print $1,$15}'|grep -v pg   > pg4.txt

比较前后的变化

[root@lab8106 ~]# diff -y -W 100 pg3.txt pg4.txt  --suppress-common-lines|wc -l
167

整个替换流程完毕,统计上面的 PG 总的变动

102 +137 +167 = 406

也就是按这个方法的变动为406个 PG,因为是只有双主机,里面可能存在某些放大问题,这里不做深入的讨论,因为我的三组测试环境都是一样的情况,只做横向比较,原理相通,这里是用数据来分析出差别

先crush reweight 0 ,然后out,然后再增加osd

首先恢复环境为测试前的环境

[root@lab8106 ~]# ceph pg dump pgs|awk '{print $1,$15}'|grep -v pg   > 2pg1.txt

记录最原始的 PG 分布情况

crush reweight 指定OSD

[root@lab8106 ~]# ceph osd crush reweight osd.16 0
reweighted item id 16 name 'osd.16' to 0 in crush map

等待平衡了以后记录当前的 PG 分布状态

[root@lab8106 ~]# ceph pg dump pgs|awk '{print $1,$15}'|grep -v pg   > 2pg2.txt
dumped pgs in format plain

比较前后的变动

[root@lab8106 ~]# diff -y -W 100 2pg1.txt 2pg2.txt  --suppress-common-lines|wc -l
166

crush remove 指定 OSD

[root@lab8106 ~]# ceph osd crush remove osd.16
removed item id 16 name 'osd.16' from crush map

这个地方因为上面 crush 已经是0了所以删除也不会引起 PG 变动
然后直接 ceph osd rm osd.16 同样没有 PG 变动

增加新的 OSD

[root@lab8106 ~]#ceph-deploy osd prepare lab8107:/dev/sdi
[root@lab8106 ~]#ceph-deploy osd activate lab8107:/dev/sdi1

等待平衡以后获取当前的 PG 分布

[root@lab8106 ceph]# ceph pg dump pgs|awk '{print $1,$15}'|grep -v pg   > 2pg3.txt

来比较前后的变化

[root@lab8106 ~]# diff -y -W 100 2pg2.txt 2pg3.txt --suppress-common-lines|wc -l
159

总的 PG 变动为

166+159=325

开始做norebalance,然后做crush remove,然后做add

恢复环境为初始环境,然后获取当前的 PG 分布

[root@lab8106 ~]# ceph pg dump pgs|awk '{print $1,$15}'|grep -v pg   > 3pg1.txt
dumped pgs in format plain

给集群做多种标记,防止迁移

设置为 norebalance,nobackfill,norecover,后面是有地方会解除这些设置的

[root@lab8106 ~]# ceph osd set norebalance
set norebalance
[root@lab8106 ~]# ceph osd set nobackfill
set nobackfill
[root@lab8106 ~]# ceph osd set norecover
set norecover

crush reweight 指定 OSD

[root@lab8106 ~]# ceph osd crush reweight osd.15 0
reweighted item id 15 name 'osd.15' to 0 in crush map

这个地方因为已经做了上面的标记,所以只会出现状态变化,而没有真正的迁移,我们也先统计一下

[root@lab8106 ~]# ceph pg dump pgs|awk '{print $1,$15}'|grep -v pg   > 3pg2.txt
[root@lab8106 ~]# diff -y -W 100 3pg1.txt 3pg2.txt --suppress-common-lines|wc -l
158

注意这里只是计算了,并没有真正的数据变动,可以通过监控两台的主机的网络流量来判断,所以这里的变动并不用计算到需要迁移的 PG 数目当中

crush remove 指定 OSD

[root@lab8106 ~]#ceph osd crush remove osd.15

删除指定的 OSD

删除以后同样是没有 PG 的变动的

ceph osd rm osd.15

这个地方有个小地方需要注意一下,不做 ceph auth del osd.15 把15的编号留着,这样好判断前后的 PG 的变化,不然相同的编号,就无法判断是不是做了迁移了

增加新的 OSD

[root@lab8106 ~]#ceph-deploy osd prepare lab8107:/dev/sdi
[root@lab8106 ~]#ceph-deploy osd activate lab8107:/dev/sdi1

我的环境下,新增的 OSD 的编号为16了

解除各种标记

我们放开上面的设置,看下数据的变动情况

[root@lab8106 ceph]# ceph osd unset norebalance
unset norebalance
[root@lab8106 ceph]# ceph osd unset nobackfill
unset nobackfill
[root@lab8106 ceph]# ceph osd unset norecover
unset norecover

设置完了后数据才真正开始变动了,可以通过观察网卡流量看到,来看下最终pg变化

[root@lab8106 ceph]# ceph pg dump pgs|awk '{print $1,$15}'|grep -v pg   > 3pg3.txt
dumped pgs in format plain
[root@lab8106 ~]# diff -y -W 100 3pg1.txt 3pg3.txt --suppress-common-lines|wc -l
195

这里我们只需要跟最开始的 PG 分布状况进行比较就可以了,因为中间的状态实际上都没有做数据的迁移,所以不需要统计进去,可以看到这个地方动了195个 PG
总共的 PG 迁移量为

195

数据汇总

现在通过表格来对比下三种方法的迁移量的比较(括号内为迁移 PG 数目)

  方法一 方法二 方法三
所做操作 stop osd (0)
out osd(102)
crush remove osd (137)
add osd(167)
crush reweight osd(166)
out osd(0)
crush remove osd (0)
add osd(159)
set 标记(0)
crush reweight osd(0)
crush remove osd (0)
add osd(195)
PG迁移数量 406 325 195

可以很清楚的看到三种不同的方法,最终的触发的迁移量是不同的,处理的好的话,能节约差不多一半的迁移的数据量,这个对于生产环境来说还是很好的,关于这个建议先在测试环境上进行测试,然后再操作,上面的操作只要不对磁盘进行格式化,操作都是可逆的,也就是可以比较放心的做,记住所做的操作,每一步都做完都去检查 PG 的状态是否是正常的

总结

从我自己的操作经验来看,最开始是用的第一种方法,后面就用第二种方法减少了一部分迁移量,最近看到资料写做剔除OSD的时候可以关闭迁移防止无效的过多的迁移,然后就测试了一下,确实能够减少不少的迁移量,这个减少在某些场景下还是很好的,当然如果不太熟悉,用哪一种都可以,最终能达到的目的是一样的

附加

有人问到一个问题,为什么按照这个流程操作的时候,会出现slow request?在进行了一次验证后,发现在迁移过程中的请求路径还是很长的,所以出现slow request还是很容易的

假如我们有三个osd,分别为0,1,2,里面有各种的分布,我们在踢掉一个osd.2后,可能出现的一个情况是
某个PG(0.3b)的[2,0]分布变成了[1,0]
而此时后台的osd.1的PG(0.3b)这个目录里面的内容实际是空的,如果这个时候,前端的请求一个对象正好是分布在0.3b这个PG上的时候,后台需要先将osd.0上面的这个0.3b的对象写入到osd.1的0.3b的pg里面去,然后再去响应客户端的请求,自然路径就长了,如果这样的请求一多,响应前台的性能就有问题了,增加节点的时候同理

请求到这种空PG的对象,PG的状态会这样变化:

从active+degraded 变成active+recovery_wait+degraded

迁移的数据量是一定的,这个看是请求的时候实时迁移然后响应还是提前迁移,然后响应,所以这个中间操作过程尽量的快的完成,然后好迁移完响应前端的请求

替换OSD操作的优化与分析的更多相关文章

  1. 转——Android应用开发性能优化完全分析

    [工匠若水 http://blog.csdn.net/yanbober 转载请注明出处.] 1 背景 其实有点不想写这篇文章的,但是又想写,有些矛盾.不想写的原因是随便上网一搜一堆关于性能的建议,感觉 ...

  2. Android 应用开发性能优化完全分析

    1 背景 其实有点不想写这篇文章的,但是又想写,有些矛盾.不想写的原因是随便上网一搜一堆关于性能的建议,感觉大家你一总结.我一总结的都说到了很多优化注意事项,但是看过这些文章后大多数存在一个问题就是只 ...

  3. 【转】Android应用开发性能优化完全分析

    http://blog.csdn.net/yanbober/article/details/48394201 1 背景 其实有点不想写这篇文章的,但是又想写,有些矛盾.不想写的原因是随便上网一搜一堆关 ...

  4. Android应用开发性能优化完全分析

    1 背景 其实有点不想写这篇文章的,但是又想写,有些矛盾.不想写的原因是随便上网一搜一堆关于性能的建议,感觉大家你一总结.我一总结的都说到了很多优化注意事项,但是看过这些文章后大多数存在一个问题就是只 ...

  5. 转:Android应用开发性能优化完全分析

    转自:http://blog.csdn.net/yanbober/article/details/48394201 1 背景 其实有点不想写这篇文章的,但是又想写,有些矛盾.不想写的原因是随便上网一搜 ...

  6. SQL优化-如何分析性能瓶颈

    MySQL优化一览图 笔者将优化分为了两大类:软优化和硬优化.软优化一般是操作数据库即可:而硬优化则是操作服务器硬件及参数设置. 1.软优化 1)查询语句优化 首先我们可以用EXPLAIN或DESCR ...

  7. MySQL优化 - 性能分析与查询优化(转)

    出处:  MySQL优化 - 性能分析与查询优化 优化应贯穿整个产品开发周期中,比如编写复杂SQL时查看执行计划,安装MySQL服务器时尽量合理配置(见过太多完全使用默认配置安装的情况),根据应用负载 ...

  8. apache kafka系列之性能优化架构分析

    apache kafka中国社区QQ群:162272557 Apache kafka性能优化架构分析 应用程序优化:数据压缩 watermark/2/text/aHR0cDovL2Jsb2cuY3Nk ...

  9. Java I/O 操作及优化建议

    Java I/O I/O,即 Input/Output(输入/输出) 的简称.就 I/O 而言.概念上有 5 种模型:blocking I/O.nonblocking I/O,I/O multiple ...

随机推荐

  1. Sending form data

    https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_and_retrieving_form_data This arti ...

  2. JSP_01

    1.定义局部变量.输出语句 <!doctype html> <html> <head> <title>定义局部变量.输出语句</title> ...

  3. Island Transport 【HDU - 4280】【最大流Dinic】

    题目链接 可以说是真的把时间卡爆了,不断的修改了好多次之后才A了,一直T一直T,哭了…… 可以说是很练时间优化了,不断的改,不断的提交,最后竟然是改了Dinic中的BFS()中,我们一旦搜索到了T之后 ...

  4. [SDOI2019]快速查询

    [SDOI2019]快速查询 [题目链接] 链接 [思路要点] 据说是 \(\text{SDOI2019}\) 最水的题 操作次数为 \(1e7\) 范围,显然要求每次操作 \(\mathcal{O} ...

  5. json字符串格式

    private static final String COMPLEX_JSON_STR = "{" + "\"teacherName\":\&quo ...

  6. JVM(Java虚拟机)详解(JDK7)

    1.Java内存区域 运行时数据区域: Java 虚拟机在执行Java程序时,定义了若干种程序运行期间会使用到的运行时数据区,其中有一些会随着虚拟机启动而创建,随着虚拟机退出而销毁.另外一些则是与线程 ...

  7. 小Q的棋盘 (贪心)

    小Q的棋盘 (贪心) 题目 洛谷传送门 做法 显然这是一棵树(这个就不多bb了,树的性质) 很容易发现一个性质,如果一条链走完,我们必须回头再走一次那条链(或一部分)才可以走到更多的点 所以为了减少这 ...

  8. #python# error:UnicodeEncodeError: 'latin-1' codec can't encode character '\u2026' in position 30: ordinal not in range(256)

    headers={ 'Referer':'https://www.lagou.com/jobs/lis-rds=&fromSearch=true&suginput=', 'User-A ...

  9. day65--mysql数据库--索引、慢日志、分页

    ---恢复内容开始--- 一.索引 (一)介绍: 数据库中专门用于帮助用户快速查找数据的一种数据结构.类似于字典中的目录,查找字典内容时可以根据目录查找到数据的存放位置吗,然后直接获取. (二)作用: ...

  10. elasticsearch 基础 —— Field Collapsing字段折叠

    允许根据字段值折叠搜索结果.通过按折叠键选择顶部排序文档来完成折叠.例如,下面的查询检索每个用户的最佳推文,并按喜欢的数量对它们进行排序. GET /twitter/_search { "q ...