限速器优化中使用字节跳动的实践探讨
发布时间:2023-03-31 09:18:49 所属栏目:动态 来源:
导读:限速器(rate limiter)是一个非常基础的网络处理功能,被广泛应用于各类网元设备,在流量调度、网络安全等领域发挥着重要作用。常见的限速器的实现方式基于令牌桶(token bucket),尽管令牌桶的原理已经被人熟知,
|
限速器(rate limiter)是一个非常基础的网络处理功能,被广泛应用于各类网元设备,在流量调度、网络安全等领域发挥着重要作用。常见的限速器的实现方式基于令牌桶(token bucket),尽管令牌桶的原理已经被人熟知,在具体实践中,我们也发现了一些挑战和共性问题。本文总结了近两年字节跳动系统技术工程团队(简称 STE 团队)在限速器优化方面的一些探索,将一些经验和教训总结出来,以飨读者。 相信每个写网络处理的工程师都写过基本的令牌桶限速器。令牌桶是一个形象的描述,即可以想象有一个桶可以容纳一定量的令牌(token),每放行一个数据包便消耗一定量的令牌,数据包的放行与否取决于令牌桶中的令牌个数。 令牌桶是有容量的,上述公式的值可能会超过令牌桶的容量,假设令牌桶的容量为 ,如果上述计算的值超过了这个限定,则令牌数等于 。 此时因为数据包 要经过,则应该消耗 1个令牌,于是更新令牌桶的时间戳为 并按照上述计算更新令牌桶内的令牌数目。如果通过以上计算已经发现实时交互界面产生的存储的令牌数大大超过了处理器的消耗,那么放行数据包;如果不是,则需要丢弃数据包。 可能会有人疑惑,为何令牌桶的容量是有限的,而为何最大的容量取名为 ,这其实是因为令牌桶其实是允许在特定的时间窗口内的速率超过限定值。以 300Kpps 限速器为例,假设 等于 300K,并且当前令牌桶是满的,此时,即使 100ms 内来了 300K 个包,那么令牌桶也会放行所有数据包(因为令牌桶的令牌数是够用的),而在100ms 内,实际速率不是 300Kpps,而是 3Mpps。顾名思义,这些令牌桶的容量其实不仅仅是限定了其通常允许的数据库突发请求的速率。 在具体工程实践中,我们遇到了以下三个问题: 1. 精度问题 实际工程实践中,时间计量单位其实是受限于系统,比如时间戳可能是以微秒(us)为单位,而每次计算的时间差可能只有 1~2us。那么一个 PPS=300K 的限速器,可能一次计算,所产生的令牌是 0.3 个,容易被整数运算忽略。最终的结果则是,实际限制为 300K/s,最后效果是只有 250Kpps 流量放行。精度过低,效果不理想。 2. 级联补偿问题 我们在实践中发现,多个限速器级联的时候,需要补偿令牌。比如对于限速器 A,这个包是放行,消耗了 A 的令牌。对于限速器 B,这个包是丢弃,因为 B 没令牌了。此时包被丢了。那么此时 A 的令牌就白白消耗了,即消耗了 token,然后包还是丢了。如果想达到一个准确的限速效果,限速器A的令牌应该被补偿。 3. TCP对丢包敏感问题 令牌桶是没有缓存的,一旦速率超过限定值,则会出现丢包。而 TCP 协议则对丢包非常敏感,一旦出现丢包,TCP 的对速率的调整比较激进。令牌桶这一特性使得他在应用于 TCP 这种流量时,经常会导致限制 100Mbps,实际上最多只能跑到 80Mbps,因为不断的丢包导致 TCP 不断地降低发送窗口。 我们在实践中发现,级联补偿反馈问题虽然存在但不是非常突出,原因是一般级联的限速器的限速值差距很大,比如单网卡的速率和整机速率,一般差距较大,不容易出现精度问题。最严重的问题是 TCP 丢包敏感导致的限速带宽达不到,影响用户体验。由图3所示,随着 TCP RTT 的增加,这个时候实际可以达到的信道带宽通常都会出现明显下降。 反压(backpressure),就是针对 TCP 对丢包敏感这一问题进行的改进。我们在第一次设计的时候,其实针对的是一个特定的场景。既虚机的虚拟网卡进行限速。而且我们的限速器正好是每个网卡有一个特定的限速器。 每个虚拟网卡都有若干队列,vSwitch 会持续的轮询这些队列拿到数据包发出。这些队列本质上其实就是包的缓存区。反压,其实就是停止或者延缓对这些队列的轮询发包,让数据包在队列上堆积,而达到将压力反馈到 Guest Kernel 的目的,这样 Guest Kernel 的 TCP 栈就会感知到拥塞,调整发送的节奏。 如今回过头来看这个设计,和 Peek 相比,其实有好有坏: 1)每次借贷的令牌量,不可控。这会导致公平性问题。大象流会不断的获取借贷资格,而小流则会趋向于饿死,在限速器竞争中,如果一方取得了优势,优势方容易持续获得优势。 2)简单的时间戳比较,开销比 peek 低。如果能够 peek 数据包,就不会有借贷的机制,也就没有停止轮询的可能,而是每次都会去虚拟队列里查看,反而开销有点大。 反压限速器因为反压的是虚机的网卡队列,只能对虚机往外发数据包有限制,而无法限制虚机的收方向的流量。这是因为我们无法反压物理网卡的数据包,物理网卡的数据包可能发往不同的虚拟网卡,每个网卡的限速值是不一样的,我们无法计算出一个确切的时间点,在这个时间点之前可以不用轮询数据包。况且,物理网卡队列满了之后,只会丢包,而虚机网卡队列满了之后,可以反压 TCP 协议栈,两者效果是不一样的。 (编辑:汽车网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐
