ceph运维大宝剑之osd内存调查
写在前面
松鼠哥的ceph专业课程上线啦!
面向新手同学,从0实战,全面入门ceph安装部署与运维,有需要的同学赶紧扫码订购吧:
最近不少读者反映我的博客访问不了,这里说明一下,博客的主机同时也是梯子,临近国庆,因为一些你懂的原因,所以暂时访问不了,在国内建的话手续真的太麻烦了,不过公众号还是会照常更新
这次的大宝剑是osd内存方面的问题,版本为ceph version 13.2.5 mimic
有关内存的一些事
在使用ceph的时候,经常会遇到两个问题
- osd内存应该分配多少才合适
- osd内存为什么会不停地上涨
关于第一个问题,osd分配多少内存合适呢?官方推荐是1TB的磁盘容量对应1GB的内存,要按照这个标准,我们一台节点有36块8TB的磁盘,这要288GB内存,成本太高了,所以这并不是合适的值,我们希望使用一个较低的值,但又不希望性能降低太多,是多少呢?
这个值的设定没有一个统一的标准,其应该根据具体环境的性能要求和硬件配置来决定
从我们实际的使用效果来看,在有ssd做元数据存储池的情况下,8TB的磁盘的osd内存限制在2GB左右是一个比较理想的值,部分环境机器配置较低的情况下(38*8T盘+64GB内存),我们将单osd内存限制在1GB,目前还没有发现什么问题,性能也完全满足客户要求
关于第二个问题,在我们实际使用中,也有发现osd内存不停上涨的现象,至少在较长的一段时间内,它就是在一直涨,通过调查,我们能够知道它的原因,也是本篇的重点
起因
我们有个环境已经接入了客户,使用rbd全天写入,流量不大,但对象很小,内存限制在1GB
1 | [osd] |
然鹅,用不了几天,在集群健康的情况下,不少osd的内存涨到了2.5GB!,osd节点的总内存才96GB,共有36个osd(8TB),节点内存使用飙升到90GB,swap被大量使用,在不重启节点osd进行内存释放的情况下,有个别节点出现僵死状态!看起来这个似乎参数并没有起到该有的作用
调查
所幸osd使用tcmalloc进行内存分配,使得我们可以使用专业的工具进行调查
首先安装包
1 | sudo yum install google-perftools |
该工具是用来解读内存dump信息的,安装完成后,我们就可以通过dump出osd的heap信息来得到它的内存情况,事实上我们可以使用下面的方式来跟踪osd内存
1 | ceph tell osd.420 heap start_profiler |
而这样dump出来的信息并没有什么用,我们不知道哪个模块使用了多少内存,所以事实上我们也没有办法得到解决方案,而且,对当前进程进行start_profiler得到的内存heap信息,是从执行start_profiler开始到当下的内存增量情况,此前osd的内存使用情况是无法得到的
我们希望osd启动后就开始跟踪内存使用情况,因此我们在环境变量文件中加入参数
1 | [root@host012 tanweijie]# cat /etc/sysconfig/ceph |
最后一行的参数就是要求osd在启动后即进入内存跟踪模式,注意,启用这个参数后,osd性能会大幅度下降,重启osd将花费更长的时间,因此建议仅重启个别osd来进行排查
接下来,我们重启一个osd,来跟踪它的整个内存分布情况
1 | systemctl restart ceph-osd@420.service |
一段时间后,在/var/log/ceph
可以看到这个osd打出的第一个heap文件,使用pprof打开查看
1 | [root@host012 tanweijie]# /usr/bin/pprof --text /usr/bin/ceph-osd /var/log/ceph/osd.420.profile.0001.heap |more |
这部分数据就非常清晰了
1 | Total表示截至当前时间,记录下来的内存使用总量 |
我们最关心的是前面三列和最后一列的数据,这样我们就能知道osd哪些函数占用了多少内存,哪些函数占用内存最多等,这里由于是在osd启动过程中记录,所以量还不是很大
为了全面跟踪osd的内存使用,我们让程序跟踪这个osd一个晚上,看看最终内存稳定的时候,是如何分布的,隔天早上的结果是
1 | [root@host012 tanweijie]# /usr/bin/pprof --text /usr/bin/ceph-osd /var/log/ceph/osd.420.profile.0225.heap |more |
从结果来看,最占内存的是rocksdb模块,37%的占用比PGLog还要多,并且对比前一天的信息,可以看出rocksdb一直都是吃内存的大户
其次是PGLog,当对象写入osd时,PGLog负责记录相关信息,这部分信息是需要常驻内存的,因此对象数越多、PG越多,osd占用的内存就会越大
上面两项共占用64.5%,剩下的主要是buffer,ceph的buffer是其处理各种op和中间数据必不可少的,能不动就不动
虽然这个osd占用的内存还没有达到此前的2.5GB的值,但是从分析结果来看,已经可以得到明显的信息,就是rocksdb耗的内存非常多,针对这种情况,我们来看下rocksdb的参数
温故知新
对rocksdb比较熟悉的朋友应该知道,rocksdb的整个写入机制中,有一个关键的结构叫memtable,它是数据写入db的第一步,写完memtable,然后去写wal,写入就会返回,写满的memtable会转变成immutable,相关参数如下
write_buffer_size - 控制memtable的大小,ceph默认是256MB
max_write_buffer_number - 控制内存中memtable的最大数量,根据内存大小来设置
min_write_buffer_number_to_merge - 控制触发flush所需要的immutable数
而在我们的环境中,早期测试追求性能,设置了write_buffer_size为512M,且min_write_buffer_number_to_merge设置为4,于是仅memtable最大使用内存就能达到2GB,所以会出现osd内存在持续增长,参数无法限制的现象,从参数上看,这些osd的内存是在3GB左右
于是,我们对该参数进行了修改,降低为64MB,重启生效后,连续跑几天,内存稳定在1GB上下
总结
本次的大宝剑遇到的问题并不复杂,从参数配置上就能够看出来的,本篇的重点是分析osd内存分布的方法和思路,同时对osd内存的使用进行梳理,供各位读者参考
- 本文作者: 奋斗的松鼠
- 本文链接: http://www.strugglesquirrel.com/2020/01/23/ceph运维大宝剑之osd内存调查/
- 版权声明: 本博客所有文章除特别声明外,创作版权均为作者个人所有,未经允许禁止转载!