UDP有多不可靠?

最近我意识到了一件事:我实际上对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会成为我工具箱中的一员了。

1 4 收藏 1 评论

关于作者:honpey

(新浪微博:@Honpey) 个人主页 · 我的文章 · 1

相关文章

可能感兴趣的话题



直接登录
最新评论
跳到底部
返回顶部