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. redis连接报错:MISCONF Redis is configured to save RDB snapshots, but it is currently not able to...

    连接redis报错: MISCONF Redis is configured to save RDB snapshots, but it is currently not able to persis ...

  2. Vue自定义事件:触发自定义事件

    一 项目结构 二 子组件(Mongo.vue) <template> <button @click="eat">按钮</button> < ...

  3. stl vector创建二维数组

    vector<vector<); for (auto it = v.begin(); it != v.end(); it++) { ; (*it).reserve();//预留空间为5,但 ...

  4. 2019Hdu多校第三场:1007 Find the answer(multiset 解法)

    原题链接: Find the answer c++中,multiset是库中一个非常有用的类型,它可以看成一个序列,插入一个数,删除一个数都能够在O(logn)的时间内完成,而且他能时刻保证序列中的数 ...

  5. hdu6570Wave (暴力求解)

    Problem Description Avin is studying series. A series is called "wave" if the following co ...

  6. 校内模拟赛T5:连续的“包含”子串长度( nekameleoni?) —— 线段树单点修改,区间查询 + 尺取法合并

    nekameleoni 区间查询和修改 给定N,K,M(N个整数序列,范围1~K,M次查询或修改) 如果是修改,则输入三个数,第一个数为1代表修改,第二个数为将N个数中第i个数做修改,第三个数为修改成 ...

  7. MySQL 查询语句--------------进阶9:联合查询

    #进阶9:联合查询 /* union 联合 合并:将多条查询语句的结果合并成一个结果 语法: 查询语句1 union 查询语句2 union..... 应用场景:要查询的结果来自于多个表,且多个表没有 ...

  8. Mimikatz 使用学习

    下载地址 https://github.com/gentilkiwi/mimikatz/ windows:https://download.csdn.net/download/think_ycx/93 ...

  9. c# 调用 webService

    开局几张  照着做就完事 说明下 这个wsdl 文件是根据别人提供的webService 接口 打开后改变后缀来的 这样就引用完成了 接下来就是重点了  怎么调用 localhost.WsSyncDu ...

  10. Linux多线程服务器端编程

    目录 Linux多线程服务器端编程 线程安全的对象生命期管理 对象的销毁线程比较难 线程同步精要 借shared_ptr实现写时拷贝(copy-on-write) 多线程服务器的适用场合与常用编程模型 ...