从操作系统说起
计算机系统是由“硬件”和“软件”两大部分组成,计算机硬件包括一个或多个处理器(CPU)、内存、键盘、显示器、磁盘、I/O接口以及其他一些外围设备比如打印机,绘图仪等等。
总之,计算机硬件部分是一个由多种电子和机械设备组成的硬件系统。
为了让人方便正确使用这些设备,就需要编写若干程序来管理这些设备,正是这些程序组成了计算机的软件系统。软件也可以分为两大类:系统软件和应用软件。人们首先直接在硬件上加载一层程序,用它来管理整个计算机硬件设备以及一些软件信息资源,同时还为用户提供开发应用程序的环境,这就是操作系统软件和实用软件。应用软件是在操作系统支持下,为实现用户要求而编制的各种应用程序。
CPU、内存和I/O接口组成的主设备通常称为主机,把没有加载操作系统的主机叫做裸机。裸机与操作系统软件的接口是由CPU的指令系统和厂商提供的系统BIOS组成。
由于操作系统向用户隐藏了系统使用的硬件设备,因此操作系统要为它上面的应用系统软件提供一组命令或系统调用接口供用户程序使用。比如我们需要使用磁盘,可以通过系统命名或系统调用来间接完成,而不需要亲自手动编写一个磁盘设备驱动程序。因此对于用户来说,当计算机加载操作系统后,用户不直接与计算机硬件打交道,而是利用操作系统提供的命令和功能区使用计算机。
由于操作系统处于硬件和软件的中央位置,因此很早就有人把操作系统成为计算机系统软件的核心,简称核心或内核。
内核态和用户态
从系统安全和保护的角度出发,在进行计算机体系结构设计时,处理机的执行模式一般设定为两种:分别称为内核模式(内核态)和用户模式(用户态)。当处理机处于内核模式执行时,意味着系统除了可以执行一般指令外,还可以执行特权指令,即可以执行访问各种控制寄存器的指令、I/O指令以及程序状态字。
当处理机处于用户模式执行时,只能执行一般指令,而不允许执行特权指令。这样做可以保护核心代码不受用户程序有意和无意的攻击。
显然,处理机在运行期间需要在内核模式和用户模式之前进行切换。
零拷贝
Kafka使用零拷贝(Zero-Copy)技术来提供它的性能,所谓的零拷贝是指将数据直接从磁盘文件复制到网卡设备中,而不需要经由应用程序之手,减少了内核和用户模式之间的上下文切换,零拷贝技术通过DMA技术实现。
直接存储器存取方式(Direct Memory Access, DMA)
DMA控制方式是以存储器为中心,在主存和I/O设备之间建立一条直接通路,在DMA控制器的控制下进行设备和主存之间的数据交换。这种方式只在传输开始和传输结束时才需要CPU的干预。它非常适用于高速设备与主存之间的成批数据传输。
我们看下下面这样的这样一个场景:
客户端在游览器中发起请求获取内容,到看到具体内容经历了什么?
首先,该请求经过解析后,通过系统调用由用户态转为核心态执行,在核心态由操作系统中的TCP/IP协议代码和网卡驱动程序控制网卡把请求发送到相应的网络上,
等待Web服务器相应。当服务器返回时,由网卡接受,并通过内核传送给客户程序。
在服务器端,内核通过网卡从网络上接受Web请求,并通过系统调用传递给Web服务器。Web服务器根据此服务请求执行相应的服务进程,并由内核把结果发送到网络上传送给用户。
从上图中可以看到如果服务器从准备数据到发送数据经历了下面4个过程。
- 调用read()时,将文件中的内容复制到内核模式下的Read Buffer中
- CPU控制将内核模式数据复制到用户模式下
- 调用send()时,用用户模式下的内容复制到内核模式下的Socket Buffer中。
- 将内核模式下的Socket Buffer的数据复制到网卡设备中发送。
从上面过程可以看出,数据是先从内核模式–>用户模式–>内核模式,浪费了2次复制过程:第一次是从内核模式复制到用户模式;第二次是从用户模式再复制回内核模式,而且在上面的过程中,内核和用户模式的上下文切换也是4次。
如果采用了零拷贝技术,那么应用程序就可以直接请求内核把磁盘中的数据传输给Socket.
零拷贝技术通过DMA技术将文件内容复制到内核模式下的Read Buffer中。不过没有数据被复制到Socket Buffer,只有包含数据的位置和长度的信息的文件描述符被加到Socket Buffer中。DMA引擎直接将数据从内核模式中传递到网卡设备。这里上下文切换变成了2次,也只经历了2次复制过程就从磁盘中传送出去了。