《深入理解Linux网络》读书笔记3

本次主要阅读了第四章,同时回顾了第三章的一些知识,学习和梳理了内核的发包

网络发包具体流程啥样?

在这里插入图片描述

为什么查看/proc/softirqs,NET_RX比NET_TX大的多

  • 首先要将NET_RX、NET_TX与UART等协议中的TX、RX区别开来,在linux中,RX并不只接收数据、TX并不只发送数据,所以原因有二:

    • 一是:当数据发送完毕时,通过硬中断的方式来通知驱动发送完毕。但是硬中断无论时数据接收,还是发送完毕,触发的软中断都是NET_RX_SOFTIRQ,并不是NET_TX_SOFTIRQ。

    • 二是:对于读来说,都是要经过NET_RX软中断的,都走ksoftirqd内核线程。而对于发送来说,绝大部分工作都是在用户进程内核态处理了,只有系统态配额用尽才会发送NET_TX,让软中断上。

综上,导致了NET_RX比NET_TX大的多

发送网络数据的时候涉及的内存拷贝操作

此处内存拷贝,只指待发送数据的内存拷贝

  • 第一次:在内核申请完skb后,会将用户传递进来的buffer里的数据内容都拷贝到skb。(如果发送数据比较大,此次拷贝开销也会较大)

  • 第二次:从传输层进入网络层的时候,每一个skb都会被克隆出来一个新的副本。目的是保存原始的skb,当网络对方没有回应ack时,还可以重新发送,以实现可靠传输。此处拷贝为浅拷贝,所指向的数据还是复用的。

  • 第三次(非必需):当IP层发现skb大于MTU时才需进行。此时会再申请额外的skb,并将原来的skb拷贝为多个小的skb。

啥是零拷贝

通过sendfile系统调用来举例

  • 如果要将本机的一个文件发送出去,做法之一是先用read系统调用把文件读取到内存,然后再调用send将文件发送出去。

    • 假设数据之前从来没有读取过,那么read硬盘上的数据需要经过两次拷贝才能到用户进程的内存。第一次是从硬盘DMA到Page Cache。第二次是从Page Cache拷贝到用户内存。

    • 此时,前面提到的sendfile就派上用场了,再sendfile系统调用中,数据不需要拷贝到用户空间,在内核态就可以完成发送处理,显著减少了需要拷贝的次数。

题外话:为什么Kafka网络性能突出?

结合本章内容可以知道一个重要原因:Kafka采用了sendfild系统调用来发送网络数据包,减少了内核态和用户态之间的频繁数据拷贝。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值