流媒体拥塞控制与流控技术分析
一、概述
1. 文章背景
音视频流传输的核心挑战在于如何在网络动态变化的环境中保持稳定的用户体验。与传统块数据传输不同,流媒体传输对时延和抖动极为敏感,需要在毫秒级别进行速率调节,而非传统 TCP 的秒级调节。
2. 核心观点
- 工程方案是权衡的结果,而非最优解
- 流媒体传输优先级:低时延 > 低抖动 > 吞吐量
- 过度复杂的算法往往弄巧成拙,简单的 buffer 水位控制方案反而被忽视
3. 文章来源
dog250 博客 - 流媒体拥塞控制与流控
二、流媒体传输的核心需求
1. 优先级排序
流媒体传输的质量指标按重要性排序:
graph TD
A[流媒体传输质量] --> B[低时延]
A --> C[低抖动]
A --> D[高吞吐]
B --> E[网络质量好<br/>高清晰度]
C --> F[网络质量稍差<br/>Buffer 吸收抖动]
D --> G[网络质量差<br/>降低码率]2. 不同网络场景的策略
| 网络质量 | 策略 | 目标 |
|---|---|---|
| 网络质量好 | 保证低时延下的高清晰度 | 最大化用户体验 |
| 网络质量稍差 | 使用少量 buffer 吸收抖动 | 平衡时延与稳定性 |
| 网络质量差 | 降低码率,少发数据 | 确保基本可用性 |
3. 码率与网络的适配原则
码率必须适应网络,而不是反过来。这一点与传统块数据传输的"尽可能多发一点"认知形成鲜明对比。
三、拥塞控制的困境
1. 时间尺度错配问题
传统 TCP 拥塞控制设计用于块数据传输,在相对较大的时间尺度(秒级)上调速。这种设计在《TCP/IP 详解》卷 1 中有详细描述。
然而,流媒体传输需要在毫秒级别甚至更小的时间尺度上调速。这种时间尺度的错配导致:
- 传统拥塞控制响应太慢
- 各种"错配算法"铺天盖地,试图弥补这一缺陷
- 越复杂的算法,往往越容易弄巧成拙
2. 发送端拥塞控制的演进
现代 sender 端拥塞控制逐渐向上"紧贴"业务,强调与编解码结合。这种趋势的原因在于:
- 流媒体传输逻辑和传输层拥塞控制难以解耦
- 希望通过跨层优化获得更好的性能
然而,作者指出这是一个值得反思的方向。如果关联编解码,事情会变得更复杂。更合理的做法是将时延的职责更多往下层压。
3. 传输层与应用层的协同
正确的协同方式应该是:
sequenceDiagram
participant 传输层 as 传输层拥塞控制
participant 应用层 as 应用层编解码
传输层->>应用层: 网络拥塞,建议降低码率
应用层->>应用层: 降低编码码率
应用层->>传输层: 已调整,发送速率降低
传输层->>应用层: 网络空闲,可以增加码率
应用层->>应用层: 提高编码码率
应用层->>传输层: 已调整,发送速率增加如果应用层不能及时响应传输层的信号,就会造成应用层时延抖动。这也是为什么流媒体拥塞控制如此困难的原因之一。
四、被忽视的简单方案
1. Buffer 水位控制方案
一个简单但有效的解决方案十几年前就已经存在:在 sender 应用层和传输层之间铺垫一个固定 buffer,应用层持续观测 buffer 水位,调整编码速率,以保持 buffer 水平一直保持稳定。拥塞控制则完全交给传输层。
这种方案的工作原理:
graph LR
A[应用层] -->|编码数据| B[固定 Buffer]
B -->|数据| C[传输层拥塞控制]
C -->|网络状态反馈| B
B -->|水位反馈| A
A -->|调整码率| B2. 为什么被唾弃
这个简单有效的方案被普遍唾弃的原因令人深思:
- 显式引入了时延
- 与"极低时延"的宣传话术相违背
- 简单是原罪,不够"高大上"
3. 墨菲氏滴管的启示
日常生活中有一个很好的例子解释持续观测 buffer 水位的原理:输液管中间的墨菲氏滴管。
工作原理:
- 不断调节滴管下游的流速
- 滴管的水位在气压作用下保持恒定
- 这就是典型的流控
TCP 的端到端流控也采用了这种方法:
- Receiver 不断反馈 rcv buffer 的"水位" rwnd
- Sender 根据 rwnd 调整发送速率
- 原理与墨菲氏滴管相同,只是依赖机制不同(TCP 依赖接收窗口反馈,而非气压)
五、流控与拥塞控制的区别
1. 核心差异
| 特性 | 流控 | 拥塞控制 |
|---|---|---|
| 作用范围 | 逐跳行为 | 端到端行为 |
| 反馈路径 | 链路层直接反馈 | 端到端间接反馈 |
| 适用场景 | 数据中心网络 | 广域网 |
| 响应速度 | 快速(微秒级) | 较慢(毫秒到秒级) |
2. 数据中心的流控优势
流控的意义更多在逐跳行为,因此广域网不适合做流控,但数据中心能:
- 数据中心网络拓扑相对可控
- 链路距离短,反馈延迟低
- 可以实现精细化的逐跳流控
3. 递归流控网络
如果把持续观测下层 buffer 水位的算法在分层网络各层间递归做下去,最终得到的就是一个 link 级的流控方案。
graph TB
A[源端] --> B[交换节点 1]
B --> C[交换节点 2]
C --> D[交换节点 3]
D --> E[目的端]
B -.流控.-> A
C -.流控.-> B
D -.流控.-> C
E -.流控.-> D这相当于将大量墨菲氏滴管级联或组成胖树结构,仍能观测到稳定平衡水位的现象。每一个滴管都维持着稳定的平衡水位。
结论:纯流控网络天然无拥塞,不再需要拥塞控制。
六、现有技术方案
1. InfiniBand
InfiniBand 是一个 link 级流控方案实例:
- 实现了真正的逐跳流控
- 基于信用机制的流量控制
- 在高性能计算领域有广泛应用
2. RoCEv2
RoCEv2(RDMA over Converged Ethernet version 2)是一个松散版本:
- 采用 PFC(Priority Flow Control)Pause 帧
- 在网络已经拥塞时迅速阻滞部分流量
- 不是全程观测并平滑阻滞
RoCEv2 的流控策略类似于:
- 显示"剩余车位 2"的停车场入口
- 排队等待几乎一定比显示"车位已满"的入口更严重
七、系统动力学视角
1. 系统动力学模型
传输网络非常适用系统动力学建模。系统由以下元素组成:
- 源:数据的产生点
- 汇:数据的消费点
- 存量:系统中的积累(如 buffer、队列)
- 流量:存量之间的转移(数据传输速率)
核心原则:流量刻画各存量水平之间的反馈。
2. 存量决定行为
系统动力学模型强调,存量决定行为,流量负责改变行为,但千万不要试图让流量决定行为。
例子:一个屋子的室温是空调的设置决定的,而不是开窗关窗决定的。
3. 流量关系的谬误
善作计量者总是试图发现各种流量之间的关系,并以此为定论决定此后的流量,但这是徒劳的。他们不过在寻找一些不存在或至少不稳定的关系。
事实:任何一个系统的流量和其它流量之间都没有稳定的关系,流量只受存量影响。
4. 在网络传输中的应用
数据和 buffer 就是存量,而 link 级的流控就是流量引起的反馈。
端到端传输控制相当于丢失了很多反馈,那也就只好由端自行发现并处理异常(丢包或时延抖动)了,这就是拥塞控制。
graph LR
A[Link 级流控] -->|直接反馈| B[存量]
C[端到端拥塞控制] -->|间接反馈| B
B -.丢失很多反馈.-> C八、工程实践中的权衡
1. 权衡的本质
作者反复强调一个观点:由于交易的本质,设计和优化的过程本就是不断权衡的过程。优化的收益需要放弃一些别的收益,最终的工程方案一定不是最优的,而是足够好的。
2. 流媒体传输的权衡
对于流媒体传输:
| 指标 | 危害程度 | 应对策略 |
|---|---|---|
| 抖动 | 危害更大 | 使用 buffer 吸收 |
| 时延 | 次要影响 | 接受少量 buffer 时延 |
| 吞吐 | 优先级最低 | 码率适应网络 |
稍微的 buffer 时延便可以吸收大量抖动,这种基于交换的解法也足够简单。
3. 简单的价值
简单是原罪的文化倾向导致了许多过度设计的方案。事实上,简单的方案往往更可靠、更易维护、更易理解。
九、总结与启示
1. 核心要点总结
- 流媒体传输需要在毫秒级别进行速率调节
- 过度复杂的拥塞控制算法往往弄巧成拙
- Buffer 水位控制是简单有效的方案,但被忽视
- 流控适合数据中心,拥塞控制适合广域网
- 系统动力学视角有助于理解网络传输的本质
2. 工程实践的启示
- 不要盲目追求"极低时延"的宣传话术
- 接受权衡,追求"足够好"而非"最优"
- 重视存量(buffer)的作用,而非仅仅关注流量
- 简单的方案往往更有价值
3. 对未来设计的建议
流媒体传输系统设计应该:
- 优先考虑 buffer 水位控制方案
- 将时延职责更多分配到传输层
- 应用层专注于根据反馈调整码率
- 避免过度复杂的跨层优化
- 在数据中心环境考虑 link 级流控