记一次FastDFS优化

问题描述 

        18个Strorage+1Tracker的线上环境,Stroage存储18T磁盘剩余空间平衡在97%左右.默认配置下频繁出现图片下载失败的情况,由于客户端代码使用了连接池,最终表现出连接资源不足.跟踪若干Storage日志偶尔有"send timeout"字样的日志.


猜测

    线上环境对FastDFS Stroage,Tracker配置改动较少,依FastDFS架构文件下载失败不会是Tracker节点连接不足引起[Tracker是轻量级的节点],目前的连接数还不足以达到Tracker的瓶颈,重点调整客户端配置和Stroage配置。

优化

Storage的配置参数有几个猜测进行调整可能有用:

  1. max_connections 默认为256,通过观察所有节点的连接情况均为达到该临界值都维持在20个连接左右,故而该参数暂不做改动,无须优化最大连接数.

  2. accept_threads 该参数决定接收客户端连接的线程数,默认值为1,适当放大该参数可改善Storage处理连接的能力,改成2[线上环境cpu为32核心可支持足够多的线程数]
  3. work_threads 工作线程用来处理网络IO,默认值为4,该参数影响Stroage可以同时处理的连接数,适当的调整这里改为20.
  4. disk_reader_threads 读取磁盘数据的线程数,对应到每个存储路径,线上环境Storage只有一个路径,默认为1,这里改为5,提高读取磁盘的线程数.
  5. disk_writer_threads 写磁盘的线程数量,也是对应一个存储路径,默认为1这里修改为5

       对所有的Storage做如上修改后,依次重启每一个节点,集群稳定后,下载失败的文件数有减少,但依然有出现客户端仍报连接超时,客户端原有的超时时间为600毫秒,修改超时时间为1000毫秒,重启所有客户端。之后在未发现有图片下载有异常. 每个Storage节点中的连接数任然维持在20个左右,但系统处理能力增强.


 总结

        分布式系统中,应充分利用多核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条左右[nestat -anp |grep fdfs |wc -l],明显Tracker并不是性能的关键,通过网络工具iptraf-ng测试到Tracker上的网络流量在1M/S左右,也没有什么问题。


      回头在测试下每个Storage上的流量状态 ,均值在40MB/S 远远未达到IO瓶颈,所有的Storage类似.   

     最终不得不怀疑是否客户端实现的有问题,相比来说生产环境中使用的版本对客户端进行了池化操作,请求使用Jetty容器通过Servlet进行暴露,首先通过调整Jetty的线程池大小、Http连接的队列大小均没有效果。最后直接拿掉资源池化的这一块,直接使用原始API一对一的进行下载,问题解决了。

      总结如下,FastDFS的整个架构设计为多线程模型,tracker在图片下载过程中只做轻量级的重定向操作[只是用来判断group在哪个节点],图片下载由客户端直连Storage进行,FastDFS不建立长连接,使用池化操作并不能带来明显的效率提升,相反使用即用即连接的方式能获得更好的性能,及时释放连接,在并发量大的情况下,通过适当的提高Tracker的线程数,Storage线程数,Client数量,Client线程数来提升整体性能. 目前算 下载系统满载的总下载流量在1.5G/S左右.

猜你喜欢

转载自blog.csdn.net/u010820702/article/details/79630115