牛客網Java刷題知識點之擁塞發生的主要緣由、TCP擁塞控制、TCP流量控制、TCP擁塞控制的四大過程(慢啓動、擁塞避免、快速重傳、快速恢復)

 

 

  很少說,直接上乾貨!html

 

 

福利 => 天天都推送 算法

歡迎你們,關注微信掃碼並加入個人4個微信公衆號:   大數據躺過的坑      Java從入門到架構師      人工智能躺過的坑         Java全棧大聯盟
 
     天天都有大量的學習視頻資料和精彩技術文章推送... 人生不易,惟有努力。
 
     百家號 :九月哥快訊               快手號:  jiuyuege
 
 
 
 
 
 
 

 

 

什麼是擁塞?緩存

  當大量的分組進入通訊子網,超出了網絡的處理能力時,就會引發網絡局部或總體性能降低,這種現象稱爲擁塞。擁塞經常使問題趨於惡化。微信

       另外一種對擁塞的解釋,即對資源的需求超過了可用的資源。若網絡中許多資源同時供應不足,網絡的性能就要明顯變壞,整個網絡的吞吐量隨之負荷的增大而降低。網絡

 

 

 

 

 

擁塞的發生與其不可避免   
   擁塞發生的主要緣由在於網絡可以提供的資源不足以知足用戶的需求,這些資源包括緩存空間、鏈路帶寬容量和中間節點的處理能力。因爲互聯網的設計機制致使其缺少「接納控制」能力,所以在網絡資源不足時不能限制用戶數量,而只能靠下降服務質量來繼續爲用戶服務,也就是「盡力而爲」的服務

  擁塞實際上是一個動態問題,咱們沒有辦法用一個靜態方案去解決,從這個意義上來講,擁塞是不可避免的架構

 

  靜態解決問題辦法1:
    例如:增長緩存空間到必定程度時,只會加劇擁塞,而不是減輕擁塞,這是由於當數據包通過長時間排隊完成轉發時,它們極可能早已超時,從而引發源端超時重發,而這些數據包還會繼續傳輸到下一路由器,從而浪費網絡資源,加劇網絡擁塞。事實上,緩存空間不足致使的丟包更多的是擁塞的「症狀」而非緣由。另外,增長鏈路帶寬及提升處理能力也不能解決擁塞問題。
  靜態解決問題辦法2:
    例如:咱們有四臺主機ABCD鏈接路由器R,全部鏈路帶寬都是1Gbps,若是A和B同時向C以1Gbps的速率發送數據,則路由器R的輸入速率爲2Gbps,而輸出速率只能爲1Gbps,從而產生擁塞。避免擁塞的方法只能是控制AB的速率,例如,都是0.5Gbps,可是,這只是一種狀況,假若D也向R發送數據,且速率爲1Gbps,那麼,咱們先前的修正又是不成立的。併發

 

 

 

 

擁塞控制和流量控制的差異
       所謂 擁塞控制就是防止過多的數據注入到網絡中,這樣可使網絡中的路由器或鏈路不致過載。擁塞控制所要作的都有一個前提,就是網絡能承受現有的網絡負荷。
        流量控制每每指的是點對點通訊量的控制,是個端到端的問題。流量控制所要作的就是控制發送端發送數據的速率,以便使接收端來得及接受。
 
 
 

 

 

TCP的擁塞控制   機器學習

  爲何須要擁塞控制?tcp

  答:因爲TCP採用了超時重傳機制,若是擁塞不加以控制,將致使大量的報文重傳,並再度引發大量的數據報丟棄,直到整個網絡癱瘓。這種現象稱爲擁塞崩潰。性能

  在網絡實際的傳輸過程當中,會出現擁塞的現象,網絡上充斥着很是多的數據包,可是卻不能按時被傳送,造成網絡擁塞,其實就是和平時的堵車一個性質了。TCP設計中也考慮到這一點,使用了一些算法來檢測網絡擁塞現象,若是擁塞產生,變會調整發送策略,減小數據包的發送來緩解網絡的壓力。

 

       擁塞控制:防止過多的數據注入到網絡中,這樣可使網絡中的路由器或鏈路不致過載。擁塞控制所要作的都有一個前提:網絡可以承受現有的網絡負荷。擁塞控制是一個全局性的過程,涉及到全部的主機、路由器,以及與下降網絡傳輸性能有關的全部因素。

 

 

 

 

 

TCP的流量控制   
  • 早期的TCP協議只有基於窗口的流控制(flow control)機制,咱們簡單介紹一下,並分析其不足。   在TCP中,爲了實現可靠性,發送方發出一個數據段以後要等待接受方相應的確認信息,而不是直接發送下一個分組。
  • 具體的技術是採用滑動窗口,以便通訊雙方可以充分利用帶寬。滑動窗口容許發送方在收到接收方的確認以前發送多個數據段。窗口大小決定了在收到目的地確認以前,一次能夠傳送的數據段的最大數目。窗口大小越大,主機一次能夠傳輸的數據段就越多。當主機傳輸窗口大小數目的數據段後,就必須等收到確認,才能夠再傳下面的數據段。例如,若視窗的大小爲 1,則傳完數據段後,都必須通過確認,才能夠再傳下一個數據段;當窗口大小等於3時,發送方能夠一次傳輸3個數據段,等待對方確認後,再傳輸下面三個數據段。  
  •  窗口的大小在通訊雙方鏈接期間是可變的,通訊雙方能夠經過協商動態地修改窗口大小。在TCP的每一個確認中,除了指出但願收到的下一個數據段的序列號以外,還包括一個窗口通告,通告中指出了接收方還能再收多少數據段(咱們能夠把通告當作接收緩衝區大小)。若是通告值增大,窗口大小也相應增大;通告值減少,窗口大小也相應減少。可是咱們能夠發現,接收端並無特別合適的方法來判斷當前網絡是否擁塞,由於它只是被動得接收,不像發送端,當發出一個數據段後,會等待對方得確認信息,若是超時,就能夠認爲網絡已經擁塞了。
  • 因此,改變窗口大小的惟一根據,就是接收端緩衝區的大小了。   
  • 流量控制做爲接受方管理髮送方發送數據的方式,用來防止接受方可用的數據緩存空間的溢出。
  • 流控制是一種局部控制機制,其參與者僅僅是發送方和接收方,它只考慮了接收端的接收能力,而沒有考慮到網絡的傳輸能力;
  • 而擁塞控制則注重於總體,其考慮的是整個網絡的傳輸能力,是一種全局控制機制。正由於流控制的這種侷限性,從而致使了擁塞崩潰現象的發生。  

 

 

 

 

 

 

TCP擁塞控制的四大過程(慢啓動、擁塞避免、快速重傳、快速恢復)

  TCP的擁塞控制由4個核心算法組成:「慢啓動」(Slow Start)、「擁塞避免」(Congestion voidance)、「快速重傳 」(Fast Retransmit)、「快速恢復」(Fast Recovery)。

   爲了方便起見,把發送端叫作client,接收端爲server,每一個segment長度爲512字節,阻塞窗口長度爲cwnd(簡化起見,下面以segment爲單位),sequence number爲seq_num,acknowledges number爲ack_num。一般狀況下,TCP每接收到兩個segment,發送一個ack。

 

 

 

 

  (1)慢啓動    
  早期開發的TCP應用在啓動一個鏈接時會向網絡中發送大量的數據包,這樣很容易致使路由器緩存空間耗盡,網絡發生擁塞,使得TCP鏈接的吞吐量急劇降低。因爲TCP源端一開始並不知道網絡資源當前的利用情況,所以新創建的TCP鏈接不能一開始就發送大量數據,而只能逐步增長每次發送的數據量,以免上述現象的發生,這裏有一個「學習」的過程。    假設client要發送5120字節到server,
  慢啓動過程以下:   
    一、初始狀態,cwnd=1,seq_num=1;client發送第一個segment。  
    二、server接收到512字節(一個segment),迴應ack_num=513。
    三、client接收ack(513),cwnd=1+1=2;如今能夠一次發送2個數據段而沒必要等待ack。   
    四、server接收到2個segment,迴應ack_num=513+512*2=1537  。 
    五、client接收ack(1537),cwnd=2+1;一次發送3個數據段   。
    六、server接收到3個segment,迴應2個ack,分別爲ack_num=1537+1024=2561和ack_num=2561+512=3073   。
    七、client接收ack(2561)和ack(3073),cwnd=3+2=5;一次能夠發送5個數據段,可是隻用4個就知足要求了   。
    八、server接收到4個segment,迴應2個ack,分別爲4097,5121   9.已經發送5120字節,任務完成!
   總結一下: 當創建新的TCP鏈接時,擁塞窗口(congestion window,cwnd)初始化爲一個數據包大小。源端按cwnd大小發送數據,每收到一個ACK確認,cwnd就增長一個數據包發送量。  

 

 

(1)慢啓動算法是一個在鏈接上發起數據流的方法。

(2)慢啓動過程:

         初始時將擁塞窗口的初始爲一個MSS,每次收到一個報文段的確認時發送方將擁塞窗口增大一個MSS,併發送兩個最大長度的報文段。兩個報文段被確認後,則發送方復每一個報文段的確認增長一個MSS,使得擁塞窗口變爲4個MSS,這樣每過一個RTT,發送速率就翻番。所以,在慢啓動階段以指數增加。

(3)慢啓動的結束:

          當出現一個由超時指示的丟包事件,TCP發送方將cwnd設置爲1,並從新開始慢啓動。

 

 

 

 

 

  (2) 擁塞避免  
    能夠想象,若是按上述慢啓動的邏輯繼續下去而不加任何控制的話,必然會發生擁塞,引入一個慢啓動閾值ssthresh的概念,當cwnd<ssthresh的時候,tcp處於慢啓動狀態,不然,進入擁塞避免階段。一般,ssthresh初始化爲 64 Kbytes。    當cwnd = 64947 + 512 = 65459,進入擁塞避免階段,假設此時seq_num = _101024:   
  一、client一次發送cwnd,可是先考慮頭兩個segment  。
     二、server迴應ack_num = 102048   。
  三、client接收到ack(102048),cwnd = 65459 + [(512 * 512) /65459] = 65459 + 4 = 65463,也就是說,每接到一個ack,cwnd只增長4個字節。   
  四、client發送一個segment,並開啓ack timer,等待server對這個segment的ack,若是超時,則認爲網絡已經處於擁塞狀態,則重設慢啓動閥值ssthresh=當前cwnd/2=65463/2=32731,而且,馬上把cwnd設爲1,很極端的處理!
   5.此時,cwnd<ssthresh,因此,恢復到慢啓動狀態。
   總結一下:若是當前cwnd達到慢啓動閥值,則試探性的發送一個segment,若是server超時未響應,TCP認爲網絡能力降低,必須下降慢啓動閥值,同時,爲了不形勢惡化,乾脆採起極端措施,把發送窗口降爲1,我的感受應該有更好的方法。
 
 
 

(1)擁塞避免算法是一種處理丟失分組的方法。(當到達中間路由器的極限時,分組將被丟棄。)

(2)擁塞避免過程:

         進入擁塞避免時,擁塞窗口的值大約是上次遇到擁塞時值的一半,每一個RTT只將擁塞窗口的值增長1個MSS.

(3)結束條件:超時或丟包。

 

 

 

 

 

  (3)(4)快速重傳和快速恢復    
  前面講過標準的重傳,client會等待RTO時間再重傳,但有時候,沒必要等這麼久也能夠判斷須要重傳,
快速重傳
  例如:client一次發送8個segment,seq_num起始值爲100000,可是因爲網絡緣由,100512丟失,其餘的正常,則server會響應4個ack(100512)(爲何呢,tcp會把接收到的其餘segment緩存起來,ack_num必須是連續的),這時候,client接收到四個重複的ack,它徹底有理由判斷100512丟失,進而重傳,而沒必要傻等RTO時間了。   
  快速恢復
  咱們一般認爲client接收到3個重複的ack後,就會開始快速重傳,可是,若是還有更多的重複ack呢,如何處理?這就是快速恢復要作的,事實上,咱們能夠把快速恢復看做是快速重傳的後續處理,它不是一種單獨存在的形態。   
 
如下是具體的流程:  
  假設此時cwnd=70000,client發送4096字節到server,也就是8個segment,起始seq_num = _100000:   
  一、client發送seq_num = _100000   。
  二、seq_num =100512的segment丟失  。 
  三、client發送seq_num = _101024   。
  四、server接收到兩個segment,它意識到100512丟失,先把收到的這兩個segment緩存起來  。 
  五、server迴應一個ack(100512),表示它還期待這個segment  。
  六、client發送seq_num = _101536   。
  七、server接收到一個segment,它判斷不是100512,依舊把收到的這個segment緩存起來,並回應ack(100512)  。
  八、如下同六、7,直到client收到3個ack(100512),進入快速重發階段。   
  九、重設慢啓動閥值ssthresh=當前cwnd/2=70000/2=35000   。
  十、client發送seq_num = 100512     如下,進入快速恢復階段。   
  十一、重設cwnd = ssthresh + 3 segments =35000 + 3*512 = 36536,之因此要加3,是由於咱們已經接收到3個ack(100512)了,
              根據前面說的,每接收到一個ack,cwnd加1   。
  十二、client接收到第四個、第五個ack(100512),cwnd=36536+2*512=37560  。
    1三、server接收到100512,響應ack_num = _104096   14.此時,cwnd>ssthresh,進入擁塞避免階段。

 

 

(1)執行條件及過程

     當收到3個或3個以上的重複ACK時,就很是有多是一個報文段丟失了。因而咱們就重傳丟失的數據報文段,而不等待超時定時器溢出。這就是快速重傳。接下來執行的不是慢啓動,而是擁塞避免,這就是快速恢復。

(2)緣由:

    沒有執行慢啓動的緣由是因爲收到的重複的ACK不只僅告訴咱們一個分組丟失了。因爲接收方只有在收到另外一個報文段時纔會產生重複的ACK,而該報文段已經離開網絡並進入了接收方的緩存。也就是說在收發兩端之間仍然有流動的數據,而咱們不想執行慢啓動來忽然減小數據流。

 

 

 

 

 

 

  真實例子

  想一想看,能不能把TCP解決擁塞的方法應用到交通擁塞呢?   咱們有兩個原則:一是擁塞不可避免,單純增長資源並不能避免擁塞的發生,只能用動態的方法加以解決;二是數據包守恆原則。政府花費很大資金修路,並不能避免堵車,只能從源頭控制,例如首先限制車輛進入主路,根據實際狀況,再慢慢增長每個路口的車流量,可是,當達到一個閥值,增長速度要放緩,並不時探測整個主路的擁堵狀況,若是狀況危急,馬上封閉半個路口,並將車流量降到最低,也就是從新回覆到慢啓動狀態。   呵呵,有趣!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

歡迎你們,加入個人4個微信公衆號:    大數據躺過的坑     Java從入門到架構師    人工智能躺過的坑     Java全棧大聯盟    
 
 
 

同時,你們能夠關注個人我的博客

   http://www.cnblogs.com/zlslch/   和     http://www.cnblogs.com/lchzls/      http://www.cnblogs.com/sunnyDream/   

   詳情請見:http://www.cnblogs.com/zlslch/p/7473861.html

 

  人生苦短,我願分享。本公衆號將秉持活到老學到老學習無休止的交流分享開源精神,匯聚於互聯網和我的學習工做的精華乾貨知識,一切來於互聯網,反饋回互聯網。
  目前研究領域:大數據、機器學習、深度學習、人工智能、數據挖掘、數據分析。 語言涉及:Java、Scala、Python、Shell、Linux等 。同時還涉及日常所使用的手機、電腦和互聯網上的使用技巧、問題和實用軟件。 只要你一直關注和呆在羣裏,天天必須有收穫

 

      對應本平臺的討論和答疑QQ羣:大數據和人工智能躺過的坑(總羣)(161156071) 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

     打開百度App,掃碼,精彩文章天天更新!歡迎關注個人百家號: 九月哥快訊

 

 

 

 

 

 

 

 

 

相關文章
相關標籤/搜索