高效性能调优的最佳实践
只有采用有效的性能调优手段,才能使得性能调优达到事倍功半的效果。近日,个人博客Liguanglei中发布了一篇关于有效性能调优建议的文章,该篇文章是作者阅读《性能调优:综合指南》的读书笔记。作者从影响系统性能的算法、算法运行环境与所需资源以及算法和环境资源的交互等因素讲述了性能调优的一些建议。新手能够直接根据这些建议进行系统调优,老手也可以拿来当作调优的参考。现对这些建议进行一个全面的梳理,以供读者参考和学习,具体内容如下:
1. 算法本身的优化
算法优化是性能局部优化的首选, 并常采用各种性能监控软件来度量CPU时间、内存占用率、函数调用次数以问题定位,然后实施各种调优方法,如优化循环、利用空间换时间、采用合适的数据结构等。但是算法本身的优化只能够帮助大家消除一些明显的编程细节引起的瓶颈,尤其单单通过算法优化的手段还不能完全解决性能问题,且具有非常大的难度。
2. 优化运行环境与资源
运行环境与资源包括各种软硬件平台,硬件环境包括CPU、内存、磁盘以及网络等。最简单且最省事的调优方法是优化硬件资源,使用快速计算资源代替慢速计算资源,提升资源的计算能力。
优化硬件资源的方式包括:
- 更快的CPU
- 更快的本地IO设备,比如内存代替硬盘, SSD 代替机械硬盘
- 加内存减少分页
- 快的网络IO设备,比如使用光纤及专线增加网络带宽,使用万兆千兆网卡代替千兆百兆网卡
- 快速计算资源代替慢速计算资源,比如快速存储代替慢速存储(属于同类型资源);本地计算换网络传输的优化最好采用压缩传输内容的优化手段(属于不同类型的资源),该方式尽管增加了CPU的压缩/解压时间,但减少了大量网络传输时间
软件环境包括操作系统、数据库、中间件等。软件环境调优的成本要相对较高, 并且工作量很大,如从Windows平台迁移到Linux 平台、从数据库A切换到数据库 B、从EJB 切换到 Spring等。这类调优见效快,但受制于预算和硬件本身的限制。由于资源始终是有限的,随着资源的消耗,仍然存在性能瓶颈。
3. 优化算法和资源间的交互
当前各种调优实践最集中的领域是优化算法和资源间的交互,如减少单台服务器(或单位计算资源)的处理量、充分利用系统资源、减少不必要的计算、减少不必要的IO等。
具体内容如下:
- 减少单台服务器(或单位计算资源)的处理量
当在单台机器处理能力已达上限的情况,就需要把压力分散到多台机器上, 从而使每台机器都能获得可接受的延迟或吞吐量。总的优化原则是分而治之,具体维度包括业务、组件边界、访问频率或对系统资源的消耗程度、瓶颈资源等。
具体内容如下:
业务:把大应用按业务分成独立的互相合作的系统,如高层的采用SOA方式,低层的采用数据库分库方式
组件边界: Web服务器、应用服务器、数据库服务器、文件服务器
对系统资源的消耗程度:采用读写分离的方式
瓶颈资源: 对数据库进行分表、分片
一旦按上述维度处理好了,大家还可以在所有维度上应用负载均衡,把访问量分散到不同服务器。
- 充分利用系统资源
采用多进程、多线程、异步操作以及负载均衡等手段,其中负载均衡主要做到了防止某台服务器过满和防止某台服务器过闲。
- 减少不必要的计算次数
缓存计算结果,尤其是服务端缓存,以减少不必要的计算。
- 减少不必要的 IO 次数
网络IO次数:客户端缓存、CDN缓存、合并资源以减少请求次数
磁盘IO次数:缓存常用数据,如利用Redis、Memcached进行缓存
最后,作者总结指出缓存是减少不必要计算和IO的重要手段,缓存的设计主要是根据资源变化频率对资源进行分类,比如动静分离等;其前提是恰当的状态管理、分离无状态的逻辑和有状态的逻辑,但会付出对一致性的一定妥协和运维的复杂为代价。缓存的适用场景包括热点不均衡、有效时间不太短、一致性牺牲程度可接受。作者还指出以上所有优化手段可以组合使用,有冲突时再做权衡。
作者还推荐了一些参阅文章:有关压力测试、负载测试的《重述:性能、容量、负载以及压力测试》和《性能调优技术的几个角度》。此外,有兴趣的读者还可以参阅酷壳陈皓发表的一篇题为《性能调优攻略》的文章。