kafka支持配額管理,從而可以對Producer和Consumer的produce&fetch操作進行流量限制,防止個別業務壓爆服務器。本文主要介紹如何使用kafka的配額管理功能。
1 Kafka Quatas簡介
Kafka配額管理所能配置的對象(或者說粒度)有3種:
user + clientid
user
clientid
這3種都是對接入的client的身份進行的認定方式。其中,
- clientid是每個接入kafka集群的client的一個身份標志,在ProduceRequest和FetchRequest中都需要帶上;
- user只有在開啟了身份認證的kafka集群才有。
如果kafka集群沒有開啟身份認證,則只能使用clientid方式來進行限流。
可配置的選項包括:
- producer_byte_rate。發布者單位時間(每秒)內可以發布到單台broker的字節數。
- consumer_byte_rate。消費者單位時間(每秒)內可以從單台broker拉取的字節數。
2 如何配置
可以通過兩種方式來作配額管理:
- 在配置文件中指定所有client-id的統一配額。
- 動態修改zookeeper中相關znode的值,可以配置指定client-id的配額。
使用第一種方式,必須重啟broker,而且還不能針對特定client-id設置。所以,推薦大家使用第二種方式。
2.1 使用官方腳本修改配額
kafka官方的二進制包中,包含了一個腳本bin/kafka-configs.sh,支持針對user,client-id,(user,client-id)等三種緯度設置配額(也是通過修改zk來實現的)。
#1. 配置user+clientid。例如,user為”user1”,clientid為”clientA”。 bin/kafka-configs.sh --zookeeper localhost:2181 --alter --add-config 'producer_byte_rate=1024,consumer_byte_rate=2048' \ --entity-type users --entity-name user1 --entity-type clients --entity-name clientA #2. 配置user。例如,user為”user1” bin/kafka-configs.sh --zookeeper localhost:2181 --alter --add-config 'producer_byte_rate=1024,consumer_byte_rate=2048' \ --entity-type users --entity-name user1 #3. 配置client-id。例如,client-id為”clientA” bin/kafka-configs.sh --zookeeper localhost:2181 --alter --add-config 'producer_byte_rate=1024,consumer_byte_rate=2048' \ --entity-type clients --entity-name clientA
2.2 直接寫zk來修改配額
假定我們在啟動kafka時指定的zookeeper目錄是kafka_rootdir
#1. 配置user+clientid。例如,針對”user1”,”clientA”的配額是10MB/sec,其它clientid的默認配額是5MB/sec。 znode: ${kafka_rootdir}/config/users/user1/clients/clientid; value: {"version":1,"config":{"producer_byte_rate":"10485760","consumer_byte_rate":"10485760"}} znode: {kafka_rootdir}/config/users/user1/clients/<default>; value: {"version":1,"config":{"producer_byte_rate":"5242880","consumer_byte_rate":"5242880"}} #2. 配置user。例如,”user2”的配額是1MB/sec,其它user的默認配額是5MB/sec。 znode: ${kafka_rootdir}/config/users/user1; value: {"version":1,"config":{"producer_byte_rate":"1048576","consumer_byte_rate":"1048576"}} znode: ${kafka_rootdir/config/users/<default>; value: {"version":1,"config":{"producer_byte_rate":"5242880","consumer_byte_rate":"5242880"}} #3. 配置client-id。例如,”clientB”的配額是2MB/sec,其它clientid的默認配額是1MB/sec。 znode:${kafka_rootdir}/config/clients/clientB'; value:{“version”:1,”config”:{“producer_byte_rate”:”2097152”,”consumer_byte_rate”:”2097152”}}</li> znode:${kafka_rootdir}/config/clients/; value:{“version”:1,”config”:{“producer_byte_rate”:”1048576”,”consumer_byte_rate”:”1048576”}}`
3 優先級
首先,我們需要明白,kafka在管理配額的時候,是以“組”的概念來管理的。而管理的對象,則是producer或consumer到broker的一條條的TCP連接。
那么在進行額度管理的時候,kafka首先需要確認,這條連接屬於哪個“組”,進而確定當前連接是否超過了所屬“組”的總額度。
在進行“組”判定的時候,依照以下的優先級順序依次判定:
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>
一旦找到了符合的“組”,即中止判定過程。
4 超額處理
如果連接超過了配額值會怎么樣呢?kafka給出的處理方式是:延時回復給業務方,不使用特定返回碼。
具體到producer還是consumer,處理方式又有所不同:
- Producer:如果Producer超額了,先把數據append到log文件,再計算延時時間,並在ProduceResponse的ThrottleTime字段填上延時的時間(v2,只在0.10.0版本以上支持)。
- Consumer:如果Consumer超額了,先計算延時時間,在延時到期后再去從log讀取數據並返回給Consumer。否則無法起到限制對文件系統的讀蜂擁。在v1(0.9.0以上版本)和v2版本的FetchResponse中有ThrottleTime字段,表示因為超過配額而延時了多久