对互联网三高框架的认识

对互联网三高框架的认识

互联网三高架构:高并发、高性能、高可用,简称三高hp

互联网应用系统开发确定常常会看到高并发和高性能这两个词,可谓是耳熟能详,而具体的含义和关系真的如你所想的,真正的理解了吗?java

先来看一个例子:mysql

一个蓄水池,是1m*1m*1m=1立方米大小,有一个出水口,出水口每秒钟流出0.1立方米,那么这个蓄水池的并发量是1立方米,出水速度是0.1立方米/秒。nginx

若是增长一个出水口,都是每秒钟流出0.1立方米,那么这个蓄水池的并发量没变,可是出水速度变成了0.2立方米/秒。web

同理,增大了出水口,蓄水池的出水速度也变快了。redis

上面咱们很容易知道,并发量是一个容量的概念,性能就是出水速度,并且有下面这些结果。算法

  • 增大蓄水池的长宽高,能够增长并发能力
  • 出水口若是扩大了出口大小,则能够提升出水的速度,也就是性能提升了。
  • 增长出水口的数量,则是增长了并行处理的能力,一样能够提升性能。

那么对照咱们计算机中,咱们的系统中,是怎么样的结果呢?sql

  • 增长服务器的内存大小,能够增长并发量。由于内存增长了,就能够开更多的进程,更多的线程,也能够扩大任务队列的大小。
  • 提升cpu的主频速度,优化程序,能够提升性能。cpu更快了,程序优化的更好了,处理单个任务的时间也就更短了。
  • 增长多核甚至分布式服务器数量,也能够提升性能,同时提升并发量。

若是只是性能提升了,并发量是否也能提升呢?api

若是咱们静态的理解并发量,那它是不会提升的。安全

而我更愿意动态的来理解并发量,即:单位时间内能够进来的最大数量。

那么提升性能,是能够线性提升并发量的,由于单位时间内,进来的同时也有出去。

咱们先来作一个假设:
  单个进程(php fast-cgi)内存占用10M
  单个线程( java web)内存占用2M
  单个协程(go)内存占用20K
  队列任务(nginx)内存占用2K


咱们下面来看看内存与并发量的关系。

内存量

进程数

线程数

协程  

  队列任务

1G

100

500

50K

500K

2G    

200

   1000  

   100K  

   1000K

4G    

400    

   2000    

   200K  

   2000K

8G    

800    

   4000    

   400K

  4000K

从上面的结果中,咱们能够很直观的看出来,并发能力在不一样的运行模式中的巨大区别。
多进程和多线程的模式,不只是内存开销巨大,并且在数量不断增长的状况下,对CPU的压力也是很是巨大,
这也是为何这类系统在并发量大的状况下会很不稳定,甚至宕机。

假设上边计算出来的数据,都是静态的容量,若是全部任务都不处理,那么内存确定都是会很快就被撑爆。
因此要达到更高的并发量,就须要有更快的处理速度,即作好性能优化。

下面,再来作一个假设。

咱们如今有一台服务器,配置是8核16G内存。

若是咱们的应用是计算密集型,纯运算的系统,如:数据索引查询、排序等操做。

并且还要假设,这个应用在多核并行运算时不存在锁竞争的状况(只读)。

        QPS = 1000ms/单个请求耗时*8


① 若是单个请求(任务)耗时100ms,那么咱们能够计算出来:qps = (1000ms/100ms)*8核 = 80个/秒

② 若是咱们优化处理的算法,单个请求耗时下降到10ms,那么:qps = (1000ms/10ms)*8核 = 800个/秒

③ 若是能够继续优化,将单个请求耗时下降到1ms,那么:qps = (1000ms/1ms)*8核 = 8000个/秒

上面的状况和优化的效果理解起来应该很容易,由于对服务器资源的依赖更可能是CPU的运算能力和数量。


在实际的互联网应用中,系统更可能是依赖mysql,redis,rest api或者微服务,属于IO密集型。按照上面的计算方式,可能就不太准确了,由于cpu是有富余的。
IO阻塞的时候,开启更多任务的方式固然有上面多进程、多线程、多协程和队列的方式来实现,并且也是有效且更好地利用服务器资源的方法,能够达到更高的并发量,
毕竟咱们把大部分的运算放到了应用外部的mysql,redis,rest api等服务。

到此为止,咱们已经知道并发量、性能优化跟服务器资源(服务器数量,cpu,内存)的关系,也知道性能优化对并发量的影响。

 

解疑答惑

1 内存越多,并发量必定能够越大吗?

答:大部分状况是的。这个问题,上面有提到过,对于多进程、多线程的模式,线程太多的时候,线程抢占时间片,CPU切换上下文会愈来愈慢。影响系统性能。

对于协程、队列的运行模式,这个问题会好不少,固然协程调度、队列维护的开销,确定也是会增长,只是增长的开销不至于对系统性能形成直线降低。


2 CPU越快,应用的性能必定越好吗?

答:绝对的。只不过CPU和应用性能提高可能不成线性增加的关系,由于应用多是IO密集型,应用性能还会受到IO阻塞的影响。


3 CPU越多,应用的性能必定越好吗?

答:大部分状况是的。若是大量锁存在,性能提高可能会大打折扣,由于并行能力会被锁住,又变成单线程执行了,没有最大的发挥多CPU的做用。


4 服务器越多,并发量必定越大吗?

答:绝对的。服务器增长,CPU和内存资源相应也就越多,并发能力也就会增大,他们之间是线性相关。


5 服务器越多,性能必定越好吗?

答:大部分状况是的。可是单个服务器的效率可能会是降低的,数据一致性问题、同步问题、锁问题,这些都会致使单个服务器的效率(CPU利用率)降低,因此不是线性相关。

关于CPU利用率:
    若是只是考虑应用对CPU利用效率的话:单核=多核=多服务器

    单进程/单线程的系统对于服务器资源的利用率更高。

    到多核的系统中,就会由于锁的问题,多任务同步的问题,操做系统调度的问题,形成必定的资源浪费。而分布式系统中,这些浪费也会更严重。

6 怎样更好的更有效的利用服务器资源呢?

答:避免由于IO阻塞让CPU闲置,致使CPU的浪费;

    避免多线程间增长锁来保证同步,致使并行系统串行化;

    避免建立、销毁、维护太多进程、线程,致使操做系统浪费资源在调度上;

    避免分布式系统中多服务器的关联,好比:依赖同一个mysql,程序逻辑中使用分布式锁,致使瓶颈在mysql,分布式又变成串行化运算。


    上面说了要避免的地方,要具体怎么来避免,到具体的业务场景就须要具体分析了。

     并且有些时候,为了业务功能,或者其它方面的需求,好比:可用性、伸缩性、扩展性、安全性,不得不牺牲掉一部分性能。

 

最后,作一个总结:

并发量,是一个容量的概念,服务能够接受的最大任务数量,动态的看待它,还须要把性能考虑进去。

性能,是一个速度的概念,单位时间内能够处理的任务数量。

高并发和高性能是紧密相关的,提升应用的性能,是确定能够提升系统的并发能力的。

应用性能优化的时候,对于计算密集型和IO密集型仍是有很大差异,须要分开来考虑。

增长服务器资源(CPU、内存、服务器数量),绝大部分时候是能够提升应用的并发能力和性能 (前提是应用可以支持多任务并行计算,多服务器分布式计算才行),但也是要避免其中的一些问题,才能够更好的更有效率的利用服务器资源。

 

posted @ 2022-05-20 08:56  While!true  阅读(63)  评论(0编辑  收藏  举报