零拷贝(zero copy)与Linux内核

如今网络应用已经从cpu密集型转成了I/0密集型,你CRUD是没有啥cpu消耗的,唯一瓶颈就是多线程,切来

切去的消耗

CS(客户端服务器),BS(浏览器服务器)。BS就是一种特殊的架构

计算机存储器

最低端是与cpu同频的寄存器

容量大,速度快,价格便宜三者无法同时满足

1.第一层寄存器

作用:让 CPU 快速访问和处理数据,避免频繁访问速度较慢的内存,是 CPU 执行指令的核心中转站

2.第二层高速缓存

3.主存

4.磁盘

5.物理内存

6.虚拟内存

没有什么是加一层中间件不能解决,如果有那就再加一层,这是计算机领域几乎真理的话

虚拟内存正是此话的又一个重要实践

操作系统32位操作系统,2的32次方,寻址也就只有4GB啊,那你怎么用上8GB的呢

应用程序是不能直接操作物理内存,都是操作虚拟内存,而虚拟内存有一张映射表,它可能映射到磁盘or内

存,这个就不得而知了

7.MMU(内存管理单元)

作用就是管映射到哪去

如果使用虚拟内存技术的话,cpu则会把这些虚拟内存地址通过地址总线送到内存管理单元MMU,MMU

再将虚拟内存地址转成 物理地址之后再通过内存总线访问物理内存

8.用户态和内核态

Linux安全的一个原因就是区分用户态和内核态,硬件只能内核态来操作,即调操作系统函数委托内核来

帮你干事

在资源和用户做了隔离,你碰不到就是安全的

Linux I/O

1.IO缓冲区

脏不是说数据有问题,只是说没落盘

刷flush了就不脏dity了。只要不是批量写,都有卡的问题

一般数据丢失,都是没刷盘就断电了

2.传统I/O读写模式

Linux的系统模式 read,write

3.zero 拷贝

指cpu不需要先将数据从某个内存复制到另外一个特定区域,这种技术通常用于通过网络传输文件时节省cpu

周期和内存带宽,即不用倒腾数据到用户态了

**3.1 mmap(memory map) **

map就是个映射

用对象,一种是深拷贝(产生新的对象),一种是浅拷贝(用的还是同一个对象)

mmap就是一种浅拷贝

这种方式是zero 拷贝较为简单的实现方式,通过调用Linux的系统函数mmap()替换原先的read()

不用拷贝到内存,直接在内核里面倒腾

两步走:先mmap 再 write,但还是4次切换

以上是老版本的Linux

3.2 sendfile()

这里的就做得更到底了,sendfile()就相当于把mmap 和 write合成了一个内核函数,这么做的好处就是少了

两次切换,因为原来是调两函数,调完后还得切回去继续调另外一个

kafka就是用sendfile来实现零拷贝,rocketmq还是用的mmap

:::color4
零拷贝,零拷贝,其实还得是拷贝的,只是不用拷贝到用户态了,直接在内核态里拷贝,对于用户态是无感知的

:::

总结

零拷贝 约等于 对象浅拷贝,直接返回引用映射