再也不怕面试官问零拷贝技术

简介: 该文章主要讨论了零拷贝技术的相关概念、传统IO读写操作的过程以及零拷贝技术的两种实现方法。

零拷贝技术前戏

在了解零拷贝之前,我们先了解下传统IO的读写操作

我们经常会使用下面两个函数向操作系统发起IO请求

//从文件或者网络socket读数据
read(file, tmp_buf, len);
//写数据到文件或者网络socket
write(socket, tmp_buf, len);

这两个函数,会阻塞客户端线程,直到IO操作完成。读写经历的过程通过下图来理解:

从上下文切换与数据拷贝两个方面来描述上面传统IO读写过程

1、首先应用程序发起read 系统调用,此时发生了从应用程序态转化成内核态一次转换

2、操作系统接收到read系统调用后,通过DMA(Direct Memory Access, 协助cpu拷贝数据的工具) copy 将硬件磁盘上的数据拷贝到内核缓冲区,此时发生了一次数据拷贝

3、从内核缓冲区拷贝数据到用户缓冲区,发生了一次数据拷贝与上写文切换

4、此时再发起系统write调用,从用户态转化成系统态,发了一次上下文切换

4、从用户缓冲区拷贝数据到socket缓冲区,发生了一次数据拷贝,并发生了一次上下文切换

5、DMA再将socket缓冲区数据拷贝到协议层,发生了一次数据拷贝

总结:以上过程共发生了4次上下文切换,数据拷贝,其实很多拷贝与切换操作不是必须的,造成IO性能低下

那么有没有办法避免上面提到的多次数据拷贝和上下文切换呢?这个时候零拷贝技术就可以上场了。零拷贝技术通常有两种方式实现。

零拷贝杀手锏之一mmap+write

tmp_buf = mmap(file, len);

write(socket, tmp_buf, len);

流程梳理:

1、调用mmap系统调用,DMA将磁盘数据拷贝到内核缓冲区,随后,内核缓冲区与用户缓冲区共享该数据,并不会发生复制操作

2、接着写系统调用执行,将内核缓冲区数据拷贝到socket缓冲区

3、最后DM将socket缓冲区数据拷贝到协议层引擎,完成数据传输

总结:mmap方式减少了一半的上下文切换与数据拷贝开销,存在1个问题

1、共享内核数据时候,当内存映射一个文件,然后在另一个进程截断同一文件时调用write时,文件将可能被并发修改。写入系统调用将被总线错误信号SIGBUS中断,该信号的默认行为是终止进程并转储核心。有两种方式解决该问题:

第一种可以通过自定义信号处理器,处理该信号,发挥中断前写好的数据,并将失败标志设置返回成功

第二种解决方案涉及从内核中租借文件(在微软Windows中称为“机会锁定”),操作系统会实时发送信号量给你,标志有其他程序需要使用该文件,可以在需要该文件前租约该文件,使用完再销毁该租约,类似于分布式锁,先锁住,我要用,用完了别人才能用。

零拷贝杀手锏之二sendfile机制

sendfile机制不仅减少了上下文切换也减少了数据拷贝,减少网络与本地文件之间拷贝次数。

分析以上过程发现

1、应用程序发起sendfile调用,DMA引擎将文件内容复制到内核缓冲区中

2、没有数据被复制到套接字缓冲区中。相反,只有包含数据位置和长度信息的描述符才会附加到套接字缓冲区。DMA引擎将数据直接从内核缓冲区传递到协议引擎,从而消除剩余的最终副本

3、因为数据实际上仍然是从磁盘复制到内存和从内存复制到导线,所以有些人可能会认为这不是真正的零拷贝。不过,从操作系统的角度来看,这是零拷贝,因为数据不会在内核缓冲区之间重复。使用零拷贝时,除了避免拷贝之外,还可以获得其他性能优势,例如更少的上下文切换、更少的CPU数据缓存污染和无CPU校验和计算。

总结

零拷贝技术对于网络IO的优化作用非常有利,本文分析了令拷贝出现的价值,零拷贝实现的手段,在很多中间件中使用了比较多,比如netty,kafka,rocketmq,zookeeper,redis,可知零拷贝技术是非常有用的,它大大的改善了传统IO慢的问题,提升服务IO整体性能。

相关文章
|
1月前
|
Linux 数据安全/隐私保护 Perl
解锁Linux高手秘籍:文件操作+命令解析大揭秘,面试场上让你光芒万丈,技术实力惊艳四座!
【8月更文挑战第5天】Linux作为服务器与嵌入式系统的基石,其文件管理和命令行操作是技术人员必备技能。本文从文件操作和基础命令两大方面,深入浅出地解析Linux核心要义,助你在面试中脱颖而出。首先探索文件系统的树状结构及操作,包括使用`ls -la`浏览文件详情、`touch`创建文件、`rm -r`慎删目录、`cp`与`mv`复制移动文件、以及利用`find`搜索文件。接着掌握命令行技巧,如用`cat`、`more`和`less`查看文件内容;借助`grep`、`sed`与`awk`处理文本;运用`ps`、`top`和`kill`管理进程;并通过`chmod`和`chown`管理文件权限。
62 8
|
1月前
|
监控 Linux 数据安全/隐私保护
Linux大神养成记:掌握这些逆天命令与快捷方式,面试秒变MVP,让你的技术实力燃爆全场!
【8月更文挑战第5天】Linux作为开源领域的核心,熟悉其基本命令对系统管理员和技术人员至关重要。本文精选了面试中常考的Linux命令,覆盖文件管理、文本处理、进程监控及权限调整等关键领域,并介绍了提高效率的快捷方式。通过掌握如`ls -l`、`grep "error"`、`top`、`chmod 755`等实用命令,以及Tab自动补全、历史命令浏览等功能,不仅能显著提升日常工作效能,还能在求职面试时展现出扎实的技术功底。
46 4
|
2月前
|
存储 搜索推荐 数据库
面试题MySQL问题之个性化推荐广告系统中ETL技术与Aerospike的结合使用如何解决
面试题MySQL问题之个性化推荐广告系统中ETL技术与Aerospike的结合使用如何解决
34 2
|
3月前
|
SQL 存储 前端开发
程序技术好文:面试知识点六:JavaWeb
程序技术好文:面试知识点六:JavaWeb
38 1
|
2月前
|
Java 应用服务中间件 持续交付
Java面试题:简述Docker等容器化技术的原理及其在Java应用部署中的作用。
Java面试题:简述Docker等容器化技术的原理及其在Java应用部署中的作用。
48 0
|
2月前
|
搜索推荐 算法 网络协议
如何做好IT类的技术面试?
如何做好IT类的技术面试?
41 0
|
3月前
|
XML Java 数据库连接
面试必备!Java核心技术100+面试题
面试必备!Java核心技术100+面试题
|
3月前
|
SQL 网络协议 Java
技术经验分享:Java不会或做错的面试题总结
技术经验分享:Java不会或做错的面试题总结
30 0
|
3月前
|
Web App开发 存储 前端开发
技术心得记录:前端面试题汇总
技术心得记录:前端面试题汇总
|
28天前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。