关于TCP拥塞控制的一点想法

今天又想到去年在华为iaccess系统上遇到的问题,由于连续丢且没有dup ack引起的TCP拥塞控制的性能问题,这个问题当时给的调参数的方案虽然缓解了问题,但不能从根本上解决此类问题,今天中午休息的时候静下心来好好想了想,把不成熟的思路整理一下,备忘。

先抛出问题,抓包发现这个用户对应的TCP连接上经常有突发的瞬时大流量数据,抓包看到VPN已经把包发出,到公网链路后出出现了大量丢包,VPN客户端的抓包显示这些包没有到达客户端。因为没有dup ack, VPN协议栈的拥塞控制状态机没有触发快速重传和快速恢复。按照newreno的算法,每隔一段时间, 重传一个包,串行地把所有的重传包都发出去,这个时间非常长,严重的时候几十秒级别!从用户的抓包看到,这种问题周期性的出现,卡得几乎不可用。其实从抓包看到,超时重传的第一个包,在100多毫秒以后已经收到ack了,第二个重传包几毫秒就收到ack,这个TCP连接已经基本恢复正常了。但是newreno的拥塞状态机还在慢腾腾地隔一段时间发一个重传包。好在写公司这个协议栈的牛人留了一个可调参数,在这个case下,收到第一个重传包的ack就把TCP拥塞状态机切到快速重传-快速恢复状态。当时用了这个参数,客户体验提升并认可了这个方案。但是这毕竟不是一个完美的方案,我们的协议栈里TCP拥塞控制这块还有很大提升空间。

这个问题的源头是因为瞬时大流量导致了连续丢包且没有一个ack。解决newreno拥塞控制导致的不必要延迟,是被动的方式,第一个丢包的超时导致的延迟用户体验就很差。 VPN作为一个中间设备如果能把瞬时大流量整型,像大坝泄洪一样把流量温和地发出去就不会导致链路上如此严重的惩罚。

后来接触了cubic,bbr等拥塞算法,cubic和reno/newreno都是基于丢包触发的被动的方法,没有整型的功能。目前没有深入学习bbr,从一些介绍上看到它的目标是让inflight packet收敛于BDP(监测到的最大带宽*最小延迟), 并且用pacing rate来进行流量控制。但我猜测这种突发的瞬时大流量对于bbr这种基于统计值来进行决策的算法是不友好的,等到bbr检测到的时候可能已经晚了,丢包已经出现了。

对于这种case,我觉得基于丢包触发的拥塞控制算法可能更有优势,它让我想到了基于强化学习的试错思想,但是错了不能白错,要亡羊补牢,要记住教训,需要拥塞控制算法在丢包后有一个记忆功能,并能测量到这个瞬时流量的大小。以后如果再遇到这样的流量就进行流量整型。拥塞控制和流量整型结合起来效果才好。把基于丢包的算法和基于流量统计、整型的算法优点结合起来,对我遇到到这个case效果会更好。流量整型就要用到buffer,用不好的话就会产生bufferbloat, 先想到这里,有点混乱,先记下下来,有时间再继续。。。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章