硕大的汤姆

硕大的汤姆

The official website of Minhua Chen

22 Oct 2020

限流与过载保护

过载保护

微信的这篇论文有个很好的介绍

过载控制往往需要对不同的服务进行专门设计,但是这种过于细致的过载控制对于整个系统来说是不利的,开发者很难估计每个服务应该可以承受的负载。

为此,微信采用了一种名为 DAGOR 的过载控制设计,在 service 粒度上管理过载,使得每个微服务的负载能被实时监控。

由于服务之间复杂的依赖关系,比如一个请求依赖 k 个服务,而这些服务都有 p 的概率拒绝服务,那么这个请求成功的概率就是 (1-p)^k。如果 k 比较大的话,服务的 sla 会明显下降。

DAGOR

DAGOR 的基本机制是:当请求到达时,为其分配一个业务优先级和红黑优先级,根据这个优先级使得它下游的服务可以强制接受或者拒绝这个请求。每个服务都有一个自己的优先级阈值,并根据其检测到的当前负载情况调整阈值。

过载检测

另一个问题是,服务如何判断自己是否处于过载状态?DAGOR 采用等待队列里的平均等待时间(简称排队时间(queuing time))来检测负载状况。

排队时间 = 请求开始被处理的时刻 - 请求到达此服务的时刻。

为什么不用 response time 或者 cpu 利用率 来检测负载情况呢?

  • 对于一个服务来说,responese time 不止收到其自身处理请求速度(自身负载)的影响,也受下游服务处理时间的影响。
  • cpu 利用率即使很高,但如果请求能被及时处理,我们也不应该认为服务进入过载状态。
  • 而 queuing time 则仅受本服务处理能力的影响。如果一个服务有足够的资源来处理请求,queuing time 就会很小,及时下游返回慢,本服务 queuing time 也不会被影响。

DAGOR 的过载检测是基于窗口的,比如在微信系统中,每秒或者每 2000 个请求,server 就会刷新它的监控状态。微信中平均的 queuing time 阈值为 20ms,超过了就意味着服务过载了。

限流

单实例限流

简单的令牌桶就可以实现,可以基于 mesh 实现,或者基于服务框架实现。

分布式限流

  • 常规手段还是使用 redis 计数,但是由于热 key 的问题,一般只适合于 qps 有限(小于 1w)的场景。
  • 如果是高 qps 场景,通常都不需要精准限流,可以考虑退化到单实例限流模式。
  • 如果是高 qps 并且需要精确限流,方案比较复杂。
key = fmt.Sprintf("%s%d", key, time.Now().Unix())

自适应限流(出口流量治理优化)

解决突发流量打挂下游服务,甚至存储服务的问题。起到保护下游,熔断下游以隔离故障的作用。

BBR 算法的目标是寻找当前系统同时具备 最大吞吐量和最低时延 的工作点,将流量发送速率控制在这个工作点附近。

https://medium.com/google-cloud/tcp-bbr-magic-dust-for-network-performance-57a5f1ccf437

BBR

https://network.51cto.com/article/685201.html

慢启动,就是对刚启动的网络连接,发送速度是试探性增长。当达到慢启动阈值后,不再指数性增长,而是进入拥塞避免阶段。

TCP BBR(Bottleneck Bandwidth and Round-trip propagation time)是由 Google 设计,并于 2016 年发布的拥塞算法,以往大部分拥塞算法是基于丢包来作为降低传输速率的信号,而 BBR 基于模型主动探测。

该算法认为随着网络接口控制器逐渐进入千兆速度时,分组丢失不应该被认为是识别拥塞的主要决定因素,所以基于模型的拥塞控制算法能有更高的吞吐量和更低的延迟,可以用 BBR 来替代其他流行的拥塞算法例如 CUBIC。Google 在 YouTube 上应用该算法,将全球平均的 YouTube 网络吞吐量提高了 4%,在一些国家超过了 14%。BBR 之后移植入 Linux 内核 4.9 版本,并且对于 QUIC 可用。

BDP 是 Bandwidth-Delay Product 的缩写,可以翻译为带宽延时积,我们知道带宽的单位是 bps(bit per second),延时的单位是 s,这样 BDP 的量纲单位就是 bit,从而我们知道 BDP 就是衡量一段时间内链路的数据量的指标。这个可以形象理解为水管灌水问题,带宽就是水管的水流速度立方米/s,延时就是灌水时间单位 s,二者乘积我们就可以知道当前水管内存储的水量了,这是 BBR 算法的一个关键指标。

我们把具有长 RTT 往返时间和高带宽的网络成为长肥网络或者长肥管道,它的带宽延时积 BDP 很大大,这种网络理论上吞吐量很大也是研究的重点。

可以简单地理解 TCP Pacing 机制就是将拥塞控制中数据包的做平滑发送处理,避免数据的突发降低网络抖动。

BBR 算法的一些思想在之前的基于延时的拥塞控制算法中也有出现,其中必有有名的是 TCP WestWood 算法。

TCP Westwood 改良自 New Reno,不同于以往其他拥塞控制算法使用丢失来测量,其通过对确认包测量来确定一个合适的发送速度,并以此调整拥塞窗口和慢启动阈值。其改良了慢启动阶段算法为敏捷探测和设计了一种持续探测拥塞窗口的方法来控制进入敏捷探测,使链接尽可能地使用更多的带宽。

TCP WestWood 算法也是基于带宽和延时乘积进行设计的,但是带宽和延时两个指标无法同时测量,因为这两个值是有些矛盾的极值,要测量最大带宽就要发送最大的数据量但是此时的 RTT 可能会很大,如果要测量最小的 RTT 那么久意味着数据量非常少最大带宽就无法获得。

TCP BBR 算法采用交替采样测量两个指标,取一段时间内的带宽极大值和延时极小值作为估计值,具体的实现本文就不展开了。

BBR 算法和 CUBIC 算法类似,也同样有几个过程:StartUp、Drain、Probe_BW、Probe_RTT,来看下这几个状态的迁移情况