![[Pasted image 20231122155709.png]] 消费者读取数据流程: 1. 消费者发送请求给kafka服务 2. kafka服务去os cache缓存读取数据(缓存没有就去磁盘读取数据) 3. 从磁盘读取了数据到os cache缓存中 4. os cache复制数据到kafka应用程序中 5. kafka将数据(复制)发送到socket cache中 6. socket cache通过网卡传输给消费者 ## 传统IO ![[Pasted image 20231122160218.png]] 伪代码: ```text buffer = File.read Socket.send(buffer) ``` 1、第一次:将磁盘文件,读取到操作系统内核缓冲区; 2、第二次:将内核缓冲区的数据,copy到application应用程序的buffer; 3、第三步:将application应用程序buffer中的数据,copy到socket网络发送缓冲区(属于操作系统内核的缓冲区); 4、第四次:将socket buffer的数据,copy到网卡,由网卡进行网络传输。 传统方式,读取磁盘文件并进行网络发送,经过的四次数据copy是非常繁琐的。实际IO读写,需要进行IO中断,需要CPU响应中断(带来上下文切换),尽管后来引入DMA来接管CPU的中断请求,但四次copy是存在“不必要的拷贝”的。 重新思考传统IO方式,会注意到实际上并不需要第二个和第三个数据副本。应用程序除了缓存数据并将其传输回套接字缓冲区之外什么都不做。相反,数据可以直接从读缓冲区传输到套接字缓冲区。显然,第二次和第三次数据copy 其实在这种场景下没有什么帮助反而带来开销,这也正是零拷贝出现的意义。 ## kafka零拷贝IO 1.消费者发送请求给kafka服务 2.kafka服务去os cache缓存读取数据(缓存没有就去磁盘读取数据) 3.从磁盘读取了数据到socket缓存中 4.socket直接将数据发送给网卡 5.通过网卡将数据传输给消费者