You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
|
|
![[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.通过网卡将数据传输给消费者
|