哈嘍大家好,我是鹹魚 今天我們來聊聊電腦網路中的 MTU (Maximum Transmission Unit) 什麼是 MTU ? MTU(Maximum Transmission Unit)是指數據鏈路層中的最大傳輸單元 通俗點來講,MTU 是指數據鏈路層能夠傳輸的最大數據幀的大小(以位元組為單 ...
哈嘍大家好,我是鹹魚
今天我們來聊聊電腦網路中的 MTU (Maximum Transmission Unit)
什麼是 MTU ?
MTU(Maximum Transmission Unit)是指數據鏈路層中的最大傳輸單元
通俗點來講,MTU 是指數據鏈路層能夠傳輸的最大數據幀的大小(以位元組為單位)
以 CentOS 7 為例,可以通過 ifconfig
命令來查看 MTU 值
為什麼需要 MTU ?
我們知道,數據在數據鏈路層中通常是以數據幀(Frame)的形式來傳輸
因為傳輸的 Frame 不可能無限大(傳小的可以),那麼一次傳多大的 Frame 最合適、最高效就成了一個需要考慮的問題
所以說我們要設定一個值(也就是 MTU),這個值用來限制 Frame 的大小
維基百科有這麼一段話
Larger MTU is associated with reduced overhead. Smaller MTU values can reduce network delay.
由上面的話可以得出:
-
MTU越大,開銷越小
這句話是很容易理解的,更大的 Frame 意味著包含的有效數據也就更多
我一次能傳更多的數據了,那麼傳輸次數就少了,在網路上的開銷就變小了
-
較小的MTU值可以減少網路延遲
這句話容易讓人引起困惑,為什麼 MTU 值小能夠減少網路延遲呢?
如果 MTU 設置的很大,意味著一次能傳更大的數據了,那占據鏈路的時間就會更長,所以總體上網路延遲就會變大
而且如果一大段數據裡面有一個 bit 出錯了,這一大段就會整個重傳,重傳的代價是很大的
那麼 MTU 設置成多少合適呢?
為什麼 MTU 的值是 1500?
RFC 標准定義乙太網的預設 MTU 值為 1500,為什麼是 1500 ?
這是一個歷史遺留問題
早期的乙太網使用共用鏈路的工作方式,為了保證 CSMA/CD(載波多路復用/衝突檢測)機制,規定了以太幀長度最小為 64 位元組,最大為 1518 位元組
-
最小 64 位元組是為了保證最極端的衝突能被檢測到,64 位元組是能被檢測到的最小值
-
最大不超過 1518 位元組是為了防止過長的幀傳輸時間過長而占用共用鏈路太長時間導致其他業務阻塞
所以說數據幀的最大長度被限製為 1518 位元組(包括幀頭、幀尾和CRC校驗)
因此,1500 位元組被定義為乙太網數據幀中數據部分的最大長度(MTU)
雖然技術不斷發展,但這個規定一直沒有更改
乙太網經過幾十年的發展,速度已經從最初的10M被提升到了上百G,速度提高了上萬倍
在這樣高速度的傳輸數據中,如果還是延續經典乙太網的最大幀長不超過1518 位元組的限制,那麼在每秒中傳輸的數據包的個數將很大
於是一些廠商提出了巨型幀(Jumbo Frame)的概念,把乙太網的最大幀長擴展到了9K
目前還沒有獲得 IEEE 標準委員會的認可,但是大多數的設備廠商都已經開始支持
發送數據大小超過 MTU 怎麼辦?
乙太網的 MTU 預設值是 1500,如果發送 Frame 小於 MTU(例如 1000 位元組),直接傳輸就行
如果大於 MTU(4000 位元組),那就需要進行分片(Fragment)
即第一次發送 1500 位元組(IP header 20 位元組 + Payload 1480 位元組)
第二次發送 1500 位元組(IP header 20 位元組 + Payload 1480 位元組)
第三次 1000 位元組(IP header 20 位元組 + Payload 980 位元組)
可能有小伙伴問,那我傳的數據大小不夠數據幀規定的最小 64 位元組怎麼辦?
答案是:在實際數據內容後面添加填充數據,使得數據包總長度達到最小長度要求。填充數據可以是任意無意義的位元組,例如全 0 或全 1 的數據
如何保證發送的數據不超過 MTU ?
前面我們知道,如果發送的數據大於 MTU,則就會進行分片操作
要讓最終傳給數據鏈路層的 Frame 數據大小不超過 1500 bytes,就要保證上層中的每一層的數據都沒有超過這個大小
如果 MTU 是 1500,那麼 IP 層就要保證 IP 層的 Packet 數據不超過 1480 bytes (1500 bytes – 20 bytes IP header),
對於 TCP 來說,它要保證每一個 Segment 數據大小不超過 1460 bytes (1460 bytes – 20 TCP header)
以 TCP 層(傳輸層)為例子, TCP 層是怎麼知道發送的數據不會超過 MTU 呢?
-
IP 層(網路層)問數據鏈路層數據最大傳輸單元( MTU )是多少
-
TCP 層會問 IP 層數據最大傳輸大小(Maximum packet size)是多少
這樣 TCP 層就會知道自己的最大傳輸數據大小,叫做 MSS(Maximum segment size)
在 TCP 的握手階段,MSS(Maximum Segment Size)是用於指定TCP報文段中數據部分的最大長度
對於 TCP 來說,知道自己的 MSS 沒有什麼用
例如作為接收端來說,收到的包大小取決於發送端,得讓發送端知道自己的 MSS 才行
所以在建立 TCP 連接時,雙方需要協商一個合適的 MSS 值,以便在數據傳輸過程中進行分片和重組
什麼是 TSO
前面我們介紹了什麼是 MTU、MSS
如果你去抓一下包看看,你可能會遇到下麵這種情況
明明協商了 MSS 為 1460 位元組,為什麼數據居然有一萬多位元組?
在建立 TCP 連接時,雙方需要協商一個合適的 MSS 值,以便在數據傳輸過程中進行分片
但是這個分片過程往往是簡單重覆而且計算量比較大的,需要占用較多的 CPU 資源
所以網卡就會對內核說:哥這種小事我來乾就好了,不需要麻煩您
然後內核就會把大包發給網卡,網卡來負責分片
這個叫做 TSO(TCP Segment Offload)
TSO(TCP Segmentation Offload)是一種網路傳輸卸載技術,用於減輕主機的網路數據包分段負擔,提高網路傳輸性能
我們在抓包的時候看到是還在內核里的包,後面網卡拆包的過程是看不到的
網卡不但能對發送的包進行 offload,也可以對接收的包進行 onload,簡單來說就是網卡會先把一些小的包積攢下來,然後合起來發送給內核
# 查看網卡上面是否開啟 TSO 功能
# on 表示開啟
[root@root~]# ethtool -k <網卡名稱>
tcp-segmentation-offload: on
tx-tcp-segmentation: on
tx-tcp-ecn-segmentation: on
tx-tcp6-segmentation: on
tx-tcp-mangleid-segmentation: off
最後總結一下:
-
MTU 是指數據鏈路層能夠傳輸的最大數據幀的大小(以位元組為單位)。由於歷史原因,MTU 的值最小為 64 位元組,最大為 1518 位元組(Payload 則是 46~1500 位元組)
-
如果發送的數據大於 MTU,則就會進行分片操作;如果小於 MTU,就會在實際數據內容後面添加填充數據,使得數據包總長度達到最小長度要求
-
-
TSO(TCP Segmentation Offload)是一種網路傳輸卸載技術。TSO 技術將分片過程從 CPU 轉移到網卡上的專用硬體,網卡負責將應用程式的大塊數據分段為適當大小的數據包,並添加 TCP 首部,然後直接發送到網路上