k8s-client限流&令牌桶算法 | 豆包MarsCode AI刷题

359 阅读4分钟

问题背景

在使用go-client希望查询创建的pod状态的时候,如果点击的频率比较高,会出现如下的报错:

Waited for 1.072567972s due to client-side throttling, not priority and fairness, request: GET:<(url)>

问题排查

查询了相关的文章了解到

为了防止突发流量影响apiserver可用性,k8s支持多种限流配置,其中就有client限流。

相关的配置代码如下:

type Config struct {
...
// QPS indicates the maximum QPS to the master from this client.
// If it's zero, the created RESTClient will use DefaultQPS: 5
QPS float32

// Maximum burst for throttle.
// If it's zero, the created RESTClient will use DefaultBurst: 10.
Burst int

// Rate limiter for limiting connections to the master from this client. If present 
// overwrites QPS/Burst
RateLimiter flowcontrol.RateLimiter
...
}

在配置中的QPS字段为master的最大QPS,未设置的话就使用默认QPS为5。

Burst字段表示限流的最大突发量,未设置的话就使用默认Burst为10。

RateLimiter字段用于限制从客户端到master的连接,会覆盖QPS和Burst的值。

解决方法

直接设置RateLimiter字段,同时设置QPS和Burst的值,设置的源代码如下。

// NewTokenBucketRateLimiter creates a rate limiter which implements a token bucket approach.
// The rate limiter allows bursts of up to 'burst' to exceed the QPS, while still maintaining a
// smoothed qps rate of 'qps'.
// The bucket is initially filled with 'burst' tokens, and refills at a rate of 'qps'.
// The maximum number of tokens in the bucket is capped at 'burst'.
func NewTokenBucketRateLimiter(qps float32, burst int) RateLimiter {
	limiter := rate.NewLimiter(rate.Limit(qps), burst)
	return newTokenBucketRateLimiterWithClock(limiter, clock.RealClock{}, qps)
}

NewTokenBucketRateLimiter 创建一个使用令牌桶算法的速率限制器。

该速率限制器允许在不超过 'burst' 的情况下短暂超过 QPS,同时仍然保持平滑的 QPS 速率为 'qps'。

桶最初填充了 'burst' 个令牌,并以 'qps' 的速率重新填充。

桶中的令牌数量上限为 'burst'。

参考文章

k8s clientset 出现 Throttling request took 限流的解决方法-CSDN博客

k8s API限流——server级别整体限流和客户端限流_kubernetes apiserver 限流配置-CSDN博客

拓展-限流算法

漏桶算法

漏桶算法(Leaky Bucket Algorithm)是一种流量控制算法,常用于网络流量整形和限速。它通过模拟一个带有固定排水速度的漏桶来限制数据流的速度。

请求先进入到漏桶里,漏桶以一定的速度出水,当水流入速度过大会直接溢出,可以看出漏桶算法能强行限制数据的传输速率。

image.png

假设漏桶的容量为10个数据包,流出速度为每秒1个数据包。

  • 正常情况下:如果数据包以每秒1个的速度流入,漏桶中的数据包数量始终保持在1个,不会发生溢出。
  • 流入速度过快:如果数据包以每秒5个的速度流入,漏桶中的数据包数量会迅速增加。当漏桶中的数据包数量达到10个时,再有新的数据包到达就会被丢弃,因为漏桶已经满了。

令牌桶算法

令牌桶算法(Token Bucket Algorithm)是一种常用的流量控制和限速算法,广泛应用于网络流量管理、API限流、消息队列等领域。它通过模拟一个可以容纳一定数量令牌的桶,以固定的速率向桶中添加令牌,从而实现对数据流的控制。

image.png

假设令牌桶的容量为100个令牌,令牌生成速率为每秒10个令牌。

  • 正常情况下:如果数据包的发送速率低于每秒10个,令牌桶中的令牌数量会逐渐增加,但不会超过100个。
  • 突发流量:如果数据包的发送速率突然增加到每秒20个,前几秒钟由于有足够的令牌,数据包可以顺利发送。但随着令牌数量减少,数据包发送速率将被迫降低到每秒10个,因为这是令牌生成的速率。
  • 令牌溢出:如果系统长时间没有数据包发送,令牌桶中的令牌数量可能达到100个。此时,即使令牌生成速率保持不变,多余生成的令牌也将被丢弃。

burst表示令牌桶的大小,QPS表示1s可以产生多少令牌。最多一秒内可以有(burst+QPS)个请求可以拿到令牌(令牌桶burst个+这1秒内新产生的QPS个),但不表示每秒都能有(burst+QPS)个请求能拿到令牌。