kafka的客户端限流(资源配额)

本文详细介绍了Kafka客户端的限流机制,包括带宽和请求速率的配额设置,以及基于(user,client-id)的分类和配置优先级。重点讲解了如何通过Zookeeper进行配置,并提供了实用的命令行操作示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

本文说明的是Kafka的客户端(生产者、消费者)与broker之前的限流,不是kafka的broker间topic副本同步的限流。

客户端限流

在kafka的官方文档,不叫限流,叫做资源配额:通过对客户端请求进行配额,控制集群资源的使用。

主要支持以下两种类型:

  1. 带宽 (从 0.9 版本开始)
  2. 请求速率 (从 0.11 版本开始)

带宽就是基于每秒传输多少个字节来进行限制;但是,注意,请求速率并不是每秒客户端可以发起多少个请求,而是网络和 I/O线程 cpu利用率的百分比。

规则

kafka 客户端以“组”来进行配额限流。同组下的所有客户端共享带宽配置,比如:配置带宽10M/秒,则该组所有客户端限制总带宽使用为10M每秒;但是请求速率指的是每个组的client 使用broker上的cpu的百分比。

组的分类规则如下:

  • (user, client-id)
  • user
  • client-id 

client-id: 客户端ID,这个比较熟悉,比如在启动一个消费者的时候,配置的一个属性:

        // client.id
        props.put(ConsumerConfig.CLIENT_ID_CONFIG, "test-consumer-id");

 如果不配置,会生成一个默认的:

User需要是开启ACL之后的一个用户主体标识,很多同学如果没用过kafka的ACL,可能对这个不太了解,可以看下这个:kafka快速配置启用ACL示例_不识君的荒漠的博客-CSDN博客_kafka-acls.sh --bootstrap-server 

而(user, client-id)这个二元组,就是需要同时指定用户主体标识和客户端ID作为一组分类。

配置位置与优先级

我目前查看官方3.3的文档 Kafka 3.3 Documentation这些配置信息还是在zookeeper上:

  1. /config/users/<user>/clients/<client-id>
  2. /config/users/<user>/clients/<default>
  3. /config/users/<user>
  4. /config/users/<default>/clients/<client-id>
  5. /config/users/<default>/clients/<default>
  6. /config/users/<default>
  7. /config/clients/<client-id>
  8. /config/clients/<default>

数字越小,优先级越高。

注意:支持broker级别的配置,但是未验证(我目前用来测试的版本是2.8)。

命令

1. 基于(user, client-id)限流配置

sh bin/kafka-configs.sh  --bootstrap-server localhost:9092 --describe --entity-type users --entity-name userName --entity-type clients --entity-name clientId

2. 指定用户

sh bin/kafka-configs.sh  --bootstrap-server localhost:9092 --describe --entity-type users --entity-name userName

3. 用户级默认配置

sh bin/kafka-configs.sh  --bootstrap-server localhost:9092 --alter --add-config 'producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200' --entity-type users --entity-default

4. 指定客户端ID

sh bin/kafka-configs.sh  --bootstrap-server localhost:9092 --alter --add-config 'producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200' --entity-type clients --entity-name clientId

5. 客户端ID级默认配置

sh bin/kafka-configs.sh  --bootstrap-server localhost:9092 --alter --add-config 'producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200' --entity-type clients --entity-default

6. (user, client-id)级默认配置

sh bin/kafka-configs.sh  --bootstrap-server localhost:9092 --alter --add-config 'producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200' --entity-type users --entity-name userName --entity-type clients --entity-default

7. 查看(user, client-id)级配置

sh bin/kafka-configs.sh  --bootstrap-server localhost:9092 --describe --entity-type users --entity-name userName --entity-type clients --entity-name clientId

8. 查看用户级配置

sh bin/kafka-configs.sh  --bootstrap-server localhost:9092 --describe --entity-type users --entity-name userName

如果不指定--entity-name,则是查看所有用户 

9. 查看客户端ID级配置

sh bin/kafka-configs.sh  --bootstrap-server localhost:9092 --describe --entity-type clients --entity-name clientId

如果不指定--entity-name,则是查看所有客户端ID的配置 

注意:

  1. producer_byte_rate=1024,consumer_byte_rate=2048,request_percentage=200三项并不是都需要配置,按需要配置
  2. 查看配置的时候,对于同一个客户端ID,既在客户端ID级别配置了,又在(user, client-id)级配置,查看的时候,也是分开查看。(user, client-id)级配置只能看到(user, client-id)级的配置。客户端ID级别配置只能看到客户端ID级别配置。

官方文档(中文版)

推荐查看:

Kafka 中文文档 - ApacheCN

### 使用Kafka限流工具的方法 为了控制消息生产和消费的速度,防止某些生产者或消费者占用过多资源Kafka提供了多种方式来实现流量控制。通过配置参数可以有效地管理客户端请求速率以及数据传输量。 #### 配置生产者的发送速率限制 可以通过设置`linger.ms`和`batch.size`这两个属性来间接影响生产者端的消息发送频率。前者决定了批处理等待时间,后者则指定了每批次的最大字节数。适当调整这两项能够有效减少网络I/O次数并平滑峰值负载[^1]。 对于更精确的速率控制,还可以利用配额机制(Quotas),它允许管理员为不同类型的客户端设定独立的数据吞吐上限: - `producer_byte_rate`: 生产者每秒可上传的最大字节数; - `consumer_byte_rate`: 消费者每秒能下载的最大字节数。 这些阈值可以在服务器端全局定义,也可以针对特定主题或者用户自定义。当某个实体超过其分配额度时,后续操作将会被延迟执行直到有足够的剩余空间为止[^4]。 #### 应用层面上的应用程序逻辑限流 除了依赖于内置功能外,在应用层面加入额外的业务规则也是一种常见的做法。例如,在编写Spark Streaming应用程序读取来自Kafka的数据时,可以选择采用`DirectKafkaInputDStream`模式,并结合窗口函数或其他聚合运算符来进行批量处理,从而达到自然节流的效果[^2]。 另外,如果是在开发基于Kafka Streams框架构建的服务,则可以直接调用API中的相应方法完成类似的任务。比如下面这段Java代码展示了如何创建一个简单的单词计数器的同时实现了基本的输入输出速度调控[^3]: ```java StreamsBuilder builder = new StreamsBuilder(); builder.stream("input-topic") .peek((key, value) -> System.out.println(key + " => " + value)) .groupByKey() .count(Materialized.as("counts-store")) .toStream() .foreach((word, count) -> { try { Thread.sleep(10); } catch (InterruptedException e) {} System.out.println(word + ": " + count); }); ``` 此示例中加入了短暂休眠以模拟实际场景下的延时效果,当然这并不是推荐的最佳实践;真实环境中应当考虑更加优雅的方式如背压支持等特性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不识君的荒漠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值