why bbr is removed from webrtc?

文章探讨了在WebRTC中使用BBR算法导致的异常高丢包率问题,分析了BBR与PacingController交互可能导致的拥塞和数据包排队延迟。作者指出,BBR在多流竞争带宽环境下可能增加网络延迟,并尝试修改算法参数以优化结果。通过调整探针RTT和编码器目标码率,作者在某些测试场景中看到改善,但仍面临挑战。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 webrtc的某个版本中实现BBR算法,后来被移除了。但是没有给出原因。
 这一个多月,我在仿真环境中[1]测试了BBR算法,在某些测试环境中竟然可以观测到超过50%的丢包。正常的BBR算法一般也就2%~3%的丢包,50%的丢包率属实有点变态。
 到这里,可能得出结论,BBR不适用于webrtc,就完事了。寻找原因,耗时多而又功劳少。幸亏我是临时工,没有kpi的要求。
 我原来觉得是quic中的BBR算法存在瑕疵,后来移植了TCP BBR的代码到webrtc中,在一些测试例子中,看到了正常的工作曲线。但是换了一些网络链路测试参数(带宽,时延),就有不正常的结果。
 什么原因导致了这么高的丢包?
 BBR算法在多个流争抢带宽的条件下,网络中的时延不可避免地增加。参看链接[2]的测试图片。在互联网这种数据转发模式下,不管什么拥塞控制算法,只要它要探测更高的带宽,总会在某个时刻导致网络传输时延的增长。
  BBR控制发包节奏的因子:congestion_window(cwnd)和pacing_rate。在webrtc中,还有另一个因素,编码器的目标码率(target_rate)。参考链接[3]给出的源码,webrtc中实现的BBR算法按照窗口滤波器的值配置target_rate。

NetworkControlUpdate BbrNetworkController::CreateRateUpdate(
    Timestamp at_time) const {
      DataRate bandwidth = BandwidthEstimate();
  if (bandwidth.IsZero())
    bandwidth = default_bandwidth_;
  TimeDelta rtt = GetMinRtt();
  DataRate pacing_rate = PacingRate();
  DataRate target_rate =
      config_.pacing_rate_as_target ? pacing_rate : bandwidth;
      
// ....
// ....
  update.congestion_window = GetCongestionWindow();
  return update;
}

 在PROBE_BW,cwnd = 2 * BandwidthEstimate() * min_rtt_。当往返时延(smooth_rtt)增加时,可能会出现这样这一种现象:BandwidthEstimate() > (cwnd / smooth_rtt)。这个时候,编码器target_rate大于(cwnd / smooth_rtt),cwnd成为瓶颈。当网络中飞行的数据包大于cwnd,pacer暂停向网络中发送数据包。会限制数据包向网络中的发送速度。尽管PacingController中的的pacing rate>=target_rate,由于cwnd的限制,PacingController会暂停向网络中发送数据包。

absl::optional<bool> RtpTransportControllerSend::GetCongestedStateUpdate()
    const {
  bool congested = transport_feedback_adapter_.GetOutstandingData() >=
                   congestion_window_size_;
  if (congested != is_congested_)
    return congested;
  return absl::nullopt;
}
void PacingController::SetCongested(bool congested) {
  if (congested_ && !congested) {
    UpdateBudgetWithElapsedTime(UpdateTimeAndGetElapsed(CurrentTime()));
  }
  congested_ = congested;
}

 编码器生成的数据包,只能在PacingController缓存,造成 packet_queue_数据包排队时延的增长。当时延超过一定的阈值时候,PacingController完全不按照BBR设置的速率控制发包节奏。为了限制最大的排队时延,PacingController存在超发机制。根据期望时延,重新计算发包速率(adjusted_media_rate_ )。比如根据我的日志,BBR要求pacing_rate为3Mbps,而PacingController最终决定的发送速率可能是6Mbps。

void PacingController::MaybeUpdateMediaRateDueToLongQueue(Timestamp now) {
  adjusted_media_rate_ = pacing_rate_;
  if (!drain_large_queues_) {
    return;
  }

  DataSize queue_size_data = QueueSizeData();
  if (queue_size_data > DataSize::Zero()) {
    // Assuming equal size packets and input/output rate, the average packet
    // has avg_time_left_ms left to get queue_size_bytes out of the queue, if
    // time constraint shall be met. Determine bitrate needed for that.
    packet_queue_.UpdateAverageQueueTime(now);
    TimeDelta avg_time_left =
        std::max(TimeDelta::Millis(1),
                 queue_time_limit_ - packet_queue_.AverageQueueTime());
    DataRate min_rate_needed = queue_size_data / avg_time_left;
    if (min_rate_needed > pacing_rate_) {
      adjusted_media_rate_ = min_rate_needed;
      RTC_LOG(LS_VERBOSE) << "bwe:large_pacing_queue pacing_rate_kbps="
                          << pacing_rate_.kbps();
    }
  }
}

 BBR的工作机制和webrtc的pacer原理,使得BBR算法完全处于失控状态,造成了极其变态的丢包率。
 如果关掉超发机制(drain_large_queues_ = false),就要忍受PacingController排队时延的不断膨胀。过高的时延是RTC类业务要尽力避免的。
 所以,BBR算法被移除,还是不冤枉的。
 那么,如何改进。
 这两周来,我一直在魔改算法参数,希望能够得到一个正常结果。比如在probe_cruise时,我设置target_rate 为0.95 * BandwidthEstimate()。在一些测试中,能够观测到正常的结果,在其他场景中,就不行。
  我尝试去掉拥塞窗口的限制。在几个测试例子里,算法测试还算正常。
  主要更改点:

  • 参考BBR v2,每5秒进入一次probe rtt,设置窗口为BDP/2。算法只在probe rtt限制拥塞窗口值:
if (PROBE_RTT == mode_) {
update.congestion_window = ProbeRttCongestionWindow();
} else {
update.congestion_window = DataSize::Infinity();
}
  • 在probe down 状态(pacing_gain = 0.75),设置编码器的目标码率为0.5 * BandwidthEstimate()。

 关于拥塞控制算法在实时通信领域的优化,我总结了一篇论文,贴到了arxiv:https://arxiv.org/pdf/2409.10042

Refer:
[1] webrtc-gcc-ns3
[2] quic-on-ns3
[3] bbr in webrtc

评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值