tcp/nc 是指 “tcp with network coding”,是一种结合了网络编码技术的 tcp 变种,网上资源很少,我也不准备多介绍,只介绍它的核心。
传统 tcp 在演进过程中一直搞不定效率问题,网络带宽在增长,cpu 却没有变得更快,为保持可靠语义,tcp 丢包判断和重传逻辑的时间占比越来越大。
从 3 次 dupack,3 个 sacked segs 到 rack,甚至跌入 rto,逻辑复杂的核心在于,你必须用某种启发式算法判定丢包,然后择机重传标记为 lost 的报文,丢包判断必须尽快,而重传却不得不谨慎,慌乱中很难把握分寸,则要么不足,要么激进。tcp 没有提供一种内在的方式,让丢包判断和重传在松弛的氛围中进行。
tcp/nc 依然是我那 “横竖一颠倒,世界变了样” 方法论的体现:
通过编码系数提供冗余,receiver 解码过程就是一个解 n 元一次方程组的过程,每一个包就是一个方程,丢一个包意味着 n 个方程少了一个,需要补一个方程,就是重传。
判断丢包非常简单,receiver 保存两个变量:
- H1 表示一个 tcp/nc 报文表示的一个方程中序号最高的包,比如上图中 receiver 收到 c2,H1 就是 p2;
- H2 表示 receiver 当前收到的连续的序号最高的包,上图中如果 c 丢失,收到 c2 时,H2 就是 p1;
如果没有丢包,H1 - H2 = 0,理论上 sender 只要发现 H1 - H2 > 0 即可补充一个冗余报文,但 sender 可以将这件事延迟,这就是给了乱序以松弛感。
比如 c1 丢失,sender 收到 c2 即可发送一个冗余报文,比如 c3 = p0 + 3p1 + p2,但它可以继续等到收到 c3,发现 H1 - H2 > 0 依旧,就可以发送一个冗余了,比如 c4 = p0 + 2p1 + p2 + p3,4 个未知数 4 个方程,p0 到 p3 解码成功。
只是一个简单例子,想说的是,这种冗余编码(可以支撑延迟一个编码窗口)提供的松弛感可以让 sender 采集足够多的数据,进行更加理性的拥塞判断,而不是像传统 tcp 那样频繁跌入 ssthresh = cwnd / 2 甚至 rto。
至于冗余度,既然不准备多介绍 tcp/nc 也就不多说,确实,相比传统 tcp,有效传输的数据更少了,但这本身就是 trade off,旨在解除 tcp 的抱怨 “花太多精力在丢包判断和重传中”,就够了。
规整化,本身就要付出代价,要看收益有多大。
浙江温州皮鞋湿,下雨进水不会胖。