kafka配额研究

配额

相关介绍:

Kafka自0.9.0.0版本引入了配额管理(quota management),旨在broker端对clients发送请求进行限流(throttling)。目前Kafka支持两大类配额管理:

网络带宽(network bandwidth)配额管理:定义带宽阈值来限制请求发送速率,阈值单位是字节/秒,即bytes/s。该功能是0.9.0.0版本引入的
CPU配额管理:定义CPU使用率阈值来限制请求发送速率,阈值以百分比的形式给出,如quota = 50表示50%的CPU使用率上限。该功能是0.11.0.0版本引入的

Kafka管理平台做的配额应该需要做网络带宽的配额。

一、配额能做什么?

设置了基于带宽的配额之后,Kafka能够做到:

  1. 限制follower副本拉取leader副本消息的速率(此项优先级低,而且不是很好判定是否需要限速,producer和consumer迫切需求,有明确的TPS)
  2. 限制producer的生产速率
  3. 限制consumer的消费速率
二、配额作用域

目前可以在3个层级上设置配额:

  1. client id(主要考虑clientid的配额)
  2. user (为启用认证之后位于认证体系中的某个用户主体,kafka管理平台没有做这方面的认证,不考虑)
  3. user + client id
三、如何设置?

我们根据第一小节中提到的3种功能来分别讨论。

3.1 限制producer端速率

方法1: 设置broker端静态参数quota.producer.default参数

比如:在server.properties中加入quota.producer.default=15728640将限制所有连入该broker的producer的TPS全部降到15MB/s以下。设置此参数的好处是能够限制集群上的所有producer,但劣处也在于此,对所有producer“一视同仁”,无法细粒度地对个别clients进行设置。(社区在0.11.0.0版本将其标记为"Deprecated",还是用动态的比较稳妥)

方法2:设置动态参数producer_byte_rate

首先演示为所有client id设置默认值,假设我们为所有producer程序设置其TPS不超过20MB/s,即20971520B/s,命令如下:

bin/kafka-configs.sh --zookeeper localhost:2181 --alter --add-config 'producer_byte_rate=20971520' --entity-type clients --entity-default
Completed Updating config for entity: default client-id.

然后我们为client.id=‘producer-1'的producer单独设置其TPS不超过10MB/s,即10485760B/s,命令如下:

四、如何实现配额

主要就是在broker端执行的,broker端故意“sleep”来实现的限速。

配额算法:
简单来说,我们假设当前实际值是O,T是我们设置的阈值,而W表示某一段时间范围,我们希望在W时间内O能够下降到T以下(如果O本来就比T小,则什么都不用做),那么broker端就需要延缓等待一段时间。如果假设这段时间是X,那么以下等式成立:

O * W = (W + X) * T

由此得出X = (O - T) / T * W。这就是Kafka用于计算等待时间的公式。当然在具体实现时,Kafka提供了两个参数来共同计算W:W = quota.window.num * quota.window.size.seconds。前者表示取样的时间窗口个数,后者表示时间窗口大小。
当Kafka检测到配额透支情况发生时,broker不会返回错误而是直接将超支配额的客户端进行减速处理。它会计算需要X然后令client强制sleep直至令其降到配额之下。

五、KAFKA管理平台的配额

现在我们系统是有1.0和0.8两个版本,1.0是有配额功能的,0.8.2需要额外实现,看了下0.9版本上配额的需求和代码PR(基本满足网络带宽限速的要求,后面的KIP都是一些CPU以及用户相关的配额)
kafka配额初始需求说明:https://cwiki.apache.org/confluence/display/KAFKA/KIP-13+-+Quotas
其他KIP:
https://cwiki.apache.org/confluence/display/KAFKA/KIP-55%3A+Secure+Quotas+for+Authenticated+Users(用户配额,在0.10.1.0版本中提交)
https://cwiki.apache.org/confluence/display/KAFKA/KIP-73+Replication+Quotas(副本拉取配额,在0.10.1.0版本中提交)
https://cwiki.apache.org/confluence/display/KAFKA/KIP-124+-+Request+rate+quotas(按请求率进行配额,改动量非常大..每个Response都增加了throttle_time_ms,在0.11.0.0版本中提交)
kafka配额在0.9版本的代码pr:https://reviews.apache.org/r/33049/diff/28#11

大体流程:

平台上监控各个client的速率(有clientId、速率、Tps)————> 判断是否需要配额————>页面增加配额(区分0.8.2&1.0 对该clientId进行配额控制)————>配额生效、监控体现

配额的流程以及考虑的点:
  1. kafka服务端需要支持配额功能(1.0是支持的,0.8.2需要额外实现)
  2. 检测到客户端的流量监控,根据TPS判断是否需要进行限速(如何拿到客户端的流量速率?)
  3. 页面控制-对需要限速的客户端进行配额(配额需要clientId,怎么拿到这个clientId??很多客户端都用的默认clientId)
  4. 对配额后的客户端流量进行监控,是否配额成功(还是监控的问题,需要拿到客户端的流量速率)
考虑的点:
  1. 0.8.2没有配额功能,怎么办?
    rebase0.9的代码到0.8.2,应该可以解决,还没调通....https://reviews.apache.org/r/33049/diff/28#11
  2. 如何拿到客户端的流量速率?
    流量速率只能在客户端的JMX中拿到...感觉需要对我们提供给外面的kafka_common_client进行二次开发才行,定时任务把流量速率发到单独的topic中,管理平台拿到这部分数据进行分析比对
  3. 配额需要clientId,怎么拿到这个clientId??很多客户端都用的默认clientId
    kafka_common_client中定死这个clientid,暂定producer+topic+system+uuid(还要保证不能重复,重启后能不能变?不能变的话还需要想个好的唯一值);同名的clientId会共享配额,不用担心用户new很多个client
    ps:因为这个clientId不固定,而且服务端也没法取到client的速率等监控数据,还是改动kafka_common_client可能更好点,
  4. 怎么判断需不需要配额,配额有没有成功?
    平台开发一个配额页面,监控所有用kafka_common_client的client的速率,根据TPS判断是否需要配额,以及页面可以动态修改配额

你可能感兴趣的:(kafka配额研究)