offload
offload特性,主要是指將本來在操作系統協議棧中進行的一些數據包處理(如IP分片、TCP分片、重組、checksum校驗等)放到網卡硬件中去做,降低系統 CPU 消耗,提高處理的性能。
我們知道計算機網絡上傳輸的數據基本單位是離散的網包,既然是網包,就有大小限制,這個限制就是 MTU(Maximum Transmission Unit)的大小,一般是1518字節。比如我們想發送很多數據出去,經過os協議棧的時候,會自動幫你拆分成幾個不超過MTU的網包。然而,這個拆分是比較費計算資源的(比如很多時候還要計算分別的checksum),由 CPU 來做的話,往往會造成使用率過高。那怎么可以把這些簡單重復的操作 offload 到網卡上呢?
LSO/LRO
LSO/LRO,分別對應到發送和接收兩個方向,即 Large Segment Offload 和 Large Receive Offload。
首先看LSO,在發送數據超過 MTU 限制的時候(太容易發生了),OS 只需要提交一次傳輸請求給網卡,網卡會自動的把數據拿過來,然后進行切割,並封包發出,發出的網包不超過 MTU 限制。
接下來看 LRO,當網卡收到很多碎片包的時候,LRO 可以輔助自動組合成一段較大的數據,一次性提交給 OS處理。
一般的,LSO 和 LRO 主要面向 TCP 報文。
GSO/GRO
Generic Segmentation Offload 和 Generic Receive Offload,分別比 LSO 和 LRO 更通用,自動檢測網卡支持特性,支持分包則直接發給網卡,否則先分包后發給網卡。新的驅動一般用 GSO/GRO。
TSO/UFO
TCP Segmentation Offload 和 UDP fragmentation offload,分別對應 TCP 報文和 UDP 報文。
很典型的發送模式,TCP 協議中就考慮了分片存在的情況,往往是切分 TCP 的數據包,叫做 TSO。而一般的情況,則稱為 LSO 或者 GSO。
對於其他不支持切片的協議例如 UDP,則只能進行 IP 層上的切片。
TSO (tcp-segmentation-offload)
從名字來看很直觀,就是把tcp分段的過程轉移到網卡中進行。當網卡支持TSO機制時,可以直接把不超過滑動窗口大小的payload下傳給協議棧,即使數據長度大於MSS,也不會在TCP層進行分段,同樣也不會進行IP分片,而是直接傳送給網卡驅動,由網卡驅動進行tcp分段操作,並執行checksum計算和包頭、幀頭的生成工作。
UFO(udp-fragmentation-offload)
是一種專門針對udp協議的特性,主要機制就是將IP分片的過程轉移到網卡中進行,用戶層可以發送任意大小的udp數據包(udp數據包總長度最大不超過64k),而不需要協議棧進行任何分片操作。目前貌似沒找到有支持UFO機制的網卡,主要是應用在虛擬化設備上。
GSO(generic-segmentation-offload)
相對於TSO和UFO,GSO機制是針對所有協議設計的發送模式,更為通用。同時,與TSO、UFO不同的是,GSO主要依靠軟件的方式實現,對於網卡硬件沒有過多的要求。其基本思想就是把數據分片的操作盡可能的向底層推遲直到數據發送給網卡驅動之前,並先檢查網卡是否支持TSO或UFO機制,如果支持就直接把數據發送給網卡,否則的話再進行分片后發送給網卡,以此來保證最少次數的協議棧處理,提高數據傳輸和處理的效率。
接收模式除了LRO、GRO,多核服務器中的網卡還推薦考慮 RSS(Receive Side Scaling),將網流分配到多個 RSS 隊列上,多個隊列綁定到不同的核心上,分散負載。
RSS(Receive Side Scaling)
具備多個RSS隊列的網卡,可以將不同的網絡流分成不同的隊列,再將這些隊列分配到多個CPU核心上進行處理,從而將負荷分散,充分利用多核處理器的能力,提交數據接收的能力和效率。
可以通過 ethtool -k eth0 命令來查看各個選項的當前狀態;
通過 ethtool -K eth0 gso off/on 這樣的命令來開關。
# ethtool -k eth0 Features for eth0: rx-checksumming: on tx-checksumming: on tx-checksum-ipv4: on tx-checksum-ip-generic: off [fixed] tx-checksum-ipv6: on tx-checksum-fcoe-crc: off [fixed] tx-checksum-sctp: off [fixed] scatter-gather: on tx-scatter-gather: on tx-scatter-gather-fraglist: off [fixed] tcp-segmentation-offload: on tx-tcp-segmentation: on tx-tcp-ecn-segmentation: off [fixed] tx-tcp6-segmentation: on udp-fragmentation-offload: off [fixed] generic-segmentation-offload: on generic-receive-offload: on large-receive-offload: off [fixed] rx-vlan-offload: on tx-vlan-offload: on ntuple-filters: off [fixed] receive-hashing: on highdma: on [fixed] rx-vlan-filter: on [fixed] vlan-challenged: off [fixed] tx-lockless: off [fixed] netns-local: off [fixed] tx-gso-robust: off [fixed] tx-fcoe-segmentation: off [fixed] tx-gre-segmentation: off [fixed] tx-ipip-segmentation: off [fixed] tx-sit-segmentation: off [fixed] tx-udp_tnl-segmentation: off [fixed] tx-mpls-segmentation: off [fixed] fcoe-mtu: off [fixed] tx-nocache-copy: on loopback: off [fixed] rx-fcs: off [fixed] rx-all: off tx-vlan-stag-hw-insert: off [fixed] rx-vlan-stag-hw-parse: off [fixed] rx-vlan-stag-filter: off [fixed] l2-fwd-offload: off [fixed]
可以使用如下命令來關閉對應的參數:
/usr/sbin/ethtool -K eth1 lro off
/usr/sbin/ethtool -K eth1 tso off
VXLAN
在網絡虛擬化中,一個最常見的技術就是隧道,這是實現overlay的通用手段。而實現隧道無非就兩種思路,一種是把轉發信息放到包頭上,即封裝/解封裝(無論VXLAN還是STT都是這個思路);另外一種是由額外的數據庫管理,轉發時候進行查詢。
VXLAN 現在已經是常見的二層虛擬化實現技術,但是由於它需要對每個數據包都進行封裝、解封裝等操作,導致基於軟件的解決方案效率不高。而且如果我們采用封裝/解封裝的作法,那么可能原來網包並沒有超過MTU限制,加上封裝包頭就超了,這就需要進行切片了。 現在已經有網卡開始支持對 VXLAN 進行一些輔助操作,包括封裝、解封裝,以及 checksum 計算等。