📄 rfc2887.txt
字号:
? 分层方式
数据被分发到多个多播组中,接收端通过加入适当的多播组来接收它们所需要的数
据。在某些情况下,这要求路由器能够支持快速加入和离开一个多播组,并且支持
更多的转发状态。
? 基于服务器的方式
用一些额外的节点来协助实现数据发送和反馈信息的联合。这些额外的节点可能并
不是一般意义上的发送端或者接收端,它们在反馈树中的作用只是协助实现可靠多
播协议。它们并不需要接收多播数据。
? 基于路由器的方式
在基于路由器的方式中,从发送端到接收端的数据流路径上的路由器可以协助实现
数据的发送和反馈信息的联合与抑制。因为路由器可以直接改变多播的路由,因此
这种方式比起基于服务器的方式对于数据流量以及哪些流量发给哪些组成员可以有
更灵活的控制。然而,一般说来路由器并没有太多剩余的存储量和运算量,这就限
制了能够加入多少额外的功能。并且,路由器的代码比应用程序的代码更难维护,
因此基于路由器的方式应当尽可能具有普适性,它们一旦投入使用就很难再去改变。
4. 实现高吞吐的机制
作为一个可靠多播协议,有两个问题是必须解决的,一个是拥塞控制,另一个是高吞吐
率。丢包是跟这两个问题都有关的一个核心问题。在多数网络中拥塞的主要征兆就是丢包。
而实现高吞吐率的主要障碍也是丢包。因此度量丢包率和抑制丢包就成为解决这两个问题的
关键所在。针对这些问题的可靠多播解决方案大致可以分为以下几类:
? 数据包确认
? 丢失数据包的反向确认
? 加入冗余,使接收端能够恢复丢包
这些方法还可以再进行细分,这样我们就可以检查每一种技术能够应用在何种限制条件
下。在这一节中,我们重点探讨使用这些机制来实现高吞吐率,而在下一节中我们将重点研
究使用这些机制来实现拥塞控制。
4.1. 基于ACK的机制
在最简单的基于ACK的机制中,每个接收端对于收到的每个数据包都要发一个ACK包给
发送端,对于每个丢失的数据包发一个重传包给发送端。这样一种机制只能应用于小规模的
多播,否则就会在发送端引发ACK确认爆炸。由于这个原因,这种机制对于大多数应用来说
是不可行的。
将多个ACK放入一个单独的数据包[RMWT98]可以缓解确认爆炸的问题,多播组的规模可
以更大一些。然而很快会走到另一个极端,从接收端到发送端的反馈信息频率过低,从而基
于发送端的拥塞控制机制不能够可靠工作。
将接收端排成一个环[WKM94],通过在环上传送一个“ACK令牌”就可以杜绝确认爆炸问
题的出现。然而环本身的生成和维护很成问题。而且如果环的生成过程中不考虑网络的实际
拓扑(了解网络拓扑在实际中是一个很难的问题),那么每个数据包引发的ACK包通过网络
干线的次数将随着接收端的数量以O(n)增长。
4.1.1. 基于树的ACK机制
将接收端排成树形结构[MWB+98, KCW98],每个接收端将ACK确认发给它的父节点,父
节点再将这些ACK确认联合起来一起发给更上层的父节点。这样一种机制比起环形结构更稳
健也更容易配置。这样一个树形结构只是用于ACK的联合,数据包的多播仍然按照正常方式
进行。树形结构比环形结构更易于构造,因为有更多的局部信息可以利用。而且树形结构的
容错能力也更强,假如有某个节点出故障,受到影响的只是它的所有后代节点。这些后代节
点在发现父节点出现故障之后还可以直接越过父节点,直接向更高一层的节点报告。用这样
一个优秀的ACK树形结构,基于树的ACK机制将有可能成为扩展性最好的一种可靠多播解决
方案。
为了更易于配置,基于树的协议必须是自组织的,也就是说那些接收端必须利用局部信
息以一种可扩展的方式自己生成树形结构的拓扑。这种方式是完全可行的,但却并不容易。
对于基于数的协议来说,限制扩展规模的主要因素是树的生成和维护机制,而不是ACK确认。
如果没有这样一个可扩展的自动生成树形拓扑的机制,协议在实现的时候就必须依靠手工来
配置,这就大大降低了它的可用性和可扩展性。
与树的生成有关的另外一个问题是子树的重传问题。通过适当的路由机制,或者使用多
个多播组,可以由中间节点来把下层节点丢失的数据包重新发给它们,而不是由发送端来重
传这些数据。这依赖于ACK树拓扑和实际数据树的拓扑的中间节点有很好的相关性,并且需
要有相关的机制来限制从发送端到子树的重传。一个好的树拓扑自动生成机制与分区管理的
多播组结合起来可能提供这样一个解决方案。如果没有这样的一个树自动生成机制,就很难
在Internet上的一个很大的多播组中使用子树重传技术。这也可以通过使用传输层路由器
的支持来帮助执行重传,尽管当前的路由器机制[FLST98]支持基于NACK的协议,而不支持
基于ACK的协议。
另外一个重要的问题是ACK树中间节点所做的联合操作的本质是什么。这些节点能够:
1. 如果所有子节点都发送ACK,就把它们联合起来,发送一个单独的ACK
2. 通过发送有ACK的子节点的列表,来进行ACK的联合操作
3. 发送一个联合的ACK,外加一个NACK子节点列表
对于数据包来说,第1种方法显然扩展性更好。然而,如果发送端需要确切知道哪些接
收端收到了数据,第2,3种方法就提供了这些信息。幸运的是,一般说来并不需要对每个
包做这样的操作,而只需要对每个ADU提供这样的信息就可以了。在数据包层用第1种方法,
而在ADU层用第3种方法,这是对于需要这种信息的应用的扩展性最好的解决方案,与其它
数据包层的解决方案相比实际上并没有带来多少开销。
4.2. 基于NACK的机制
接收端可以不需要为每个收到的数据包都发送一个ACK,而是对每个检测到已经丢失的
数据包发送一个反向确认(NACK)。这样一种机制相对于基于ACK的机制有以下的优点:
? 发送端不需要知道接收端的确切数目,这样就可以将建立拓扑阶段从环状或树状的
基于ACK的算法中去掉。
? 由接收端来负责可靠性,容错措施就可以相对简单一些。
? 发送端的状态可以大量减少,因为发送端不需要去跟踪接收端的状态。
? 不管多少个接收端丢失了某个数据包,都只需要发送一个NACK给发送端就可以了。
所以NACK抑制是完全可行的。
不足之处在于发送端很难知道它何时可以释放发送缓冲区,并且需要有一些额外的会话
层机制来通知发送端某个接收端已经收到了全部数据。对于大多数应用来说,这些问题都并
不重要。
4.2.1. NACK抑制
基于NACK的协议之间的一个最大差别就在于NACK抑制是如何做的。NACK抑制的目标是
当第一次发现某个包丢失之后,立刻发送一个并且只有一个NACK到发送端,然后丢失数据
的唯一一份拷贝重新发送出来,并且被那些需要这个包的接收端接收下来。
不同的协议用不同的方法来满足或接近满足这些目标。
? SRM[FJM95]中用发送端到丢失数据的节点之间的闭环传输时间(Round trip time,
RTT)来对随机定时器进行加权。这种方法很有效,但是在NACK抑制开始之前需要
计算每个节点的RTT。
? NTE[HC97]使用一个基于随机密钥和滑动窗口的发送端触发机制。这种方法不需要
随机定时器,可以用于大型的会话,但是在进行拥塞控制的时候,很难提供一个稳
定的底层反馈流。
? AAP[Ha99]用指数分布的随机定时器,不需要计算RTT,因此对于大型会话也很有效。
? PGM[FLST98]和LMS[PPV98]中在路由器中加入额外的算法来抑制重复的NACK。在
PGM中,路由器可以与SRM中的随机定时器协同工作,并且使抑制局部化,从而不
需要对整个多播组进行整体的NACK抑制。
这些方法中最一般的可能是指数分布的随机定时器。尽管使用SRM中的定时器可以减少
反馈延时,但是在RTT未知或接收端总数未知的情况下,它很难得到实际的应用。相比之下,
指数分布的随机定时器对于一个大型的会话,不管其延时特性是好是坏,都可以很好地工作。
只要有可能,任何一种形式的基于随机定时器的方法都可以与路由器的支持结合起来。
发送端触发机制[HC97]就很难与路由器的相关支持结合起来。
4.3. 复制
有些可靠多播协议设计时多数情况下并不需要有显式的可靠机制。比如说,在一个用多
播实现的多人网络游戏中,将一个运动物体的位置不停地用多播发出去。这种位置流信息并
不需要额外的可靠保证,因为在重传一个旧的位置之前,新的位置已经取代了旧的位置。然
而,当运动物体与其它物体相交互或者停止移动的时候,就需要保证交互信息或者最终的位
置信息的传送是完全可靠的。
并不只是游戏需要考虑这类问题。NTE共享文本编辑器[HC97]使用同样的机制来处理一
行文字的变化。对于每次更改,都重新发送整个行,那么这种情况下不需要有额外的可靠保
证。复制的主要优势在于它不易收到空间上不相关的丢包的影响。对于传统的基于ACK或
NACK的协议,任何一个包被一个很大的接收端集合中的所有接收端正确接收的概率相当低。
这就导致重传的码率相当高。相比起来,复制流并不受接收端集合增长的影响,不同的接收
端丢失的包通常不同,而这时并不会增加网络的流量。
4.4. 分组层前向纠错
前向纠错是用来保护数据使之免受误码破坏的一项很成熟的计数。擦除码在可靠多播可
以得到很好的应用。
最简单的分组层的FEC就是将若干个将要发出的分组合起来对它们进行异或操作,生成
一个新的分组,并将这个新的分组也发送出去。如果每三个原始分组生成一个新的异或分组,
那么这三个分组中的任何一个丢失,而异或分组收到的话,丢失的原始分组可以重建出来。
还有一些更为一般的擦除码[BKKKLZ95],[Ri97],[LMSSS97]可以用k个原始分组生成n
个分组发送出去。这样,只要接收到n个分组中的任意k个分组,k个原始分组都可以完全
重建出来。
在应用FEC的时候,发送端将数据分组分成若干轮,每次对一轮中的分组进行编码并生
成新的监督分组。某些情况下一轮中的所有分组就构成了一个ADU,而在另外一些情况下一
轮中的分组只是ADU的一小部分。
用擦除码来恢复丢包比起用重传机制有很大的进步,因为这时发送端并不需要知道哪些
分组丢失了。因此,在恢复空间上无关的丢包的时候,重传流量就大大减少了。
我们可以把分组层的FEC方案分成两类:主动FEC和被动FEC。这两者的区别在于:主
动FEC中发送端先验地确定对于每一轮数据分组生成多少个监督分组;而在被动FEC中发送
端最开始只发送原始分组,并不发送监督分组,然后,发送端根据接收端的反馈来计算出丢
包最严重的接收端每一轮有多少个丢包,并以此来决定应当生成多少个监督分组。这些监督
分组当然也可以用于丢包不太严重的接收端恢复丢包。接收端通过ACK和NACK来向发送端
报告每一轮有多少个丢包。用NACK的时候,只有每一轮丢包最严重的接收端需要发送一个
NACK,因此它的丢包数就被用来作为NACK中随机定时器的权重。
主动FEC和被动FEC可以结合起来使用,例如,对每一轮发送都使用一定量的主动FEC,
如果某个接收端丢包过于严重无法恢复时,它可以请求发送端对这几轮数据包增加FEC监督
包的数量。
FEC对于减少丢包所造成的重传流量是很有效的,然而,它要求数据分组分成轮来发送,
这会增加端到端的延时。对于大数据量的应用来说这一般不成什么问题,但是对于交互式应
用来说,这种方法可能就不如直接重复发送更为有效。
4.5. 分层FEC
当数据被同时发往多个多播组的时候,可以应用另外一种分组层的
FEC[RVC98][BLMR98]。在这种情况下,原始的k个分组经过FEC生成n个编码分组,n远远
大于k。然后这n个编码分组被分别发往多个多播组。当某个接收端想要接收原始数据时,
它可以加入一个或多个多播组,并接收编码分组。当它接收到k个不同的编码分组,它就可
以退出这些多播组并重建出原始的k个分组。
这样一种分层机制的最重要之处在于不同的接收端可以根据它们自己的容量、处理能力
等以不同的速率来接收数据。这种机制中不需要接收端送回任何反馈信息,这样就可以保证
较高的吞吐率,并且吞吐率并不因为接收端集合的大小而受影响。然而,接收端以这种方式
来加入和离开多播组,会给拥塞控制机制带来一定的问题。同一个拥塞控制链上的接收端在
加入和离开分组的时候需要相互协调一下。如下一节所述,[RVC98]中提出了一个分层的拥
塞控制方案。
5. 拥塞控制机制
Internet的基本传输模型是最大努力服务(best-effort service)。在这种模型中,
不保证任何的吞吐率、延时和丢包率。终端系统被认为是自适应的,能够在网络拥塞的情况
下把它们的传输率适当降低。尽管以后Internet会开始支持带宽预留并对一些特定应用支
持不同的服务等级,但是除非终端系统明确知道它已经预留了带宽,否则它还是要进行拥塞
控制。
广义上讲,单发送端的多播拥塞控制解决方案有五类:
? 发送端控制,单组
只有一个多播组来做数据传输。用从接收端传回的反馈来控制这个组的发送速率。
目标是按照最慢的接收端的速率来进行传输。
? 发送端控制,多组
把最初得一个多播组按照拥塞点自适应地划分成若干个子组。在应用层,数据首先
发送到离发送端最近的子组,然后由这个子组将数据以更低的速率转发到更远的子
组。用这样一种方式,不同的接收端可以以不同的速率来接收数据。在子组内仍然
使用基于发送端的拥塞控制方案。
? 接收端控制,单组
只有一个多播组来做数据传输。由接收端来根据当前网络的拥塞状况决定是否发送
端的速率过高,不能适应这个速率的接收端就自动离开多播组。
? 接收端控制,分层组织
[RVC98]中提出了一种不需要接收端反馈的分层的拥塞控制机制。发送端将数据同
时分散的发往多个多播组,接收端根据它们自己的网络带宽及网络的拥塞状况来决
定加入哪些多播组,使得接收的数据量能够适应网络的拥塞状况。然而,这种方案
要求在一条瓶颈链路之后的若干个接收端能够相互协调地加入和离开不同的多播
组。并且这种方法是否能够在实际的Internet上应用还未得到完全证实。因此,
在拥塞控制方案上还需要有更深入的工作。
? 基于路由器的拥塞控制
可以在多播路由器中加入额外的机制来协助进行多播的拥塞控制。这些机制包括:
? 条件性加入:某个接收端在加入多播组时设定一个丢包率,当高于这个丢包率
时,允许路由器拒绝其加入。
? 路由器过滤掉合理速率以上的流量。这也包括在网络的不同位置根据局部拥塞
状况设定不同的合理速率[LVS99]。
? 公平排队机制结合端到端速率自适应调整
基于路由器的方案要求路由器比起传统的干线路由器有更多的状态。因此,在短期
内,这类方案只能应用于内联网。
对于可靠多播协议,必须把拥塞控制和可靠传输放在同等重要的位置来考虑。同样的机
制有时在提供可靠传输的同时也实现了拥塞控制。
在基于接收端的拥塞控制方案中,用FEC来做开环数据传送是一个很好的选择,对于大
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -