大历史下的 pacing:why & how

卸载一切到网卡,解放 cpu,兜售自己的设想:功能越来越多,吞吐越来越大的网卡。万物皆关联,吞吐越大的网卡反而更闯祸。范雅各布森的大历史视野不是每个工程师都具备的,更何况经理们。

事实是,网卡发送得太快而不是太慢了,因此需要让网卡更慢而不是更快一些。在报文之间塞入哪怕再小的 time slice 都好过突发。但这是为什么?建议阅读:Evolving from AFAP: Teaching NICs about time

人们很明确下面的话:

IP’s AFAP model is embodied in our current NIC API – we tell the NIC what to send but not when to send it. I believe that our ability to build future high efficiency networks depends critically on evolving the NIC API to cover both ‘what’ & ‘when’. I’ll try to explain why and how, at least in Linux, the evolution could be easy.

但人们并不真的践行。后面会提到,即使有了 edt 以及类似的东西,经理们依然倾向于为报文附着一个更早的时间戳,错的不是网卡应该具有的机制,而是人们使用这种机制的认知。

由于交换网络星形拓扑的本质,交换容量一般高出主机网卡一个数量级,主机并没有加速网络的动机,因为端到端时延几乎就是准光速时延,交换机配备一些少量 buffer 吸收突发。主机流量畅通无阻,更快的网卡只会导致交换机排队徒增时延,资源够用,不卷网卡。

随主机性能的发展,应用对带宽的需求也增加,但无论如何交换机总能相对于主机网卡保持至少 10x 的增速,网卡 100mbps,交换机 1gbps,网卡 1gpbs,交换机 10gbps,如此而已。交换机设备商总能拉开接入带宽和交换带宽数量级的差异,这背后起作用的是摩尔定律。

直到有一天摩尔定律曲线开始往下弯折,主机网卡性能逐渐追平交换机,主机当高楼,带宽看作绿地,越来越高的容积率让网卡陷入内卷。前面我在分析 bbr 从 buffer 挤占带宽时描述过带宽挤占的动力学,不再赘述,简单说就是你努力制造更快的网卡只能至多保持住固定带宽的比例,但如果你什么都不做,你所能用的带宽将越来越小。

但另一条路才是正确的,自律,也就是 pacing。

核心交换容量虽不能再跟随摩尔定律的节奏,但却还可通过并行化而负担更大交换容量,至少目前而言,应对应用的需求并不在话下。和摩尔定律时代唯一不同的是交换机和网卡不再有数量级的差异,比如网卡 25gbps,交换机普遍只有 100gbps 而不是 250gbps。

此情况下,较小 buffer 的网络已不符合现状了,如今需要更大的 buffer 应对突发,而更大的 buffer 的时延副作用很明显,因此大 buffer 是另一个问题,而不是方案。

若要使应用流量达到以前畅通无阻的效果,办法就是主机主动感知和测量(虽然不会准,但能算个大概)瓶颈带宽,然后基于此带宽主动自律,这便是 pacing。

在这个大历史框架下,我们发现这自然而然就是 rate-based 拥塞控制算法的背景,而 google 正是在这个 2010 年代研发并部署了 bbr,一切都不是空穴来风。

再看如何做到 pacing,pacing 得以平滑部署的功劳要归于 tcp/ip 的简洁。tcp/ip 来自于做减法而不是加法。

tcp/ip 最大的特点是对周边不做任何假设和限制,ip 尽力而为而 tcp 提供可靠性,虽然事后来看可靠性也并非必须。总之,在当时那个年代,tcp/ip 最大化了通用最小化了约束,这支撑它平稳度过摩尔定律曲线开始向下弯折的拐点。

设计 tcp/ip 时,让它比看起来更好非常容易,做出某种假设和限制将事情复杂化几乎是当代经理每天都在做的事,随着时过境迁,一些外部条件发生改变导致某些假设不合时宜,要把其中一些限制去掉时,就很难甚至不可能了,因此 tcp/ip 的简洁性非常重要,它没有规定如何发送报文的细节,这给了 pacing 被引入的空间。

仅就 linux tcp 而言,pacing 至少经历了三种方案,一开始借用 fq-qdisc,后来 bbr 在 tcp 逻辑内部实现了 internal pacing,再后来有了 edt(earliest departure time),而 dpdk 版的 tcp pacing 更灵活。

对拥塞控制而言,做 pacing 就完了,而拥塞控制与流量控制是分开作用的,前者负责从网卡发出到网卡接收到的传输区间,但绝不是从离开 tcp 层就开始起作用了,我们发现,引入 edt 后,对 small queue 的依赖自然也降低了,这个和引入 tcp rack 对 tlp,er 的依赖降低一样。

在 pacing instead of burst 这个大原则指导下,一切都往时间戳靠就对了,因为需要基于时间做出更精确的控制以支撑 pacing,与 tcp rack 基于时间戳做丢包检测同理,edt 基于时间戳做发送也是正确的(google swift 用时间戳做更精确的标记也是为支撑更精确的计算)。

edt 的思想很简单,传输层控制逻辑根据采集到的数据计算出 pacing rate,为每一个待发送报文贴上一个时间戳,网卡基于该时间戳安排报文的实际发送,这消除了网卡发送报文时的计算和调度带来的误差和抖动,发送逻辑只需要查看一下报文上的时间戳即可。

从 edt 的 earliest 修饰看出,作为一个不仅限于 tcp 的通用逻辑,它规定 “最早发送时间” 而不是 “最迟发送时间”,edt 是往里收着的,它并不倾向于 “以尽可能快的速率发送”,相反它限制 “最快速率不能超过 x”。

即使一个主机中塞入了 10000000000 个连接,如果它们果真采用正确的方式测量和计算而不是冒进,计算结果也会合理均分瓶颈带宽。

但这一次,在对细节的理解上,经理们可能又错了。按照上一段的解释,如果每个连接都倾向于正确计算 delivery rate,网卡在一个时间轮上按照报文 edt 发送,总速率一定不会超过网络的瓶颈带宽,在后摩尔定律时代,虽然网卡追平了交换机,但不是越大越好。

但如果经理获得了一个更好的网卡(称经卡),一定会用光它。经理一定会塞入更多的报文,大多数经理并不知道 edt,更不用谈传输逻辑正确计算速率,他们用 blind flood 方式测试网卡而不是在现网测试有效吞吐。更难以理喻的是,他们宁可接受发送 100 个报文让交换机扔掉 50 个,也不愿意只发送 50 个。如果交换机因此升级到可支撑 100 个报文,经卡则会发送 150 个,宁愿用重传报文打满带宽。至于公平性,恶意假设是,你忽略公平性而获益,让我做公平性肯定在骗我。

反 pacing,反收敛导致资源浪费,每发送一个注定被丢弃的报文都是电能在做无用功,每排查一例因此导致的丢包和重传问题(绝不是故障,但很多人不清楚丢包和重传不是故障)都在无效消耗工人精力,可能还有公司的钱。内卷思维在经理心里是一贯的。

pacing 迎着大历史背景而生,要迎合 pacing 不是试图绕开它,这是获得最佳能效的唯一方式,这是历史决定的。

值得担心的不是它有多复杂,相反它很简单。值得担心的是人们在内心里的 “慢了就会输” 的笃念,就像在路上即使没急事也不允许有车在自己前面一样。如果只能发送 10 个报文,经理们总倾向于发送 11 个,如果 100gbps 网卡刚跑到 60gbps,经理们会尝试让它跑到 70gbps,至于好几跳以后的那个交换机的情况,谁在乎。

“慢了就会输” 是人们内心笃定的,这可能是人们讨厌等待却又喜欢排队的原因。大家都已经在排队了,我还等什么呢,pacing 和错峰是不被接受的,凭什么是我错峰到人后,人们宁可挤作一团也不想主动收敛。这可能是我们国家人太多的缘故,这导致我们国家的人普遍有 “宁愿挤作一团”,“不甘人后”,“慢了就会输” 的笃念,这些笃念影响着我们做的每一件事,我们会把这些笃念注入到我们设计的一切,以致很多人把 “取消 pacing,激进发送数据” 作为自己面试或晋升的亮点,而对方也会觉得 “我艹,牛逼!” … 本文以范雅各布森的大历史视角分析一下 pacing 的故事。

浙江温州皮鞋湿,下雨进水不会胖。

  • 10
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值