谈谈网络通讯中的流量整形

前面的两篇文章《谈谈网络通讯中的 ACK、NACK 和 REX》《谈谈网络通讯中的 FEC 基础》介绍了网络通讯中的丢包重传和 FEC 的相关理论和方法,他们都是在网络发生丢包的状况下的补救措施,本文则往前进一步,介绍下如何经过流量整形技术,尽量地避免网络发生丢包。算法

从堵车提及缓存

v2-dbd54149c8a9baf674a0237ea5623f5d_hd.png

堵车的缘由有不少种,咱们先聊聊图中的这种:假设某公路是 3 股道,也就是说,每时刻能同时进入该公路的车辆并行是 3 辆,那么,若是某一时间段,同时试图进入该公路的车辆超过 3 辆,则必然会出现因为公路的承载能力不够带来的 “堵车”。微信


v2-e3fd9186c204581fb255c15e64838d65_hd.png

网络传输也相似,假设网络带宽是 2Mbps,若是在每秒硬塞给网络的数据包 > 2Mbps,网络通道也会受不了。不过它的表现形式与公路不同的地方在于:超出网络承载能力的数据包,可能会被网卡/路由器/交换机给丢掉,即咱们常说的丢包(loss)。网络


对于网络传输而言,丢包带来的成本是很高的,由于一些重要的数据包丢失后,是须要 “重传” 的,而 “重传” 太多,来回反复会增长了数据传输的延时,也会进一步恶化网络负荷,最终极大地下降了传输的效率。app


所以,咱们须要从根本上尽量地减小 “丢包” 的产生,简单来讲,就是控制单位时间内送入网络传输的数据量,尽可能平滑且不要超过网络带宽承载能力。ide

控制对象ui

既然要控制送入网络传输的数据量,就得先找到数据是怎么产生的,又是在经过哪一个环节送入到网络的。编码

DraggedImage.png


如图,音视频传输的数据 “源头” ,无外乎就是本地的音视频文件、麦克风采集的音频流、摄像头采集的视频流、桌面采集到的屏幕流等,它们通过编码压缩和封包处理,而后通过 “发送模块” 送入到网络中。spa

设置和修改采集的配置(如:分辨率、帧率)、编码器的配置(如:GOP 间隔、码率)等,是能够减小实时产生的总数据量的,可是数据的产生并非 “平滑” 的,特别是视频流/屏幕流,画面的突变,会带来数据量的突变,所以,送入到 “发送模块” 的数据量,也并不会老是 “平滑” 的。3d


从上面的 “堵车” 理论,为了不丢包,咱们须要尽量地将数据 “平滑” 地送入网络中,所以,“流量整形” 在此派上了用场,它做用于 “发送模块”,目标是调整数据传输的平均速率,防止突发性的流量暴增致使网络拥塞和丢包。

流量整形

如何平输入和输出,一个最容易想到方法,就是增长 “缓冲”,让输入的数据先进入 “缓冲区” ,而后用恒定的 “速率” 从缓冲区取数据输出。这种方法称之为 “漏桶算法”。

漏桶算法(Leaky Bucket)

v2-da28afda819a75f0cd11aa4c5e05512b_hd.png

如图,使用一个 packet buffer(漏桶),把全部输入的 packet 缓存起来。


设置一个目标的输出码率(好比:3Mbps),固定的时间间隔(好比:10ms),读取 packet buffer(漏桶)中固定数量的 packet(如:3Mbit * 10ms / 1000 = 0.03Mbit)进行网络发送。注:若是某时刻缓冲区没有数据,则不用发送了。


漏桶算法的缺点

漏桶算法有一个明显的缺点,由于很是精准的网络带宽没法预判,那么假设你设置了一个比较小的目标码率(如 3Mbps),可能小于真实的网络带宽(如 10Mbps),这时,若是业务上产生了一些突发的流量,真实的网络带宽本能够容许更快地完成发送,但通过了漏桶算法后,依然会以恒定的目标码率慢慢地发送。因此说,漏桶算法没法充分用满网络资源来下降传输延时。


解决方案有 2 个:

  1. 先慢启动,而后将漏桶的目标码率持续上探,直到出现网络恶化(如:丢包增多)后再降下来,如此反复,维持一个动态平衡,使得漏桶算法的目标码率持续无限逼近网络的承载能力

  2. 改进漏桶算法,容许其在执行过程当中,偶尔出现一些超过预设平均值的突发传输能力,用于应对业务上的流量突发,即:令牌桶算法


令牌桶算法(Token Bucket)

v2-c4cda3c67c50d6e4f01f6179dafe3991_hd.png

令牌桶算法在漏桶算法基础上,提出一个改进,就是新增了 “令牌” 和 “令牌桶”。


“令牌” 表明着容许传输的字节数量,咱们以固定的时间间隔(好比:10ms)产生并送入 “令牌” 到  “令牌桶”,“令牌桶” 设置一个  “令牌” 数量上限(满了没有消耗就丢掉新增的令牌),所以,一次传输最大的容许突增的字节数 = M x B


发送模块,以固定 t ms 的时间间隔去读取 packet buffer,读取的字节数 X 必须接近但小于等于当前 “令牌桶” 中容许传输的字节数(即:“令牌桶” 里剩余的  “令牌个数” x B)。而且,传输完了多少字节,则删除掉 “令牌桶” 里对应个数的 “令牌”。


这种方法解决突发流量的关键点在哪呢 ?


在于 “令牌” 是能够积累的,可能缓冲区在前 N ms 都没有突发的数据,这时,“令牌” 依然在产生,而且被积累在了 “令牌桶”,一旦缓冲区突增了大量的数据,则能够在短期内快速消费掉。固然,为了防止突破网络承载能力致使丢包,“令牌桶” 的最大 “令牌数量” 也相应作了一些限制。

小结

关于网络通讯中的流量整形就简单介绍到这里了,“漏桶算法” 和 “令牌桶算法” 其实在不少的地方都有使用,好比服务端的限流降级,好比音视频的平滑丢帧等等,固然,也还有一些基于这些算法的各类改进策略,这里就不一一介绍了,欢迎你们来信 lujun.hust@gmail.com 交流,另外,也欢迎你们关注个人新浪微博 @卢_俊 或者 微信公众号 @Jhuster 获取最新的文章和资讯。

相关文章
相关标签/搜索