有些交換器的延遲跟封包大小幾乎無關,有些會隨封包變長而線性增加。同樣是二層轉發,為什麼會差這麼多?
答案在 frame 的結構裡,只跟兩個欄位有關。
交換器要決定往哪送,需要的是目的 MAC,它在 frame 的前 6 bytes,收到就夠查表。要判斷 frame 有沒有壞,需要的是 FCS,它在最後 4 bytes,得把整個 frame 收完才可以。
一個在最前面,一個在最後面。你選哪個先做,就決定了這台設備的延遲曲線長什麼樣。
| 讀到哪裡就開始轉發 | 延遲跟 frame 長度的關係 | |
|---|---|---|
| cut-through | 前 6 bytes(目的 MAC) | 幾乎無關 |
| store-and-forward | 整個 frame(要驗 FCS) | 線性增加 |
它至少要等整個 frame 收完才開始送,處理時間不會因為封包變長而變,所以 64 bytes 跟 1518 bytes 一相減,剩下的就是序列化的差。用 Day 9 表格「純 frame 」那一欄:64 bytes 是 51.2 ns,1518 bytes 是 1214.4 ns,光因為封包變長就多了 1163 ns。線速越慢,這個差距就越大,1G 是 8 ns/byte,同樣從 64 到 1518 就差 11632 ns。
這是這篇最有用的地方:它給了一個可以被推翻的預測。 之後我會在同一台 7150 上把轉發模式切成 store-and-forward,用一樣的兩個 port、一樣的線、一樣的 10G 線速,再跑一次同樣的 frame size 掃描。
預測是這樣:cut-through 那條曲線從 64 到 1518 幾乎不爬,store-and-forward 那條應該多爬 1163 ns,兩條線的斜率差落在 0.8 ns/byte。爬的量要是差太多,要改的是這個模型,不是設備。
斜率才是要看的東西。 接近平的是 cut-through,貼著該線速 ns/byte 的是 store-and-forward。一台 1G 的 cut-through 同樣畫出接近平的線,只是整條線位置比較高。拿絕對值去證明「哪一台慢十倍」,那是把線速的帳算到轉發模式頭上。
它在還沒驗 FCS 的時候就把封包送出去了,所以壞封包會被完整轉發到下游才被丟掉。錯誤沒有被擋在發生的那一跳,它會往下擴散。 資料本身不會壞掉,但壞封包佔用了整條路徑上每一段的頻寬跟佇列。一條線材接觸不良,沿路每台交換器的 CRC 計數器都可能跟著跳,真正壞的那條線可能在好幾跳之前。
中間還有兩種折衷:fragment-free 收滿 64 bytes 再轉,adaptive 在錯誤率變高時切回 store-and-forward。這台兩種都沒有,只支援 cut-through 跟 store-and-forward 兩種模式。預設是 cut-through,Day 7 掃出來那條平的線也證明它現在就跑在這個模式。
先講一個容易誤判的狀況。看到延遲隨封包變長而增加,第一反應通常是「這台設備不夠快」,實際上那是它在等整個 frame 收完好驗 FCS。
真正該收緊的不是延遲的門檻,是 CRC 的告警門檻。一般環境可以容忍 CRC(FCS 驗不過的那些)慢慢累積再處理。cut-through 下不行:在你決定要不要處理之前,那些壞封包已經跑過整條路徑了。
所以我的做法是 CRC 從零變非零就告警,不設累積量。
CRC 從 0 變非零 -> 立刻告警,查那一段的線材與光模組
健康的環境裡它本來就是零。設累積門檻等於允許它慢慢壞,而在 cut-through 下,慢慢壞的東西會一路擴散出去。
至於「手上這台到底是哪一種」,Day 7 已經給過量法,64 和 1518 兩個長度各量一次,看兩個的差是接近 0 還是一千多。這比翻 datasheet 可靠,因為那個差是自己量得出來的。
各種錯誤計數器分別代表什麼故障,那是後面的題目。明天講封包進了主機之後的事:從網卡到應用程式,時間花在哪幾層。