FastDFS优化
问题描述
18个Strorage+1Tracker的线上环境,Stroage存储18T磁盘剩余空间平衡在97%左右。默认配置下频繁出现图片下载失败的情况,由于客户端代码使用了连接池,最终表现出连接资源不足。跟踪若干Storage日志偶尔有“send timeout”字样的日志。
image.png猜测
线上环境对FastDFS Stroage、Tracker配置改动较少,依FastDFS架构文件下载失败不会是Tracker节点连接不足引起[Tracker是轻量级的节点],目前的连接数还不足以达到Tracker的瓶颈,重点调整客户端配置和Stroage配置。
优化
Storage的配置参数有几个猜测进行调整可能有用:
- max_connections 默认为256,通过观察所有节点的连接情况均为达到该临界值都维持在20个连接左右,故而该参数暂不做改动,无须优化最大连接数。
- accept_threads 该参数决定接收客户端连接的线程数,默认值为1,适当放大该参数可改善Storage处理连接的能力,改成2[线上环境cpu为32核心可支持足够多的线程数]。
- work_threads 工作线程用来处理网络IO,默认值为4,该参数影响Stroage可以同时处理的连接数,适当的调整这里改为20。
- disk_reader_threads 读取磁盘数据的线程数,对应到每个存储路径,线上环境Storage只有一个路径,默认为1,这里改为5,提高读取磁盘的线程数。
- disk_writer_threads 写磁盘的线程数量,也是对应一个存储路径,默认为1,这里修改为5。
对所有的Storage做如上修改后,依次重启每一个节点,集群稳定后,下载失败的文件数有减少,但依然有出现客户端仍报连接超时,客户端原有的超时时间为600毫秒,修改超时时间为1000毫秒,重启所有客户端,之后再未发现有图片下载有异常。 每个Storage节点中的连接数任然维持在20个左右,但系统处理能力增强。
image.png总结
分布式系统中,应充分利用多核CPU的处理能力,适当的调整线程数来优化处理能力,对IO型业务应该使用多线程来提高IO的续写效率,避免排队阻塞。
进一步优化
第二天下午收到反馈,任然出现部分图片下载失败的情况,经排查这次下载失败的原因为某个客户端报“无法获取服务端连接资源:找不到可用的tracke”导致。意思是Tracker不能为客户端提供更多的连接资源而拒绝服务,从而部分客户端获取不到Traker连接而报错。
分析原因,第一步尝试去调整Tracker处理连接相关的参数,tracker.conf中如下几个参数可适当调整:
- max_connections=1024 最大连接数,包括所有客户端的读写连接数,可根据系统并发适当的调高,这里修改为1024
- accept_threads=5 负责接收客户端请求的线程数
- work_threads=25 负责处理客户端请求的连接数,这里只负责解析应该去哪个Stroage去下载/上传图片
- 调整客户端连接池的大小,所有连接池资源的总和不应该超过上述配置的1024这个值,否则客户端将报"找不到可用的tracke",修改连接池大小为30,继续观察。
进一步优化
一个月左右的时间足以发生大的变故,期间进行过一次扩容操作,扩容操作后也都将对应的Storage节点进行了优化,通过fdfs_monitor工具查看每个Storage上的连接数都维持在10个左右,和配置的最大值256差距很大。但客户端还是频繁出现图片下载异常的情况,情况比之前更加糟糕。
起初怀疑是否Tracker到达性能瓶颈,通过调整Tracker的线程数和连接数已经没有什么效果,查看Tracker的连接数也维持在50条左右[netstat -anp |grep fdfs |wc -l],明显Tracker并不是性能的关键,通过网络工具iptraf-ng测试到Tracker上的网络流量在1M/S左右,也没有什么问题。
image.png回头在测试下每个Storage上的流量状态,均值在40MB/S 远远未达到IO瓶颈,所有的Storage类似。
image.png最终不得不怀疑是否客户端实现的有问题,相比来说生产环境中使用的版本对客户端进行了池化操作,请求使用Jetty容器通过Servlet进行暴露,首先通过调整Jetty的线程池大小、Http连接的队列大小均没有效果。最后直接拿掉资源池化的这一块,直接使用原始API一对一的进行下载,问题解决了。
总结如下,FastDFS的整个架构设计为多线程模型,tracker在图片下载过程中只做轻量级的重定向操作[只是用来判断group在哪个节点],图片下载由客户端直连Storage进行,FastDFS不建立长连接,使用池化操作并不能带来明显的效率提升,相反使用即用即连接的方式能获得更好的性能,及时释放连接,在并发量大的情况下,通过适当的提高Tracker的线程数、Storage线程数、Client数量、Client线程数来提升整体性能。目前算下载系统满载的总下载流量在1.5G/S左右。
--------------------- 本文来自 it小奋 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/u010820702/article/details/79630115?utm_source=copy