多条流共享同一瓶颈链路时,涉及到并发调度问题。
调度在微观上就是查找,调度本身会带来开销。视角放远一点,我们仅当开销是个黑盒,不问细节,看看怎么回事。
类比进程调度,多进程分时运行,想象中时间被所有进程完全分享,实际上调度本身也占用时间,随着进程规模增加,调度开销也增加,O(1)调度的代价是调度周期的延长,因此O(1)理论上不存在,现实中log级已很好。因此,时间利用率随进程规模增加而降低。
开销与规模正相关,多流收敛也一样。
多流之间互不相识,不知对方存在,完全自组织,靠感知带宽,RTT等反馈的变化知道别的流存在,但不知道数量几何。带宽,RTT的变化来自于流与buffer以及流之间的交互,而感知这种交互需要时间,这个感知时间的存在就是固有损耗的根源。
那么,带宽利用率具体损耗在哪里呢?
与进程调度一样,多流收敛过程本身也会消耗带宽,这种消耗随着流规模增加而增加,也就是流越多,收敛本身损耗的带宽就越多,总有效带宽不会随流规模线性扩展。
这是普遍真理。
以AIMD为例。丢包使流执行MD,若降到可用带宽以下,空闲带宽作为浪费损耗,丢包重传则作为冗余带宽损耗掉,这就是收敛本身的损耗。因此AIMD不可能达到100%的带宽利用率,实际场景甚至60%都达不到。
多BBR流总带宽利用率稍好,但BBR多流收敛条件极为苛刻,且流之间公平性欠佳。
抛开ProbeRTT这种主动损耗,BBR不能抗抖动。BBR只在唯一的理想情况下对带宽的估计准确,但现实中却有一万种场景估不准。比如BBR以为高估了,突然有大流退出,实际却是低估,反之以为低估,burst了一波,实际却是高估。若考虑AIMD流带来的buffer延迟变化,丢包,抖动将更剧烈。
流越多,抖动的排列组合越多,带宽估算越不准,带宽利用率随流规模增加而渐低,这是事实,谁也救不了。这种固有损耗和高楼里的电梯必然占掉使用面积一样,是固有的。
携带丢包,延迟抖动的情形,AIMD的流间公平性好于BBR,因为AIMD是天然公平的,而BBR则需要主动公平。然而BBR的总带宽利用率却好于AIMD,这是因为BBR可以很快恢复随机非拥塞丢包前的带宽,AIMD却不能,因此BBR的单流带宽利用率很高,多流总带宽利用率自然也很高。
非抖动的稳定情形,BBR流间公平性,收敛速度以及总带宽利用率都相对较好。AIMD依赖RTT和buffer深度收敛,而BBR则在相对更短的时间间隔执行收敛,如8个round,10秒时间等。但这不意味着BBR好,对于固有损耗,寥不等于无,且抖动场景十之八九,绝对稳定场景则万里挑一。
总之,无论AIMD还是BBR,带宽利用率的降低都是固有的自组织损耗,消除这种损耗的唯二方式:
- 带外互通有无,不再自组织而是协作式,彼此告知彼此的情况,但这种互通有无的带外开销难道不也是一种开销?
- 带内干预,主动违背端到端原则,在转发节点增加流反压等源抑制机制。但这些设施难道不是开销?这些额外操作带来的延时难道不是开销?
最近思考大并发系统。共享瓶颈链路的拥塞控制也是此类系统的一个实例,既然是并发系统,调度开销就是固有的,谁也避不开。跟同事讨论BBR的一些优化,写点想法。
浙江温州皮鞋湿,下雨进水不会胖。