我们做性能优化的目的是提高吞吐量,希望系统的qps越高越好。
一个请求的处理过程可以分为CPU时间(S)+IO等待时间(W),当S和W固定时,我们可以通过调整并发数来提高系统的qps,有经典理想公式1如 并发数C=(W/S+1)*cpu核数,并发数为c时,可以让cpu keep busy,最大限度的利用系统资源。
如下图,一个格子表示一个时间单位,单核CPU,假设绿色为CPU时间(S为1个时间单位),深蓝色为IO等待时间(W为3个时间单位),在10个时间单位内能够完成的完整请求数为7个,最优并发数C为[(3/1)+1]*1=4个,4个的并发数就可以充分利用cpu资源,当并发数>4时反而会增加额外的线程切换开销,降低qps。
|
|
|
|
|
|
|
|
|
|
1
|
|
|
|
5
|
|
|
|
|
|
|
2
|
|
|
|
6
|
|
|
|
|
|
|
3
|
|
|
|
7
|
|
|
|
|
|
|
4
|
|
|
|
8
|
|
|
如果不考虑线程切换等因素带来的cpu开销,并且内存、io不成为瓶颈的时候,当调整了一个最佳并发数C后,cpu百分百利用了,系统的最大qps可以计算为qps=(1000/S)*cpu核数, 也就是说如果要提高系统的吞吐量,就要尽可能地减少每个请求的cpu消耗。在真实环境下,线程切换会带来额外的开销,所以也要尽可能地减少io等待时间,减少最优并发数。即要达到最高qps,就是要最小化S和W/S。对于业务系统的一个有效的优化实践是做pagecache,最小化每个请求的cpu消耗和io等待时间。实施方式是把页面个性化、实时更新模块异步化,把非实时公用模块进行pagecache。
当系统进行优化后,达到一个较高的qps,但始终是有一个极限的。比如我们的qps达到300,但是在每秒的访问次数达到500,那么每秒都会堆积200个请求,如果这种状况持续很长时间,最终系统将无法提供正常访问,直至cpu耗尽而挂。当遇到这种场景时,流控还是需要的,让cpu留最后一口气拒绝掉超载的200个请求,保留实力正常服务那300个请求。
流控主要可以分为两种,一种是控制并发数,基于上面的最优并发数公式,可以知道,当实际并发数小于最优并发数时,cpu是不可能被耗尽的,总有闲置的时间,调整并发数,可以控制cpu的使用率。另外一种是控制每秒请求数,让每秒请求数小于最高qps也能让cpu资源不被耗尽。
实际情况下,如果对应用进行限流,限流的阀值较难制定,因为难以精确地算出每个请求的cpu时间和io等待时间,另外上述的公式都是在一个假设的理想模型下,实际场景更为复杂,不能和理想模型完全吻合。所以限流的阀值,还是要基于压测的。从压测的结果,我们能够知道在应用安全负载下的并发数和qps,基于这个数据,来决定并发流控和qps流控的阀值。
4 压测实验数据 (st cpu时间,wt io等待时间,c为并发数),和上述公式吻合
st | wt | c | qps | cpu | load | rt |
15 | 15 | 5 | 155 | 13 | 1.8 | 31 |
10 | 288 | 30 | 3 | 35 | ||
15 | 400 | 45 | 5.5 | 38 | ||
20 | 470 | 55 | 7.8 | 43 | ||
25 | 500 | 62 | 9 | 50 | ||
30 | 510 | 66 | 13 | 59 | ||
35 | 516 | 68 | 13 | 66 | ||
50 | 540 | 72 | 17 | 70 | ||
60 | 540 | 73 | 15 | 110 | ||
80 | 545 | 72 | 18 | 150 | ||
15 | 1 | 5 | 240 | 23 | 2 | 20 |
10 | 400 | 55 | 5.3 | 25 | ||
20 | 508 | 65 | 9 | 39 | ||
25 | 520 | 68 | 12 | 48 | ||
30 | 538 | 70 | 14 | 55 | ||
40 | 530 | 71 | 15 | 74 | ||
15 | 200 | 10 | 45 | 6 | 0.4 | 217 |
30 | 137 | 15 | 1.5 | 219 | ||
50 | 227 | 25 | 3 | 220 | ||
70 | 314 | 35 | 4 | 222 | ||
f#y#.htm | ||||||
10 | 770 | 13 | 1.4 | 12 | ||
20 | 970 | 17 | 1.7 | 20 | ||
35 | 1150 | 21 | 4 | 30 | ||
60 | 1200 | 25 | 4.5 | 55 | ||
75 | 1500 | 32 | 9 | 50 | ||
95 | 1440 | 32 | 10 | 67 | ||
105 | 1560 | 39 | 11 | 66 | ||
120 | 1300 | 25 | 5 | 90 |