tshark 抓包性能 CentOS 6 v CentOS 7
我正在嘗試使用 tshark 連續擷取大約 20mbit/sec 的流量。如果我在 CentOS 6.5 上使用 tshark 擷取數據包,我會丟棄大約 4% 到 66% 的數據包。如果我在 CentOS 7 上做同樣的事情,它永遠不會報告任何丟棄的數據包。我實際上試圖通過做一些瘋狂的事情來讓它丟棄數據包,比如向 xml 輸出大量流量。據我所知,它沒有丟包。我的問題是,CentOS 7 是否有某種功能使丟包變得不可能?還是它丟包而不告訴我?
例如,我執行如下命令:
tshark -i ens224 -c 100000 -w /tmp/delme.pcap tshark -i ens224 -c 100000 -T pdml > /tmp/delme.pcap
對於第一個命令 CentOS 6 報告 4% 丟包,CentOS 7 報告 none。對於第二個命令,CentOS 報告 66% 的封包遺失,但 CentOS 7 沒有報告。
請注意,兩台機器都執行從原始碼編譯的 tshark 1.12.7。
我的問題是,CentOS 7 是否有某種功能使丟包變得不可能?
不,但它有兩個功能可以大大降低丟包的可能性:
- 包含套接字
TPACKET_V3
的核心版本;PF_PACKET
- 用於 套接字
TPACKET_V3
的libpcap 版本。PF_PACKET
Libpcap 使用
PF_PACKET
套接字在 Linux 2.2 及更高版本上進行擷取(Linux 1.x 和 2.0 沒有PF_PACKET
套接字)。原始PF_PACKET
套接字使用正常套接字機制傳遞數據包,這意味著 libpcap(或任何其他擷取流量的程序)必須recvmsg()
為每個數據包在該套接字上進行一次呼叫。例如,這比 BSD 和 OS X 上的 BPF 機制的工作方式更昂貴,在每次讀取時都會傳遞多個*數據包,因此,在高流量的情況下,進行的系統呼叫更少。我認為,Linux 2.4 引入了“turbopacket”機制(這就是“TPACKET”中的“T”代表 - “turbo”),它提供了一個由核心和使用者空間共享的記憶體映射緩衝區。這樣,在傳遞數據包時需要更少的副本,並且使用者空間中的數據包讀取循環可以在每次喚醒時處理多個數據包(為了等待數據包到達,使用者空間會進行
select()
、poll()
或epoll()
呼叫)。不幸的是,該機制提供了一個固定大小的緩衝區環,並且 libpcap 必須為最大可能的數據包選擇足夠大的大小。早期版本選擇的數據包大小與提供的快照長度相同,即您使用的 Wireshark 版本可能為 64K-1,這相當浪費 - 緩衝區最終沒有足夠的插槽用於數據包以避免溢出。一些後來的版本試圖使用 MTU 來確定插槽大小,但它不能總是這樣做,即使可以這樣做也可能是浪費。在某些 3.x 版本(3.6?)中
TPACKET_V3
,添加了一個明顯不同的 turbopacket 機制。它更像 BPF,因為緩衝區不保存一個數據包,它可以包含多個數據包。這可以更好地利用記憶體進行擷取,並且丟棄的數據包更少。