架构师必备基础二
主要内容是:一些名词的解释
一、名词解释
1、吞吐率:WEB服务器单位时间内处理的请求数。
2、最大并发用户数和最大并发连接数的本质区别?
- 当实际并发用户数稍稍大于服务器所能维护的文件描述符上线时,如果请求的性质决定了处理每个请求花费的时间非常少,比如请求1KB的静态网页,那么每个请求都可以快速处理然后释放文件描述符,这样从用户的角度而言,等待时间几乎不会较少太多。所以在这种情况下,我们希望服务的最大并发用户数可以大于最大并发连接数。
- 如果请求决定了处理每个请求要花费相当长的时间,比如下载10MB文件或者请求动态内容,那么即使服务器可以支持较大的并发连接数,比如使用异步IO理论上可能支持2万个并发连接,对于下载10MB文件来说,可能由于宽带的瓜分而导致每个用户下载速度缓慢。而对于请求动态内容,由于可能CPU的时间瓜分导致每个用户的等待时间过长。所有在这种情况下我们希望服务的最大并发用户数小于理论上的最大并发连接数。
3、进程的概念
进程是由内核调度,从内核的观点看,进程的目的就是担当分配系统资源的实体。同时进程也可以理解为记录程序实例当前运行到什么程度的一组数据,多个进程通过不同的进程描述符与这些数据进行关联。
每个进程都有自己独立的内存地址和生命周期。当子进程被父进程创建后便将父进程地址空间的所有数据复制到自己的地址空间,完全继承父进程的所有上下文信息,他们之间可以通信,但是互不依赖。它的创建有fork()系统调用,代价很大。
为此Linux 2.0之后,提供了对轻量级进程的支持,它由一个新的系统调用clone(),并由内核直接管理,像普通进程一样独立存在,各自拥有进程描述符,但是这些进程允许共享一些资源,比如地址空间、打开文件等。轻量级进程减少了内存的开销,并为多进程应用程序的数据共享提供了直接支持,但是上下文切换的开销还是在所难免。
引入线程的概念:从内核的角度来看,多线程只是一个普通的进程,他是由用户态通过一些库函数模拟实现的多执行流,所以多线程的管理完全在用户态完成,这种实现方式下线程切换的开销相比于进程和轻量级进程都要少些,但是它在多处理的服务器中表现较差,因为只有内核的进程调度器才有权分配多个CPU的时间。
POSIX线程另外一种实现,它可以说是内核级线程库,因为它通过clone()来创建线程,也就是说他的实现原理是将线程和轻量级进程一对一关联,每个线程实际上就是一个轻量级进程,这样使得线程完全由内核进程调度器来管理。
4、进程调度器
内核中的进程调度器维护着各种状态的进程队列,进程调度器维护着一个包括所有可运行进程的队列,称之为运行队列,以及一个包括所有休眠进程和僵尸进程列表。
它的一项重要的责任就是决定下一个运行的进程,如果运行的进程不只一个进程,所以引入了进程的优先级。进程的优先级除了可以由线程自己决定外,进程调度器在进程运行时也可以动态调整他们的优先级,比如对有些进程适当提高优先级,对有些进程进行处罚,降低他们的优先级,这些行为的出发点都是为了让所有进程更好地重叠系统资源。Linux可以使用命令:nice,pr表示进程调度器给进程的时间片长度,单位是时钟个数,一个时钟是多长时间这跟CPU主频和操作系统平台有关,比如Linux PR 15表示150ms。
5、系统负载
[root@SJSWT44-66 renren-profile]# cat /proc/loadavg
0.00 0.00 0.00 1/380 4647
1/380 1代表运行队列中的进程个数,而380表示此时进程的总数。
前面三个值表示1、5、15分钟得出的系统负载,0.0说明任何进程可以马上获得CPU,不需要等待。
6、进程的切换
上下文切换?
进程拥有自己独立的内存空间,但是每个进程都只能共享CPU寄存器。一个进程被挂起的本质就是将它的CPU寄存器的数据拿出来暂存在内核态堆栈中,而一个进程恢复工作的本质就是将它的数据重新装入CPU寄存器,这段装入和移除的数据就是硬件上下文除此之外进程上下文还包含了进程运行时需要的一切状态信息。
7、IOWait和锁竞争