前一篇《存儲大講堂:NAS存儲系統(tǒng)性能優(yōu)化攻略》發(fā)布后,一位讀者對smb和smb2的不同工作方式很感興趣。為了檢驗“叫外賣”(如果對這個詞感到困惑,請參考前一篇)的方式能提高多少效率,他在NAS和作為客戶端的Windows 7上都啟用了smb2,果然看到讀寫性能大幅度提升。
熟悉網(wǎng)絡(luò)的讀者可能會存疑:在局域網(wǎng)里的往返時間(RTT)很短,讀寫的總時間其實大多消費在服務(wù)器的響應(yīng)上。smb2的改進(jìn)看起來只節(jié)省了RTT,可能達(dá)到大幅度提升(比如數(shù)倍)的效果嗎?這個質(zhì)疑完全正確,但這位讀者的實驗結(jié)果也是真實的。怎么解釋這個矛盾呢?答案就在TCP協(xié)議上。本文將詳解TCP中影響NAS性能的各個因素,包括對以上矛盾的解釋。
在逐條分析之前,先讓我們復(fù)習(xí)一下TCP的重傳機(jī)制,因為后面會多次談及它。當(dāng)有TCP包在網(wǎng)絡(luò)上丟失時,TCP有兩種機(jī)制來實現(xiàn)重傳:超時重傳和快速重傳。下圖展示了這兩種情況:
圖1, 發(fā)送方只給接收方傳送了一個包。不幸的是這個包在網(wǎng)絡(luò)上丟失了,所以發(fā)送方遲遲等不到來自接收方的確認(rèn)。在經(jīng)過一段時間(RTO)之后,發(fā)送方認(rèn)為該包已經(jīng)丟失了,所以重新傳了一次。這個機(jī)制就是超時重傳。RTO能達(dá)到數(shù)百毫秒,這在計算機(jī)世界可以算“浪費很長時間”了,NAS對一個讀寫請求的響應(yīng)也就幾個毫秒。除此之外,超時重傳還會使TCP發(fā)送窗口降到最小,更是雪上加霜。如果網(wǎng)絡(luò)中有超過0.1%的超時重傳,我們就能看到明顯的性能問題。減少超時重傳對提高性能有明顯的改善。
圖2,發(fā)送方要給接收方傳送5個包,不幸的是第一個就丟失了。由于這個發(fā)送窗口>=5個MTU,所以發(fā)送方在沒有接收方確認(rèn)的情況下繼續(xù)發(fā)送了四個包。接收方在收到這些包的時候,可以通過包號知道第一個包丟失了。所以收到第n個時(n=2,3,4,5),接收方就發(fā)一個“收到n,但1還沒收到呢”給發(fā)送方(如下圖的紅線所示)。發(fā)送方在收到四個“但是1還沒收到呢”的消息后,意識到1可能已經(jīng)丟失了,就趕緊重傳一個。這個機(jī)制稱為快速重傳。由于這個過程沒有等待時間,所以對性能影響較小。實現(xiàn)超時重傳的條件是發(fā)送方在丟了一個包后,接下來還有4個或以上包可以傳。
明白了這兩個機(jī)制后,我們再逐條分析TCP對性能的影響因素:
1、TCP滑動窗口:如果要把10塊磚從A地搬到B地,你是一次搬一塊,總共搬10次,還是一口氣搬10塊呢?在力氣允許的條件下,自然是一口氣搬完速度快,因為節(jié)省了往返時間。網(wǎng)絡(luò)傳輸也是如此,如果有10個TCP包要傳,在帶寬允許的情況下應(yīng)該一起發(fā)送,而不是發(fā)一個就等確認(rèn),然后再發(fā)下一個。舉個例子,假如往返時間RTT是2毫秒,那10個包逐個傳至少要花20毫秒;一起傳就只需要2毫秒多一點,對性能的提高是顯而易見的。除此之外,在發(fā)生丟包的時候,大窗口可以提高快速重傳的概率,減少了超時重傳。比如10個包一起傳時,前6個包中任何一個丟失都可以由接下來的4個包觸發(fā)快速重傳。而每次傳4個包是永遠(yuǎn)等不到快速重傳的機(jī)會的。
2、多線程:在一個TCP session里,如果存在多個線程,也可以在丟包時提高快速重傳的概率。還記得《NAS性能優(yōu)化之一》里關(guān)于smb2的“叫外賣”圖片嗎?在第一個請求沒有完成的情況下,就可以發(fā)送第二個請求。如果第一個請求有丟包,那第二個請求的包可以幫忙湊滿四個,從而觸發(fā)快速重傳。本文開頭提到的讀者在測試smb2時得到大幅度的性能提升,很可能就得益于此。除了SMB2和NFS協(xié)議,EMC免費提供的EMCOPY工具也能在SMB中實現(xiàn)多線程拷貝。
3、超時重傳時間(RTO):這是一個動態(tài)值。RFC規(guī)定了計算該值的方法,但是結(jié)果比較大,已經(jīng)不適用當(dāng)今的網(wǎng)絡(luò)環(huán)境了。有些NAS(比如Celerra)提供一個設(shè)置,允許強(qiáng)制把該值改小。
4、Jumbo Frame:中文好像翻譯為巨幀。就是把MTU增大到9000,從而減少TCP頭和IP頭在一個網(wǎng)絡(luò)包中所占的比例。理論上這是能提高性能的,但是實際效果卻不一定。因為大包的丟失概率更大一點,而且包數(shù)少了,就更有可能發(fā)生超時重傳。
5、網(wǎng)絡(luò)擁塞:除了網(wǎng)絡(luò)配置出錯(比如兩端的speed/duplex不符合),另外一個導(dǎo)致丟包的因素就是網(wǎng)絡(luò)發(fā)生擁塞。如何避免呢?最有效最簡單的方法當(dāng)然是購買更高端的switch,但這也是最難被接受的建議。有一個將就的辦法,就是人為的把TCP滑動窗口強(qiáng)制在擁塞點以下。寧愿每次少傳一點,也不要丟包。有些NAS(比如Celerra)提供了強(qiáng)制最大滑動窗口的設(shè)置,但是要確定一個合適的擁塞點比較麻煩,需要抓大量的包分析。
寫到這里,突然想到可以寫幾篇如何利用Wireshark分析網(wǎng)絡(luò)包的。不過,這個讀者群應(yīng)該比NAS還小很多吧?
原文鏈接:http://stor.zol.com.cn/292/2928959.html