最近ceph集群发生了一些比较奇怪的现象,搬去另外一个机房的那套集群在恢复正常业务之后,一直有一些问题
写在前面
松鼠哥的ceph专业课程上线啦!
面向新手同学,从0实战,全面入门ceph安装部署与运维,有需要的同学赶紧扫码订购吧:
完成测试后接入实际的业务流量,测试时未能发现的问题在业务运行过程中出现了。
问题现象
问题是由前端业务写入不顺利开始的,前端大量写入图片的程序开始频繁出现TCP连接超时的报错,并伴有不少HTTP 500的错误,目前我们的写行为比较单纯,两套集群写入量是五五开的,但是,一旦有某套集群写入有问题,就会自动剔除该集群的写入,写入量会全部转移到另外一个无问题的集群
排查过程
刚开始,怀疑是两端服务器tcp连接数不够导致,其中ceph这边的tcp连接数被设置成很大,而且搬迁前后并没有发生改动,使用命令统计了一下tcp的连接,未见有超出的现象
在搬迁完成后,我们趁着机器重新开机前,加装了64G内存,从而设备内存增长到314G,由于设备此前使用的是单根64G的内存,所以就直接加装了一根64G的内存,排查发现,numa的内存分布及其不合理,未加内存的node内存被耗尽,另外一个node则空闲很多,会不会是因为部分跑在未加内存的node上,跨node访问引发了性能问题?
1 | [root@ceph-52-204 tanweijie]# numactl -H |
不管是不是这原因,内存分布如果不均匀导致numa的miss很高,也是异常情况,所以做出了调整,将跑在node1上的5个osd调到node0上跑,均衡一下内存使用,确认每个node都剩余超过20G内存后,跑了一晚,竟然好了!没有再出现500错误和连接超时。
在我们要举杯欢庆的时候,白天10点后业务高峰来到后,又开始陆续出现http 500和connection timeout的问题,看来高兴得太早了
后来又陆续怀疑是不是网络问题,我们写入客户端到集群使用了专线,专线最近一直也不稳定,有可能大量的丢包导致上传文件失败引发?而且,出问题的客户端使用的是aws-nodejs的客户端,会不会根这个sdk有关系?
经过排查,使用python boto持续长时间写入竟然不会有问题,那么很可能跟网络没有关系了,况且tcp通信正常的情况下,数据包不容易出现问题,那么是sdk的问题吗?有可能,不同的sdk使用的tcp方式可能有差异,python boto只需要一次连接,使用该连接就可以持续传输数据,看起来是用的长连接,如果nodejs使用的tcp是短连接的话,有可能是并发太高导致rgw扛不住,但是我们测试过,这种并发还是小儿科的,不会扛不住
求助社区
rgw的日志、系统、网络及内存配置等都排查过无果后,笔者将打开的rgw日志中,http 500的完整处理日志提交到了社区
1 | 2018-11-15 16:32:25.897665 7f187d57d700 1 ====== starting new request req=0x7f187d577110 ===== |
社区当晚就给了答复,The '165.197798' in this log output shows that it took over two minutes to complete. It's likely the client timed out and closed the connection. This doesn't look like a bug.
,噢,在put_obj:completing中,165.197798
表示该部分处理花费的时间,是的,花费了超过2分半钟,这导致客户端连接超时,断开连接,从而引发http 500
发现解决办法
其实从上面的分析,已经可以大致分析出问题,rgw处理请求太慢,这会导致连接超时或者现有连接出现http 500的现象,实际上,在运行了几个月后,写入的业务量相对于早期已经提高很多,所以在配置上已经跟不上处理的要求了
前端写入业务此前一直使用短连接进行写入,目的是优化每次的读写,然后实际使用时,长连接会使得http 500和timeout问题变得更严重,这里的问题暂时还没查清楚,但可以确定的是rgw的处理能力跟不上了,要调整的参数应该就是num_threads
,关于这个参数,redhat和官方具体的解释是:
1 | num_threads |
这样看来,每个线程单独处理一个进来的连接,这就意味着,如果当前连接数已经饱和,新的连接则需要等待,如果一直等不到,就timeout,但即使等到了连接,因为线程的饱和,在处理请求的时候也可能因为资源的不足或者其他资源的占用导致无法即使响应,而引发http 500
为什么不是一开始就调大
在参数调优阶段,这个num_threads是经过笔者调整多次的,当时定的值是160,为什么不在一开始就调大呢?原因是调优阶段时使用的是cosbench和python bto来进行验证调试结果,cosbench在实际测试的时候,即使ops很高,也只能在一小段时间内得出结果,笔者对该参数设置为100、200、300、400的时候进行过对比发现在200左右,再调大该值,对性能没有贡献了,再调整几次,发现160左右能达到最佳性能,所以定了这个值,而boto使用的是长连接,对高并发的连接请求更是不能覆盖到。
现在看来,调优的测试工具也应该对场景覆盖多一些,另外,针对该值的调优可以看看这篇干货Ceph Rados Gateway Tuning
最终的解决
我们的解决方法就是
- 1、将rgw的num_threads调大,最终调整到768
- 2、给radosgw进程分配更多的cpu核,从原来的8核增加到12核
- 3、针对tcp连接,优化net.ipv4.tcp_timestamps和net.ipv4.tcp_tw_recycle,使得连接能快速被回收
修改配置并全部生效后,未再发现http 500和timeout的问题
参考资料
Civetweb Configuration Options
HTTP FRONTENDS
- 本文作者: 奋斗的松鼠
- 本文链接: http://www.strugglesquirrel.com/2018/11/28/解决一次rgw线程数不足引发的问题/
- 版权声明: 本博客所有文章除特别声明外,创作版权均为作者个人所有,未经允许禁止转载!