MTU 值是什麼意思?1500、1492 與對網速的影響
MTU 值(Maximum Transmission Unit,最大傳輸單元)是一個網路介面一次能發出的最大 IP 包長度,單位是位元組,包含 IP 首部,不含乙太網幀頭。乙太網預設 1500,PPPoE 撥號要多佔 8 位元組封裝,所以是 1492。MTU 合適時對網速幾乎沒有影響,路徑上某段 MTU 偏小、傳送方又收不到通知時,才會出現網頁打不開、大檔案傳不動。
MTU 值是網路介面一次能傳送的最大 IP 包長度(Maximum Transmission Unit,最大傳輸單元),以位元組計,包括 IP 首部和裡面的 TCP、UDP 首部,但不包括乙太網幀頭和校驗欄位。普通乙太網的 MTU 是 1500,意思是一個乙太網幀最多裝 1500 位元組的 IP 包;IP 包比路徑上某一段的 MTU 大,IPv4 要麼分片、要麼丟棄並通知傳送方,IPv6 的路由器不分片,只能由傳送方自己切小。家用寬頻 PPPoE 撥號多了 8 位元組封裝,MTU 變成 1492。絕大多數伺服器保持預設的 1500 即可,需要動 MTU 的是隧道、VXLAN、PPPoE 和儲存網巨幀這幾類場景。
MTU 1500 是什麼意思:1500 位元組裡裝了什麼
以一個滿長度的 TCP 報文為例,看看線路上的一幀由哪些部分組成,哪些算進 MTU:
| 部分 | 位元組 | 算不算進 MTU |
|---|---|---|
| 前導碼與幀起始定界符 | 8 | 不算,只佔線路時間 |
| 乙太網頭:目的 MAC、源 MAC、型別 | 14 | 不算 |
| 802.1Q VLAN 標籤(帶標籤時) | 4 | 不算 |
| IPv4 首部 | 20(IPv6 為 40) | 算 |
| TCP 首部 | 20,帶時間戳選項時 32 | 算 |
| 應用資料 | 1460,帶時間戳選項時 1448 | 算 |
| 幀校驗序列 FCS | 4 | 不算 |
| 幀間隙 | 12 | 不算,只佔線路時間 |
所以 MTU 1500 對應的乙太網幀是 1518 位元組(帶 VLAN 標籤 1522),線上路上實際佔 1538 位元組的時間。
這裡有個常見的混淆:MTU 是三層概念,幀長是二層概念。Linux 上 ip link 顯示的 1500 指 IP 包;不少交換器在連接埠上配置的是最大幀長,開巨幀時常見的 9216 就包含了二層頭。伺服器設成 9000 時,交換器連接埠至少要能收 9018 位元組的幀(帶 VLAN 標籤 9022)。各廠商介面命令裡的“MTU”算不算二層頭並不統一,以裝置文件為準。
檢視本機 MTU:
ip link show eth0 # 輸出中的 mtu 1500
cat /sys/class/net/eth0/mtu
netsh interface ipv4 show subinterfaces
MTU 值 1492 和 1500 的區別,以及 MTU 的取值範圍
1492 比 1500 少的 8 位元組
區別就在 PPPoE 的 8 位元組:PPPoE 頭 6 位元組(版本與型別、程式碼、會話 ID、長度),再加 PPP 協議欄位 2 位元組。乙太網幀的資料部分仍然最多 1500 位元組,扣掉這 8 位元組,留給 IP 包的只剩 1492(RFC 2516)。
| 鏈路 | 乙太網幀資料部分 | 封裝開銷 | IP 包最大(MTU) | TCP 的 MSS(IPv4) |
|---|---|---|---|---|
| 普通乙太網 | 1500 | 0 | 1500 | 1460 |
| PPPoE 撥號 | 1500 | 8 | 1492 | 1452 |
1492 不是“更好”或“更差”的數值,它是由鏈路決定的,設錯才會出問題:
- 撥號介面是 1492,內網口仍是 1500。電腦按 1500 發出的 TCP 包到了路由器裝不進 PPPoE,所以家用路由器和光貓一般會在撥號介面上自動改寫 TCP 握手裡的 MSS(MSS 鉗制),讓連線一開始就用 1452 的資料段,電腦上不用改。
- 機房伺服器一般不涉及 1492。伺服器是靜態位址接入,MTU 為 1500;存取它的家庭使用者在 PPPoE 後面,他們握手時帶過來的 MSS 已經是 1452,伺服器的 TCP 會自動按小的那個發。
- 有的運營商支援 1500 的 PPPoE。RFC 4638 允許兩端在支援 1508 位元組乙太網載荷時讓 PPPoE 承載完整的 1500,是否可用以運營商為準。
MTU 值範圍與常見取值
| 場景 | MTU(IP 包,位元組) | 來由 |
|---|---|---|
| IPv4 最小值 | 68 | RFC 791 要求每條鏈路至少能不分片地傳 68 位元組 |
| IPv6 最小值 | 1280 | RFC 8200 規定,達不到的鏈路必須在下層自行分片重組 |
| 乙太網標準 | 1500 | 伺服器、交換器、寬頻的預設值 |
| PPPoE 撥號 | 1492 | 多 8 位元組封裝 |
| GRE 隧道 | 1476 | 外層 IPv4 首部 20 + GRE 頭 4 |
| IPIP、6in4 隧道 | 1480 | 外層 IPv4 首部 20 |
| VXLAN(承載網 MTU 1500) | 1450 | 見下文“機房裡什麼時候需要調整” |
| WireGuard | 常見預設 1420 | 按 IPv6 外層預留 80 位元組;外層是 IPv4 時實際開銷 60 位元組 |
| IPsec | 視演算法和模式而定 | 加密演算法、認證演算法和隧道模式不同,開銷不同,以實測為準 |
| 巨幀 | 常見 9000 | 不是 IEEE 標準值,網路卡和交換器支援的上限各不相同,以規格書為準 |
MTU 和 MSS 是什麼關係
MSS(Maximum Segment Size,最大報文段長度)是 TCP 一個報文段裡能裝的資料量,由 MTU 減去 IP 首部和 TCP 首部得到:IPv4 是 1500 − 20 − 20 = 1460,IPv6 是 1500 − 40 − 20 = 1440。雙方在三次握手的 SYN 裡各自告訴對方“我能收多大的段”,傳送時取對方通告的 MSS 和本端路徑 MTU 中較小的那個。Linux 預設開啟 TCP 時間戳,每段還要再讓出 12 位元組,所以實際每段裝 1448 位元組。
一條已建立連線實際在用的值,可以直接看:
ss -tin dst 203.0.113.10
# 輸出裡的 mss:1448 pmtu:1500 分別是當前每段的資料量和這條路徑的 MTU
MSS 和 MTU 的關係決定了 MSS 鉗制這個常用手段:在隧道或撥號的閘道器上,把經過的 SYN 裡的 MSS 改小,兩端就會主動發小包,不必等分片或丟包。例如 GRE 隧道 MTU 為 1476,對應 MSS 1436:
iptables -t mangle -A FORWARD -o gre1 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1436
思科路由器在介面下用 ip tcp adjust-mss 1436,其他廠商有類似命令,以裝置文件為準。要注意 MSS 鉗制只對 TCP 有效,UDP 和 ICMP 的大包照樣超長,基於 UDP 的業務要靠應用自己控制包長。
MTU 不匹配會怎樣:分片、PMTUD 黑洞與“網頁打不開”
Linux 的 TCP 預設在 IPv4 包上設定 DF(禁止分片)位,靠路徑 MTU 發現(PMTUD,RFC 1191)找到合適的包長:
- 傳送方按本機 MTU 1500 組包,並設定 DF 位。
- 路徑上某台路由器的出介面 MTU 只有 1476,例如要進入 GRE 隧道,裝不下,就丟棄這個包,回一條 ICMP 型別 3、程式碼 4 的“需要分片但設定了 DF”訊息,裡面寫著 1476。
- 傳送方收到後,把這條路徑的 MTU 記為 1476,切小重發,連線繼續。
- 如果第 2 步的 ICMP 被沿途的防火牆或安全組過濾掉,傳送方永遠收不到通知,只會一遍遍重傳同樣大小的包。這就是 PMTUD 黑洞。
IPv6 同理,通知訊息是 ICMPv6 型別 2(包過大),而且 IPv6 路由器從不替你分片,攔掉它就一定是黑洞。黑洞的症狀很有辨識度,共同點是“小包能過、滿長度的包過不去”:
| 現象 | 原因 |
|---|---|
| ping 正常、SSH 能登入,一檢視大檔案或輸出很多內容,終端就卡住 | 敲命令和回顯都是小包,大段輸出才會湊成滿長度的包 |
| 網頁能開啟一部分,大頁面、圖片載入到一半停住 | 前面的小包透過了,後面滿長度的包被丟 |
HTTPS 卡在 TLS 握手,curl -v 停在 Client hello 之後 |
伺服器發回的證書鏈通常有幾 KB,要拆成多個滿長度的包 |
| scp、rsync 進度停在 0% | 一開始傳的就是滿長度的資料包 |
| VPN 連上了,能 ping 通對端內網,內網網頁和檔案共享打不開 | 隧道封裝讓路徑 MTU 變小 |
沒有設定 DF 的 IPv4 包會被路由器分片轉發,不會形成黑洞,但任何一片丟失整個包就作廢,按連接埠過濾的防火牆也可能丟棄不帶連接埠資訊的後續分片。
定位時先用 tracepath 看路徑 MTU 在哪一跳變小,再用禁止分片的 ping 驗證:
tracepath -n 203.0.113.10
ping -M do -s 1472 -c 3 203.0.113.10 # 1472 + 8(ICMP 頭)+ 20(IP 首部)= 1500
tcpdump -nni eth0 'icmp[icmptype] == 3 and icmp[icmpcode] == 4' # 有沒有收到“需要分片”的通知
tracepath 的輸出類似下面這樣(範例),第 2 跳出現 pmtu 1476,最後的 Resume 行給出整條路徑的 MTU:
1?: [LOCALHOST] pmtu 1500
1: 198.51.100.1 0.418ms
2: 192.0.2.9 1.902ms pmtu 1476
2: 192.0.2.9 2.015ms
3: 203.0.113.10 9.877ms reached
Resume: pmtu 1476 hops 3 back 3
tracepath 同樣依賴 ICMP 通知,已經形成黑洞時它看不出變化,這時以 ping 的結果為準:1472 發出去沒有任何回應、減小到某個值才通,那個值加 28 就是路徑 MTU。處理方法按優先順序:
- 放行 ICMP 型別 3 程式碼 4 和 ICMPv6 型別 2,讓 PMTUD 正常工作,例如
iptables -A INPUT -p icmp --icmp-type fragmentation-needed -j ACCEPT。 - 在隧道或撥號的閘道器上做 MSS 鉗制。
- 在伺服器上設定
net.ipv4.tcp_mtu_probing=1,核心檢測到黑洞後自動改用更小的包探測(RFC 4821),預設值 0 表示關閉。 - 把傳送端網路卡 MTU 調小。它會影響這台機器的全部流量,作為最後的手段。
MTU 值對網速有什麼影響
先算一筆帳:線上路上,每個幀除了 IP 包還要佔 38 位元組(乙太網頭 14、FCS 4、前導碼 8、幀間隙 12),IP 包裡又要扣掉 52 位元組的 IPv4 和 TCP 首部(含時間戳選項)。不同 MTU 下,線路時間裡真正用來傳資料的比例是:
| MTU | 線路上每幀佔用 | 每幀 TCP 資料 | 有效載荷佔比 |
|---|---|---|---|
| 9000 | 9038 | 8948 | 99.0% |
| 1500 | 1538 | 1448 | 94.1% |
| 1492(PPPoE,幀內多 8 位元組封裝) | 1538 | 1440 | 93.6% |
| 1400 | 1438 | 1348 | 93.7% |
| 1280 | 1318 | 1228 | 93.2% |
結論很直接:在 1280 到 1500 之間,MTU 設多少,頻寬利用率只差 1 個百分點左右。把 MTU 從 1500 降到 1400,速度不會有可感知的變化;反過來,在公網上也不可能靠調大 MTU 提速,因為路徑上的大多數鏈路就是 1500。真正讓網速“變慢”的是 MTU 不匹配:被丟的包要等超時重傳,TCP 又把丟包當成擁塞而降速,嚴重時連線直接卡死。
巨幀的收益也不主要在頻寬上,而在包數量上。10 Gbps 跑滿時,1500 的 MTU 每秒約 81.3 萬個包,9000 的 MTU 每秒約 13.8 萬個,只有前者的六分之一左右,主機處理中斷和協議棧的開銷隨之下降。現代網路卡普遍有 TSO、GRO 等分段解除安裝功能,大包的切分和合並交給網路卡完成,巨幀帶來的 CPU 節省比這個比例小,實際效果以壓測為準。
機房裡什麼時候需要調整 MTU:隧道、VXLAN 與巨幀
需要調整的情況,幾乎都來自“包外面又套了一層”。常見封裝的開銷,以及想讓裡面的業務繼續用 1500 時,承載網至少要多大:
| 封裝 | 額外開銷(位元組) | 承載網為 1500 時內層可用的 MTU | 內層要保持 1500,承載網至少 |
|---|---|---|---|
| 802.1Q VLAN 標籤 | 4,加在幀上,不佔 IP 包 | 1500 | 交換器能收 1522 位元組的幀,支援 802.1Q 的交換器都滿足 |
| QinQ 雙層標籤 | 8,同上 | 1500 | 交換器能收 1526 位元組的幀 |
| PPPoE | 8 | 1492 | 1508 |
| GRE(IPv4 外層) | 24 | 1476 | 1524 |
| IPIP、6in4 | 20 | 1480 | 1520 |
| VXLAN(IPv4 承載) | 50 | 1450 | 1550 |
| VXLAN(IPv6 承載) | 70 | 1430 | 1570 |
| WireGuard(IPv4 外層) | 60 | 1440 | 1560 |
VXLAN 的 50 位元組是這樣來的:它把內層的整個乙太網幀(14 位元組幀頭加 IP 包)裝進外層 UDP,再加上 VXLAN 頭 8、UDP 頭 8、外層 IPv4 首部 20,比內層 IP 包多出 14 + 8 + 8 + 20 = 50 位元組。
處理隧道和 VXLAN 有兩種思路:
- 調大承載網 MTU:資料中心內部的交換器都在自己手裡時,把承載網設到 1600 或直接開巨幀,租戶和虛擬機器繼續用 1500,不用逐台修改。這是優先選擇。
- 調小內層 MTU:承載網改不了(例如跨公網的隧道)時,把內層設為 1450 之類的值,可以透過 DHCP 選項 26 下發給虛擬機器,同時在閘道器上做 MSS 鉗制。
開巨幀要守住幾條規則:
- 只在封閉的二層範圍內用:儲存網(iSCSI、NFS、Ceph 叢集網)、虛擬化遷移網、備份網;公網介面和上聯運營商的介面保持 1500。
- 同一網段的主機和交換器連接埠一起改:主機 9000,交換器連接埠按幀長設到裝置支援的上限。二層交換器丟棄超長幀時不會發任何 ICMP 通知,只在連接埠計數里留下記錄,比三層的黑洞更難發現。
- 改完逐對驗證:
ping -M do -s 8972 10.50.0.12(9000 − 28 = 8972),每一對需要通訊的主機都要通。
在管理系統裡怎麼落地
MTU 問題難查,往往是因為不知道一台伺服器到底經過了哪些裝置、在哪個網段。Toplink DCIM 的交換器管理把伺服器和交換器連接埠的對應關係登記在一起,在伺服器列表裡就能查到它的上聯交換器、連接埠號、所屬 VLAN 和連接埠速率,需要核對介面 MTU 或超長幀計數時,可以在瀏覽器裡開啟這台交換器的 SSH 終端執行 display、show 命令,會話全程錄影。儲存網、VXLAN 承載網這類有特殊 MTU 規劃的網段,可以在 IP 位址管理裡給位址段打上“儲存網 · MTU 9000”這樣的標籤,並登記所在 VLAN 和閘道器裝置,裝機的人查這個位址段時,就能看到它的 MTU 要求,不必再去翻網路規劃文件。
常見問題
把 MTU 改小能降低遊戲延遲嗎?
基本不能。在 1 Gbps 連接埠上發出一個 1500 位元組的滿長度幀只需約 12 微秒,100 Mbps 上約 0.12 毫秒;遊戲資料包本身通常只有幾十到幾百位元組,根本用不到 MTU 的上限。延遲主要由距離、路由和擁塞決定。
Wi-Fi 的 MTU 也是 1500 嗎?
通常是。Wi-Fi 幀本身能裝下比 1500 更多的資料,但無線網路要和乙太網橋接互通,系統裡無線網路卡的 MTU 一般也顯示為 1500。
MTU 和 MRU 有什麼區別?
MTU 管傳送,MRU(最大接收單元)管接收。PPP、PPPoE 鏈路在建立時由雙方協商 MRU,撥號裝置上看到的 1492 往往就是協商出來的;乙太網介面一般只配置 MTU。