大家好,欢迎来到停止重构的频道 ,上两期介绍了性能指标和性能测试。
从本期开始,我们进入性能调优部分。首先,我们讨论一下性能调优的基本思路。
可能很多人会不屑一顾,性能调优能有什么基本思路,按照说明调整配置文件不就可以了吗。但是,如果仅仅修改配置的话,那么可能4核和16核服务器并没有性能区别,但是公有云上的价格却相差了4倍多。
一个网站系统是由很多台服务器组成的,性能调优并不是一件简单的事情,它的难点在于如何正确评估各个服务所需要的硬件配置。
在目标峰值压力下,不会出现一部分服务器性能吃紧而一部分服务器性能过剩的情况。 需要提前说明的是,不同服务最好部署在不同的服务器,不然出现性能问题时,很难分清楚哪个服务有问题。
性能调优需要解决好以下3个问题
- 明确局部服务的目标性能指标
- 服务调优
- 编程方案提升性能
明确局部服务的目标性能指标
首先是明确局部服务的目标性能指标 ,在前面《性能测试》时提到目标性能指标无非就是并发量、响应时间、吞吐量、错误率。
在局部调优时,我们更看重吞吐量,因为系统内部,更像是关系复杂的水管网络,各个服务器的吞吐量就像是水流量,当各个服务器的吞吐量符合要求时,自然不会出现局部性能过剩而局部性能不足的情况。
我们以一个比较普遍的网站系统结构为例 :包含后端部分、数据服务部分 ,其中数据服务部分包含Redis、MySQL服务。
假设整个系统的目标性能指标为:1000并发、平均响应时间500毫秒、吞吐量为2000rps、错误率低于0.5%。
那么,理论上后端部分的吞吐量为2000rps,Redis、MySQL的吞吐量也至少为2000rps。 但考虑到一个接口可能会同时调用Redis或MySQL各一次,或调用同一个数据服务2次 ,那么Redis、MySQL的吞吐量最好为4000rps。
当然在前面《性能测试》时说过: 更新数据的接口只需要目标性能的1/2 。所以,数据服务的读操作的吞吐量为4000rps,而写操作的吞吐量只需要2000rps。
当然一些接口可能会出现调用数据服务五六次的情况,对于这些特殊接口可以暂时忽略,因为这些接口只是一小部分,即使响应时间很慢,前端加一下loading动画即可。
吞吐量明确了之后,局部调优时,错误率最好为0。
至于各个服务的并发量是需要通过多次测试确定的,因为它取决于每个服务的软件实现方式,可能总体目标1000并发值对于某个服务来说实在太多。 以Redis为例:由于Redis是单线程的 ,所以让Redis同时接收太多的请求并无益处(性能反而更低)。
这里需要说明的是:即使某个服务的并发量少于总体的并发量 ,吞吐量仍可能满足总体目标吞吐量,因为吞吐量是并发量除以平均响应时间求得,所以只要平均响应时间足够低,则吞吐量仍可满足目标。
比如Tomcat的线程数设置为500 ,即只有500个请求同时被处理 ,那剩下的500(目标是1000并发)个请求应该如何处理呢 ?剩下的500个请求放到Tomcat等待队列里即可,因为在前面《性能指标》那一期内容里 ,说明了并发量其实是饭店里的顾客和排队顾客的总和,所以让一部分请求进入等待区是合理的 ,同时处理过多的请求反而会由于互相抢占资源而性能更低 。
服务调优
接下来是单个服务调优,一般是通过修改服务的配置文件,让软件服务拥有目标吞吐量 。具体软件服务的调优在后续视频将会详细讲解。其中,将会包含调优方案、硬件配置推荐、集群方案。 当然,我们只讲常用的服务以抛砖引玉 如Nginx、Tomcat、Redis、MySQL等。
编程方案提升性能
一些服务即使调优,或扩展集群,都无法达到目标性能,例如,让MySQL获得10万rps以上的性能 ,几乎是不可能的。
所以,我们需要通过一些手段降低这些性能较弱的服务的压力, 后续将会讲解一些常用的方案, 如Redis缓存方案降低MySQL读读频率等 。
总结
本期讲解了性能调优的基本思路,后续我们将讲解具体服务的调优方法以及提高性能的一些方案 ,也会介绍它们的集群方案,敬请期待。