软件系统性能瓶颈真相
?在我的机器上,大概时间是:
?打印时间大概是:
??
?打印时间:
??
从局域网的memcached取一次数据所需平均时间:528065?
?
其实测试1是计算机最擅长的操作,通常这个操作在计算机的内存进行,测试2操作其实是一个IO操作,会涉及到一个向显卡写数据的IO,第三个操作,其实是一个网络IO,计算机会向网卡发送一个指令,到另外一条机器接收到命令,最后再从网卡读结果。
最后得出,各时间大概有如下关系:
快速排序≈一次磁盘IO≈1/29memcached所需要的时间。
?
可以看出,系统中一旦发生IO,其所需的时间通常比直接操作内存慢好几百倍,因为一个快速排序,会有好几百次的数据移动和比较。对于经过网络的操作,通常其速度又会比磁盘慢至少一个数量级。
?
尽管现在各种分布式产品很流行,但是这些基础常识,还是应该牢记在心,这样才能够写出高效率,高稳定性的软件。下面是我总结出的代码中几条涉及到性能的几条准则:
一、能够在内存解决的尽量不要访问磁盘,能在本机磁盘解决的,尽量不要访问网络。
二、多线程并发访问程序中,能不共享数据的尽量不要共享(StringBuilder优于StringBuffer);能够使用并发工具类(Atomic相关类,ConcurrentHashMap,CAS等)的,尽量不要使用synchronized。
三、在访问数据库时,对于常用的查询条件一定要建好复合索引。能够不排序的尽量不要排序,如果需要排序的,一定把排序字段提前存好,而不要在查询的时候再计算排序字段。
四、批量优于单个操作,很多产品,比如数据库,memcached等,都有批量及单个操作。在一些任务类中,如果能够批量操作,则优先使用批量接口。
五、某些计算时间长(比如用户要导出大文件)的操作,尽量进行优化。如果系统中必须存在这样的操作,那就用队列来专门解决这些问题,一定要控制系统线程的数量。
?
另外,在项目中,大多数系统的瓶颈可能都在数据库,通常,如果一个系统的用户超过1w,缓存就非常必要了。其实,性能问题,不仅仅出在代码级别,还有可能是在中间件上发生,比如apache的默认配置,就非常不适合大的并发系统,mysql的缓存,oracle的最大连接数等等,甚至前段的JS加载及运行,都可能带来性能问题。精通一些中间件,同样可以提高系统的性能和吞吐量。
?
通常性能都是在用户使用时才被发现,因此,排查问题比较困难。关于他的话题,写出好几本书也阐述不完,在这里,写的标题有点夸张,但是,不可置疑,软件中的IO确实是系统瓶颈很重要的一个原因。
?
?
对这类话题感兴趣?欢迎发送邮件至donlianli@126.com关于我:邯郸人,擅长Java,Javascript,Extjs,oracle sql。更多我之前的文章,可以访问?我的空间?
1 楼 jahu 2013-08-03 计算结果不正确,
测试二,不仅有io,还有显示时间,
测试三,网络连接时间,你不算进入,比如tpc的三次握手? 2 楼 商人shang 2013-08-03 本人也是邯郸人。。。。 3 楼 saiyaren 2013-08-03 你的性能瓶颈分析我觉得并不赞同,因为我是专门做性能优化的的,而且是做日访问量PV 在亿级别以上的:
1.前端分析:
一般来说前端分析的话,一般都是计算密集型的,也就是对于CPU的消耗,所以这时候需要分析的瓶颈一般来说,如果CPU没有跑满,但是已经无法处理更多的吞吐,那么一定要分析是否是NET IO遇到了瓶颈,如果NET IO没有瓶颈,那么可能是其中出现了等待过多造成的延迟,一种是增加web server简单的proxy分配多个压力,一种是通过profiler工具分析瓶颈,看消耗cpu的点;
如果是网络瓶颈(NET IO),一般出现在cdn服务器上,这时一般是增加网卡吞吐(一般目前常用的是千兆和万兆网卡),或者看4层负载是否均衡(LVS)
2.后端分析:
如果是数据密集型的,一般问题出现在WA上,比如CDN,这些一般是读的内容加载内存文件系统中(或者自己写个内存文件系统模块),然后持久用SSD
如果是库的话一般来说前端会通过CACHE去进行读的缓存,数据库的瓶颈一般是通过架构修改来进行提升的;
我之前做过一个优化,修改架构后性能提高10倍;
总结:
一般计算密集型的瓶颈点事CPU,一般通过NET IO一起分析
一般存储密集型的分析平静是WA
个人之言,简单的分析,许多细节可能还需要跟踪瓶颈解决瓶颈才是硬道理,上述算法一般不是瓶颈点;
还有就是一般解决瓶颈的也有通过语言解决的如我们目前用的HIPHOP就是把php转换成c++后来转换成了JIT VM
点不同,所以还需要根据每个系统的瓶颈来进行分析提高性能 4 楼 saiyaren 2013-08-03 性能的东西不是你说的这么简单的,是一个很复杂的分析过程,尤其是分析瓶颈找到最大的消耗点(hot point)才可以解决问题 5 楼 donlianli 2013-08-04 saiyaren 写道你的性能瓶颈分析我觉得并不赞同,因为我是专门做性能优化的的,而且是做日访问量PV 在亿级别以上的:
1.前端分析:
一般来说前端分析的话,一般都是计算密集型的,也就是对于CPU的消耗,所以这时候需要分析的瓶颈一般来说,如果CPU没有跑满,但是已经无法处理更多的吞吐,那么一定要分析是否是NET IO遇到了瓶颈,如果NET IO没有瓶颈,那么可能是其中出现了等待过多造成的延迟,一种是增加web server简单的proxy分配多个压力,一种是通过profiler工具分析瓶颈,看消耗cpu的点;
如果是网络瓶颈(NET IO),一般出现在cdn服务器上,这时一般是增加网卡吞吐(一般目前常用的是千兆和万兆网卡),或者看4层负载是否均衡(LVS)
2.后端分析:
如果是数据密集型的,一般问题出现在WA上,比如CDN,这些一般是读的内容加载内存文件系统中(或者自己写个内存文件系统模块),然后持久用SSD
如果是库的话一般来说前端会通过CACHE去进行读的缓存,数据库的瓶颈一般是通过架构修改来进行提升的;
我之前做过一个优化,修改架构后性能提高10倍;
总结:
一般计算密集型的瓶颈点事CPU,一般通过NET IO一起分析
一般存储密集型的分析平静是WA
个人之言,简单的分析,许多细节可能还需要跟踪瓶颈解决瓶颈才是硬道理,上述算法一般不是瓶颈点;
还有就是一般解决瓶颈的也有通过语言解决的如我们目前用的HIPHOP就是把php转换成c++后来转换成了JIT VM
点不同,所以还需要根据每个系统的瓶颈来进行分析提高性能
一看就是很专业的高手,我说的只是从编程方面来说的,文中也说道,性能是一个很复杂的问题。可能你站的高度更高,看到的更全面些吧。 6 楼 saiyaren 2013-08-05 donlianli 写道saiyaren 写道你的性能瓶颈分析我觉得并不赞同,因为我是专门做性能优化的的,而且是做日访问量PV 在亿级别以上的:
1.前端分析:
一般来说前端分析的话,一般都是计算密集型的,也就是对于CPU的消耗,所以这时候需要分析的瓶颈一般来说,如果CPU没有跑满,但是已经无法处理更多的吞吐,那么一定要分析是否是NET IO遇到了瓶颈,如果NET IO没有瓶颈,那么可能是其中出现了等待过多造成的延迟,一种是增加web server简单的proxy分配多个压力,一种是通过profiler工具分析瓶颈,看消耗cpu的点;
如果是网络瓶颈(NET IO),一般出现在cdn服务器上,这时一般是增加网卡吞吐(一般目前常用的是千兆和万兆网卡),或者看4层负载是否均衡(LVS)
2.后端分析:
如果是数据密集型的,一般问题出现在WA上,比如CDN,这些一般是读的内容加载内存文件系统中(或者自己写个内存文件系统模块),然后持久用SSD
如果是库的话一般来说前端会通过CACHE去进行读的缓存,数据库的瓶颈一般是通过架构修改来进行提升的;
我之前做过一个优化,修改架构后性能提高10倍;
总结:
一般计算密集型的瓶颈点事CPU,一般通过NET IO一起分析
一般存储密集型的分析平静是WA
个人之言,简单的分析,许多细节可能还需要跟踪瓶颈解决瓶颈才是硬道理,上述算法一般不是瓶颈点;
还有就是一般解决瓶颈的也有通过语言解决的如我们目前用的HIPHOP就是把php转换成c++后来转换成了JIT VM
点不同,所以还需要根据每个系统的瓶颈来进行分析提高性能
一看就是很专业的高手,我说的只是从编程方面来说的,文中也说道,性能是一个很复杂的问题。可能你站的高度更高,看到的更全面些吧。
没有没有,只是做了一点点优化方面的东西,有点经验,其实我最近也一直想分析一些分析性能的方式和profiler的工具,这是比较常用的,更深层次一般都是从系统角度和编译角度优化了,那个一般人都不会接触的
7 楼 Shen.Yiyang 前天 楼主你这套结论适合大型机,把所有的性能都在单机器范围内做好。但是现在的趋势是水平扩展,这种架构下,就不可能像你说的那样各种避免IO,最常见的做法是分离计算和IO,来提升性能。 8 楼 saiyaren 前天 Shen.Yiyang 写道楼主你这套结论适合大型机,把所有的性能都在单机器范围内做好。但是现在的趋势是水平扩展,这种架构下,就不可能像你说的那样各种避免IO,最常见的做法是分离计算和IO,来提升性能。
其实大部分还都是在计算上消耗,IO一般来说瓶颈不大,包括数据库中,IO瓶颈其实一般换架构可以解决,比如SSD,或者内存模型等等,如果是数据库的话,一般操作在WA消耗也不是太大