什麼是慢啓動
最初的TCP的實現方式是,在連接建立成功後便會向網絡中發送大尺寸的數據包,假如網絡出現問題,很多這樣的大包會積攢在路由器上,很容易導致網絡中路由器緩存空間耗盡,從而發生擁塞。因此現在的TCP協議規定了,新建立的連接不能夠一開始就發送大尺寸的數據包,而只能從一個小尺寸的包開始發送,在發送和數據被對方確認的過程中去計算對方的接收速度,來逐步增加每次發送的數據量(最後到達一個穩定的值,進入高速傳輸階段。相應的,慢啓動過程中,TCP通道處在低速傳輸階段),以避免上述現象的發生。這個策略就是慢啓動。
慢啓動導致客戶端與服務器之間經過幾百毫秒才能達到接近最大速度的問題,對於大型流式下載服務的影響倒不顯著,因爲慢啓動的時間可以分攤到整個傳輸週期內消化掉。可是,對於很多HTTP連接,特別是一些短暫、突發的連接而言,常常會出現還沒有達到最大窗口請求就被終止的情況。換句話說,很多Web應用的性能經常受到服務器與客戶端之間往返時間的制約。因爲慢啓動限制了可用的吞吐量,而這對於小文件傳輸非常不利。慢啓動重啓除了調節新連接的傳輸速度,TCP還實現了SSR(Slow-StartRestart,慢啓動重啓)機制。
這種機制會在連接空閒一定時間後重置連接的擁塞窗口。道理很簡單,在連接空閒的同時,網絡狀況也可能發生了變化,爲了避免擁塞,理應將擁塞窗口重置回“安全的”默認值。毫無疑問,SSR對於那些會出現突發空閒的長週期TCP連接(比如HTTP的keep-alive連接)有很大的影響。因此,我們建議在服務器上禁用SSR。在Linux平臺,可以通過如下命令來檢查和禁用SSR:
$>sysctlnet.ipv4.tcp_slow_start_after_idle
$>sysctl-wnet.ipv4.tcp_slow_start_after_idle=0
爲演示三次握手和慢啓動對簡單HTTP傳輸的影響,我們假設紐約的客戶端需要通過TCP連接向倫敦的服務器請求一個20KB的文件,下面列出了連接的參數。
•往返時間:56ms。
•客戶端到服務器的帶寬:5Mbit/s。
•客戶端和服務器接收窗口:65535字節。
•初始的擁塞窗口:4段(4×1460字節≈5.7KB)。
•服務器生成響應的處理時間:40ms。
•沒有分組丟失、每個分組都要確認、GET請求只佔1段。
•0ms:客戶端發送SYN分組開始TCP握手。
•28ms:服務器響應SYN-ACK並指定其rwnd大小。
•56ms:客戶端確認SYN-ACK,指定其rwnd大小,並立即發送HTTPGET請求。
•84ms:服務器收到HTTP請求。
•124ms:服務器生成20KB的響應,併發送4個TCP段(初始cwnd大小爲4),然後等待ACK。
•152ms:客戶端收到4個段,並分別發送ACK確認。
•180ms:服務器針對每個ACK遞增cwnd,然後發送8個TCP段。
•208ms:客戶端接收8個段,並分別發送ACK確認。
•236ms:服務器針對每個ACK遞增cwnd,然後發送剩餘的TCP段。
•264ms:客戶端收到剩餘的TCP段,並分別發送ACK確認。
大家可以練習一下,如果將cwnd值設置爲10個TCP段,那麼圖2-5所示的過程將減少一次往返,性能可以提升22%!通過新TCP連接在往返時間爲56ms的客戶端與服務器間傳輸一個20KB的文件需要264ms!作爲對比,現在假設客戶端可以重用同一個TCP連接(圖2-6),再發送一次相同的請求。
•0ms:客戶端發送HTTP請求。
•28ms:服務器收到HTTP請求。
•68ms:服務器生成20KB響應,但cwnd已經大於發送文件所需的15段了,因此一次性發送所有數據段。
•96ms:客戶端收到所有15個段,分別發送ACK確認。
同一個連接、同樣的請求,但沒有三次握手和慢啓動,只花了96ms,性能提升幅度達275%!
以上兩種情況下,服務器和客戶端之間的5Mbit/s帶寬並不影響TCP連接的啓動階段。此時,延遲和擁塞窗口大小纔是限制因素。事實上,如果增大往返時間,第一次和第二次請求的性能差距只會加大。大家可以練習一下,試試不同的往返時間會有什麼結果。理解了TCP擁塞控制機制後,針對keep-alive、流水線和多路複用的優化就簡單得多了。
增大TCP的初始擁塞窗口。把服務器的初始cwnd值增大到RFC6928新規定的10段(IW10),是提升用戶體驗以及所有TCP應用性能的最簡單方式。好消息是,很多操作系統已經更新了內核,採用了增大後的值。可以留意相應的文檔和發佈說明。在Linux上,IW10是2.6.39以上版本內核的新默認值。但不要就此滿足,升級到3.2以上版本還有其他重要更新。
典型案例:
問題描述:
hbase主備集羣之間增量同步,主集羣在上海,備集羣在張北,服務器均爲萬兆網卡,且帶寬沒有達到上限;長途帶寬爲專線,帶寬足夠,不會成爲瓶頸。跨長途帶寬複製數據,由於數據量較大,總是有延遲。
解決方法:
將內核參數sysctl-wnet.ipv4.tcp_slow_start_after_idle從1調整到0解決。