WebRTC 拥塞控制 | 网络带宽过载检测

简介: 本文是 WebRTC 拥塞控制 第 3 篇

作者:泰一
来源:码神说公众号

  • 导读
  • 网络带宽使用状态
  • 自适应阈值的设计
    • 为什么要动态自适应?
    • 阈值自适应算法
  • 源码分析
    • Detect 函数
    • UpdateThreshold 函数
  • 测试用例

导读

上一篇介绍了 Trendline 滤波器计算延迟梯度趋势的过程,求得了最终值 trendline_slope。接下来,就要用这个斜率值与阈值进行比较,从而检测网络带宽的使用状态,比如是否过载。实际的带宽检测过程涉及到:调整延迟梯度斜率值、过载触发条件、阈值自适应,本篇将介绍这个过程。

网络带宽使用状态
WebRTC 定义了三种网络带宽的使用状态:Normal、Underuse、Overuse,即正常、低载、过载。

enumclass BandwidthUsage {
  kBwNormal = 0,
  kBwUnderusing = 1,
  kBwOverusing = 2,
};

下图展示了过载检测中三种信号的产生机制,其中,上下两条红色曲线表示动态阈值:image.png
蓝色曲线表示调整后的延迟梯度斜率值:image.png

image.png

过载检测原理


可知,网络带宽使用状态的判定方法为:

image.png

自适应阈值的设计

为什么要动态自适应?

image.png

adaptive threshold is able to solve the starvation issue and allows the GCC flow to share the bottleneck fairly with the concurrent TCP flow,γ(t) follows m(t) with a smaller time constant which avoids the generation of a large number of consecutive overuse signals and prevents the starvation of the GCC flow.

理想的网络环境中,延迟梯度为 0,而在实际的网络环境中,延迟梯度则是不断变化的,让阈值跟随延迟梯度的变化而进行动态调整,可以降低 GCC 算法对延迟梯度变化的敏感度。

阈值自适应算法

GCC 提出的阈值自适应算法公式如下:
image.png

源码分析

基于 WebRTC 71 版本。

网络带宽的过载检测与动态阈值的更新也是在 TrendlineEstimator 类中实现的,函数声明如下:

class TrendlineEstimator {
private:
  void Detect(double trend,
    double ts_delta,
    int64_t now_ms);

  void UpdateThreshold(
    double modified_trend,
    int64_t now_ms);
};

每个数据包组(除了首个包组)的到来都会触发过载检测和阈值的动态更新。

Detect 函数

该函数输入延迟梯度趋势的值、包组的发送时间差、包组的到达时间,从而评估网络带宽的使用状态,比如是否过载?

image.png

constexprint kMinNumDeltas = 60;
constdouble modified_trend =
  std::min(num_of_deltas_, kMinNumDeltas) *
  trend * threshold_gain_;

num_of_deltas_ 表示包组间延迟梯度计算的次数,取值范围是 [2, 60],threshold_gain_ 是 Trendline 滤波器的增益参数,其默认值为 4,这两个变量都会对延迟梯度趋势值进行放大。

image.png

if (modified_trend > threshold_) {
  if (time_over_using_ == -1) {
    time_over_using_ = ts_delta / 2;
  } else {
    time_over_using_ += ts_delta;
  }
  overuse_counter_++;
  if (time_over_using_ >
      overusing_time_threshold_ &&
      overuse_counter_ > 1) {
    if (trend >= prev_trend_) {
      time_over_using_ = 0;
      overuse_counter_ = 0;
      hypothesis_ =
        BandwidthUsage::kBwOverusing;
    }
  }
}

值得一提的是,源码关于过载时间的计算是:过载时长等于包组发送时间差值 send_delta_ms 的累加。但是在首次检测到过载时,过载时长会初始化为包组发送时间差的一半,我把这个做法理解为一种类似于 TCP 的慢启动策略。注意,在满足所有条件触发过载信号后,过载时长与过载次数这两个变量要重置为 0。

UpdateThreshold 函数

该函数动态更新延迟梯度趋势的阈值。

当延迟梯度斜率和阈值的差值大于 kMaxAdaptOffsetMs (15) 时,不更新阈值。

if (fabs(modified_trend) > threshold_ +
  kMaxAdaptOffsetMs) {
    last_update_ms_ = now_ms;
    return;
}

这种情况可能发生在这样的场景:因为某些原因,网络链路的容量突然降低,导致延迟梯度瞬间急剧增长。

image.png

int64_t time_delta_ms = std::min(now_ms - last_update_ms_, kMaxTimeDeltaMs);
threshold_ += k * (fabs(modified_trend) - threshold_) * time_delta_ms;
threshold_ = rtc::SafeClamp(threshold_, 6.f, 600.f);

还有两点值得一提:

阈值计算公式中的 time_delta_ms 指的是包组的到达时间差 arrival_delta_ms,而上文中过载时长则是根据包组的发送时间差 send_delta_ms 来计算。
初始阈值设置为 12.5,计算后的阈值需要控制到 [6, 600] 这个区间内。GCC 草案解释了这么做的原因:

since a too small del_var_th(i) can cause the detector to become overly sensitive.

测试用例

继续使用了上篇的测试用例,一共构造了 41 个包组,来模拟过载检测的过程,输出如下:

image.png

测试输出


观察日志输出,有几个比较关键的点:
  1. 初始的延迟梯度阈值设置为 12.5,随后开始动态自适应,一直调整到了 GCC 草案建议的阈值范围的最小值 6,在包组 21 到来并开始计算延迟梯度斜率之前,保持不变。
  2. 包组 21 到来之前,样本点数量未达到窗口大小,虽然不会进行延迟梯度斜率的计算,但是会执行过载检测和动态阈值更新,由于斜率初始化为 0,小于阈值 6,故认为网络状态正常。
  3. 包组 21 到来之后,样本点达到窗口大小 20,开始计算延迟梯度斜率,可以看出,阈值跟随斜率而变动,但由于斜率一直大于阈值,故网络一直处于过载状态。

至此,网络带宽过载检测的内容介绍完毕。下一篇将介绍三种网络带宽使用状态的信号(normal、overuse、underuse)如何驱动 AIMD 码率控制器工作,从而有效的进行拥塞控制,感谢阅读。

参考资料
[1]Gcc Analysis: https://c3lab.poliba.it/images/6/65/Gcc-analysis.pdf

[2]GCC 草案: https://tools.ietf.org/html/draft-ietf-rmcat-gcc-02#section-5.4

「视频云技术」你最值得关注的音视频技术公众号,每周推送来自阿里云一线的实践技术文章,在这里与音视频领域一流工程师交流切磋。

image.png

相关文章
|
7天前
|
机器学习/深度学习 计算机视觉 网络架构
【YOLO11改进 - C3k2融合】C3k2DWRSeg二次创新C3k2_DWR:扩张式残差分割网络,提高特征提取效率和多尺度信息获取能力,助力小目标检测
【YOLO11改进 - C3k2融合】C3k2DWRSeg二次创新C3k2_DWR:扩张式残差分割网络,提高特征提取效率和多尺度信息获取能力,助力小目DWRSeg是一种高效的实时语义分割网络,通过将多尺度特征提取分为区域残差化和语义残差化两步,提高了特征提取效率。它引入了Dilation-wise Residual (DWR) 和 Simple Inverted Residual (SIR) 模块,优化了不同网络阶段的感受野。在Cityscapes和CamVid数据集上的实验表明,DWRSeg在准确性和推理速度之间取得了最佳平衡,达到了72.7%的mIoU,每秒319.5帧。代码和模型已公开。
【YOLO11改进 - C3k2融合】C3k2DWRSeg二次创新C3k2_DWR:扩张式残差分割网络,提高特征提取效率和多尺度信息获取能力,助力小目标检测
|
10天前
|
机器学习/深度学习 搜索推荐 安全
深度学习之社交网络中的社区检测
在社交网络分析中,社区检测是一项核心任务,旨在将网络中的节点(用户)划分为具有高内部连接密度且相对独立的子群。基于深度学习的社区检测方法,通过捕获复杂的网络结构信息和节点特征,在传统方法基础上实现了更准确、更具鲁棒性的社区划分。
25 7
|
7天前
|
机器学习/深度学习 计算机视觉 网络架构
【YOLO11改进 - C3k2融合】C3k2融合DWRSeg二次创新C3k2_DWRSeg:扩张式残差分割网络,提高特征提取效率和多尺度信息获取能力,助力小目标检测
【YOLO11改进 - C3k2融合】C3k2融合DWRSDWRSeg是一种高效的实时语义分割网络,通过将多尺度特征提取方法分解为区域残差化和语义残差化两步,提高了多尺度信息获取的效率。网络设计了Dilation-wise Residual (DWR) 和 Simple Inverted Residual (SIR) 模块,分别用于高阶段和低阶段,以充分利用不同感受野的特征图。实验结果表明,DWRSeg在Cityscapes和CamVid数据集上表现出色,以每秒319.5帧的速度在NVIDIA GeForce GTX 1080 Ti上达到72.7%的mIoU,超越了现有方法。代码和模型已公开。
|
2月前
|
机器学习/深度学习 安全 网络安全
利用机器学习优化网络安全威胁检测
【9月更文挑战第20天】在数字时代,网络安全成为企业和个人面临的重大挑战。传统的安全措施往往无法有效应对日益复杂的网络攻击手段。本文将探讨如何通过机器学习技术来提升威胁检测的效率和准确性,旨在为读者提供一种创新的视角,以理解和实施机器学习在网络安全中的应用,从而更好地保护数据和系统免受侵害。
|
2月前
|
机器学习/深度学习 数据采集 网络安全
使用Python实现深度学习模型:智能网络安全威胁检测
使用Python实现深度学习模型:智能网络安全威胁检测
173 5
|
24天前
|
运维 安全 网络协议
Python 网络编程:端口检测与IP解析
本文介绍了使用Python进行网络编程的两个重要技能:检查端口状态和根据IP地址解析主机名。通过`socket`库实现端口扫描和主机名解析的功能,并提供了详细的示例代码。文章最后还展示了如何整合这两部分代码,实现一个简单的命令行端口扫描器,适用于网络故障排查和安全审计。
|
26天前
|
机器学习/深度学习 边缘计算 5G
|
3月前
|
计算机视觉
在yolov5项目中如何使用自带摄像机不用网络摄像机进行实时检测?
这篇文章讨论了在yolov5项目中,如何避免使用网络摄像机而改用自带的本地摄像机进行实时目标检测,并提供了解决摄像头打开错误的具体步骤和代码示例。
在yolov5项目中如何使用自带摄像机不用网络摄像机进行实时检测?
|
4月前
|
网络协议 算法 程序员
提高网络稳定性的关键:TCP滑动窗口与拥塞控制解析
**TCP可靠传输与拥塞控制概要:** 小米讲解TCP如何确保数据可靠性。TCP通过分割数据、编号段、校验和、流量控制(滑动窗口)和拥塞控制(慢开始、拥塞避免、快重传、快恢复)保证数据安全传输。拥塞控制动态调整窗口大小,防止网络过载,提升效率。当连续收到3个相同ACK时执行快重传,快恢复避免剧烈波动。关注“软件求生”获取更多技术内容。
126 4
提高网络稳定性的关键:TCP滑动窗口与拥塞控制解析
|
3月前
|
机器学习/深度学习 监控 算法
基于深度学习网络的人员行为视频检测系统matlab仿真,带GUI界面
本仿真展示了基于GoogLeNet的人员行为检测系统在Matlab 2022a上的实现效果,无水印。GoogLeNet采用创新的Inception模块,高效地提取视频中人员行为特征并进行分类。核心程序循环读取视频帧,每十帧执行一次分类,最终输出最频繁的行为类别如“乐队”、“乒乓球”等。此技术适用于智能监控等多个领域。
67 4