UDP有多不可靠?

honpey發表於2014-11-19

最近我意識到了一件事:我實際上對UDP一無所知。好吧,我知道它是無連線的,沒有三次握手過程,所以它對傳輸的質量不作任何保證。但是,在實際工程應用時,UDP的這些特徵意味什麼呢?

我啟用了5個VPS(虛擬專用伺服器,譯者注),在7個小時相互傳送UDP包,不過網路負載並不大(不過可以嘗試下加大負載的情況)。每臺伺服器,每9-11秒就會隨機地接收一個包並且傳送5-10個包,包的大小從16到1016位元組不等。

其中兩個伺服器位於新澤西州(NJ)的同一個資料中心,其餘三臺分別位於洛杉磯(LA)、阿姆斯特丹(NLD)和東京(JPN)。

可靠性分析

我想知道的第一件事是UDP到底有多不可靠。看到下表,我很好奇,我們是在討論25%,50%,75%的傳送率嗎?

包的接收數目

 

接收方

 

NJ 1

NJ 2

LA

NLD

JPN

NJ 1

2981/2981 2888/2889 2964/2964 3053/3054

NJ 2

3016/3016 3100/3101 2734/2735 3054/3054

LA

2901/2941 2932/2975 2938/2942 2712/2712

NLD

3038/3038 2771/2772 2724/2724 2791/2791

JPN

2551/2552 2886/2886 2836/2838 2887/2887

包的接收率

 

接收方

 

NJ 1

NJ 2

LA

NLD

JPN

NJ 1

100 99.97 100 99.97

NJ 2

100 99.97 99.97 100

LA

98.64 98.55 99.86 100

NLD

100 99.97 100 100

JPN

99.96 100 100 100

這些資料遠超過我的預期。我原以為從NLD—JPN一線會有明顯超出均值的丟包,但是事實並不是這樣的。反而是從LA發出、傳送到NJ的資料有些異常。原因何在?

首先,我將原因鎖定在包的大小。我會使包儘量小(16位元組的頭,0-1000位元組的有效資料):

每種大小的包的丟失個數

0-115 116-215 216-315 316-515 516-715
13 11 12 13 23

沒有什麼異常。那麼,這些包丟失的時間如何分佈呢?

不幸的是,我沒有儲存時間戳啊(Why?!),但是我統計了每一對伺服器間丟包時間分佈。從LA到NJ2的丟失的所有的43個包中,其中29個包在第1-2分鐘內丟失。NJ1的包也大部分在剛開始很短的時間內丟失。

 

排隊

我關注的另一個點是排隊。

為了探討這個問題,我們首先要討論下陣列的逆序數。逆序數就是陣列中位置順序與大小順序相反的一對數。假設現有一個陣列10,8,3,7,4,那麼你必須要調換8次才能達到正確的順序,這8次分別是:((10,8),(10,3),(10,7),(10,4),(8,3),(8,7),(8,4),(7,4))。

逆序數

 

NJ 1

NJ 2

LA

NLD

JPN

NJ 1

0 2994 2581 4658

NJ 2

0 3147 2459 4645

LA

3980 3861 3237 4010

NLD

3125 1826 3133 4189

JPN

3920 4417 4147 4425

不知道你覺得怎樣,我不確定這組資料是否有價值。這確實看上去很高,當然,使用UDP的一個很重要的原因是你可以丟棄掉某些包。如果你傳送了10000個包,最後一個包先來,之前的9999個包之後才依次到來,那麼你就不需要做9999次調換了,直接把那第1個包丟掉即可。

如果我們把比已經處理過的包的號碼小的包丟棄會怎樣?比如,現在有5個包來了,1,5,4,3,6,7,由於我們已經處理過了5,所以把3和4給丟棄了。那麼還剩下幾個“good”的包呢?

正常順序的包的數目

 

NJ 1

NJ 2

LA

NLD

JPN

NJ 1

100 52.40 55.94 36.77

NJ 2

100 52.47 54.22 38.02

LA

41.72 42.32 50.48 39.34

NLD

46.32 59.34 44.79 39.27

JPN

980 1083 1141 1087

正常順序的包的比率

 

NJ 1

NJ 2

LA

NLD

JPN

NJ 1

100 52.40 55.94 36.77

NJ 2

100 52.47 54.22 38.02

LA

41.72 42.32 50.48 39.34

NLD

46.32 59.34 44.79 39.27

JPN

38.40 37.53 40.20 37.65

做一個小小的調整,如果我們將5個包整合到一起,再次使用上面的丟棄演算法:

正常順序的包的數目(包整合之後):

 

NJ 1

NJ 2

LA

NLD

JPN

NJ 1

2981 2061 2235 1807

NJ 2

3016 2214 2041 1889

LA

1868 1873 2066 1720

NLD

2200 2273 1920 1712

JPN

60.38 62.51 61.13 59.99

正常順序的包的比率(包整合之後):

 

NJ 1

NJ 2

LA

NLD

JPN

NJ 1

100 71.34 75.40 59.17

NJ 2

100 71.40 74.63 61.85

LA

63.52 62.96 70.22 63.42

NLD

72.42 82.00 70.48 61.34

JPN

1541 1804 1735 1732

 

結論:

沒有長時間的、大量的資料做支撐,很難得到任何結論。然而,上面的資料表明UDP的可靠性還是相當不錯的。但是距離越遠,遇到的跳變就越多,這也意味著發生不可預知錯誤的概率就越大,但是如果一切都還OK,距離也不成問題了。

排隊機制是個問題。通過整合包,我們發現效能有了很大的提升。在許多場合,排隊都不會產生質的影響,除非你在瘋狂發包,否則通過一個簡單的時間戳和接收端的重排機制,UDP的效能依舊可觀。

我會做更多的測試、更長的時間、更多的資料、更多的地點。同時,我還會把UDP和TCP的相關效能做個對比。但是無論如何,我認為,可靠性超出我預期的UDP會成為我工具箱中的一員了。

相關文章