client-go 的 QPS 和 Burst 限速

1. 什么是 QPS 和 Burst ?

在 kubernetes client-go 中,QPS 和 Burst 是用于控制客户端与 Kubernetes API 交互速率的两个关键参数:

QPS (Queries Per Second)

定义:表示每秒允许发送的请求数量,即限速器的平滑速率。

用途:用来控制客户端与 API Server 的持续请求速率。

场景:适用于需要长时间维持均匀的 API 调用的情况。

Burst

定义:表示瞬时允许发送的最大请求数量,即限速器的突发容量。

用途:允许在短时间内发送的请求数量上限,适用于突发性调用场景。

场景:例如,客户端初始化时,需要快速获取大量资源。

2. 实验验证

可以通过编写代码,发送大量 API 请求来验证 QPS 和 Burst 的行为。以下是一个实验示例:

go 复制代码
package main

import (
	"context"
	"flag"
	"fmt"
	"log"
	"sync"
	"time"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
)

func main() {
	// 加载 kubeconfig
	kubeconfig := flag.String("kubeconfig", "~/.kube/config", "Path to kubeconfig file")
	flag.Parse()
	config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
	if err != nil {
		log.Fatalf("Failed to load kubeconfig: %v", err)
	}

	// 设置 QPS 和 Burst
	config.QPS = 5.0  // 每秒 5 个请求,也是默认设置
	config.Burst = 10 // 突发允许 10 个请求,也是默认设置

	// 创建客户端
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		log.Fatalf("Failed to create clientset: %v", err)
	}

	// 统计开始时间
	startTime := time.Now()

	// 使用 WaitGroup 追踪请求完成
	var wg sync.WaitGroup
	totalRequests := 50
	wg.Add(totalRequests)

	// 发送大量请求
	for i := 0; i < totalRequests; i++ {
		go func(i int) {
			defer wg.Done()
			_, err := clientset.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{})
			if err != nil {
				log.Printf("Request %d failed: %v", i, err)
			} else {
				log.Printf("Request %d succeeded", i)
			}
		}(i)
	}

	wg.Wait()
	fmt.Printf("Total time taken: %v\n", time.Since(startTime))
}

配置 QPS 和 Burst:

设置 QPS = 5,表示每秒最多发送 5 个请求。

设置 Burst = 10,允许在瞬时突发时最多发送 10 个请求。

当发生客户端限流时,会出现类似如下输出:

sh 复制代码
2025/01/10 15:01:50 Request 32 succeeded
I0110 15:01:50.468917    3083 request.go:729] Waited for 1.19372275s due to client-side throttling, not priority and fairness, request: GET:https://127.0.0.1:63092/api/v1/pods
2025/01/10 15:01:50 Request 33 succeeded

当发生客户端限流时,请求排队,实际完成时间会被延长。

实验结果:

当设置 QPS = 5,Burst = 10 时,请求全部成功,完成耗时 8s

当设置 QPS = 1,Burst = 2 时,请求全部成功,完成耗时 48s

调整建议

如果需要高频请求,可适当增大 QPS 和 Burst,避免客户端过度限流。

同时,合理设置参数,可以避免客户端过高的并发负载影响集群稳定性。

源码机制

client-go 使用令牌桶进行速率限制,桶容量为 burst 大小,按照每秒生成 QPS 个令牌的速率产生令牌(不会实际启动协程生成令牌,而是根据时钟计算),只有拿到令牌才能请求 kube-apiserver,如下图所示:

reference: client-go QPS、Burst和令牌桶

相关推荐
Kendra9195 小时前
Kubernetes 常用命令
云原生·容器·kubernetes
2501_9399090514 小时前
k8s基础与安装部署
云原生·容器·kubernetes
谷隐凡二14 小时前
Kubernetes Route控制器简单介绍
java·容器·kubernetes
李少兄19 小时前
Kubernetes 日志管理
docker·容器·kubernetes
秋饼19 小时前
【K8S测试程序--git地址】
git·容器·kubernetes
oMcLin19 小时前
如何在RHEL 9上配置并优化Kubernetes 1.23高可用集群,提升大规模容器化应用的自动化部署与管理?
kubernetes·自动化·php
ghostwritten20 小时前
Kubernetes 网络模式深入解析?
网络·容器·kubernetes
原神启动120 小时前
K8S(七)—— Kubernetes Pod 基础概念与实战配置
云原生·容器·kubernetes
不想画图21 小时前
Kubernetes(五)——rancher部署和Pod详解
linux·kubernetes·rancher
大都督老师21 小时前
配置 containerd 使用镜像加速器拉取 Docker Hub 镜像
容器·kubernetes·k8s