最初的算法:
- 在 winmax 中追踪 alpha rounds 的 bw / rtt,将其 bw 记为 b;
- 在 winmin 中追踪 k*alpha rounds 的 rtt,记为 minrtt;
- 保持 inflight = b * minrtt + beta。
后来我给 beta 增加了一个 rtt 缩放系数,主要是避免 rtt 膨胀,增加一个往回收缩的趋势:
- 保持 inflight = b * minrtt + (minrtt / rtt) * beta。
今天有朋友提出这算法全靠统计波动随机收敛,没有自动收敛的适应力。ok,那么还需要增加一个负反馈环,该反馈环作为另一个 beta 系数,要与 bw 负相关。
看量纲,beta 是一个表示数据量的标量,它可由 bw 和 rtt 相乘获得,而 rtt 可由 "报文数量" 与 bw 相除获得,显然,若想控制报文数量,则可由 beta / bw 获得 rtt,再乘以一个预期带宽 gamma 就是了:
- 保持 inflight = b * minrtt + (minrtt / rtt) * (beta / bw) * gamma。
如果你的预期带宽是 500mbps,预期 buffer 量为 20m,则 gamma = 20m,beta = 500mbps:
保持 inflight = b * minrtt + (minrtt / (rtt * bw)) * 10000。
但事实上,还是那句话,"不要试图精确控制,让统计学来搞定",千万不要在这里把事情过度复杂化,避免重蹈覆辙,我们只需要给出一个负反馈系数。因此上式可简化为:
- inflight = b * minrtt + (minrtt / (rtt * bw)) * beta。
bw 越大,inflight 位于 buffer 中的 probe 余量越小,它便逐渐出让带宽,反之 bw 越小,inflight 位于 buffer 中的 probe 余量越大,可获得更多带宽。与此并列,rtt 超出 minrtt 意味着 buffer 开始堆积,于是 probe 余量减小抵制这膨胀。
这就是算法的全部,全程负反馈。
如果碰到 loss-based cc(or capacity-seeking) 怎么办?有趣的是,只需要将 probe 余量计算系数的分子分母倒置就 ok,这正好是一个 "加性增"。
算法中揉进丢包检测处理,间隔倒置 beta 系数就能自适应,但这又复杂了不是吗,这不是我一直怼的吗,所以可这么做,但别做。
下个问题,随流量增加,buffer 中的 probe 余量是累加的,该算法在这个点上似乎是 "不可扩展" 的,这可是计算机算法相关判断标准的大忌,只要不可扩展,O(f(n)) 里的 f(n) 不上凸就是一个孬算法,这咋办。
没任何算法能空手套白狼,但程序员却总妄想空手套白狼。程序员总希望找到不花任何代价完成系统伸缩和扩展的方法,10000000 条流的表现要和只有 1 条流是一模一样,这是纯扯犊子。
任何统计复用系统,只要系统过载(超过容量的一个比例阈值),时延一定增加,甚至系统崩溃,随着网络中流量的快速增加,后果非常类似于操作系统面临 fork 炸弹,再好的调度算法也无力应对。
既然系统可过载,buffer 增加甚至溢出就是允许的。
流数量增加,buffer 占用一定增加。但这算法会尽力让 buffer 增加的速度变慢,(minrtt / rtt) 系数就干这个,只要 k 足够,beta 系数会逐渐变小,让 buffer 中 probe 余量增加变慢。
解决系统过载问题的核心不再算法,而在端决策。
如果你看到实时导航发现路上已经堵成一锅粥了,你还会出行吗?会开车但看不懂地图的人还真会照旧出行,但恰恰就是他们在添堵,但他们会想,凭什么让我等。
同理,视频卡成狗了,你会不断刷新而不是暂停,而刷新行为就是添堵。
如果网络没有准入限制,不在端限流,只在转发节点限流,会让事情更糟,随之而来就是各类 qos,调度,pfc 类弱智方案。
好的端决策应把 "能不能发" 和 "发多少" 分开,算法只能告诉你发多少,无法告诉你能不能发,能不能发由 qoe 决定,如果你认为 "凭什么让我等",即使算法告诉你不能发,它能阻止你吗,各类 "加速" 属此类,实属减速,最终让系统过载!如果你想获得好的体验,算法反馈的结果(比如有效吞吐[delivery rate])让你截止,这才是缓解拥塞的好方法。
拥塞控制一定要有准入约束,只要流量入网,就只能调度它,即使丢包,端的重传行为无非继续注入流量而已,不限制准入,转发节点所做的任何事,只是让网络变得更慢,而不是加速。
准入控制意味着报文阻塞在本地排队,网络告诉你什么时候可以发,时间可预期,端系统就可以精确调度其它任务,而不是被不可预期的回应中断,事情都解决了。但这就不是统计复用系统了。
所以,算法限制 inflight,剩下的交给统计律,本质上就是让系统行为可预期(不管在多大范围内)。我给这个算法取名 tcp cangchangroad,简称 tcp ccr,因为我在嘉定仓场路一个花园写的代码,但 ccr 也可以认为是 congestion control rewrite。
浙江温州皮鞋湿,下雨进水不会胖。