Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Quotas are currently configured for client-ids. All clients with the same client-id are currently grouped together as a quota entity, enforcing one quota for all clients with the same client-id. This KIP proposes to define quotas for safe client groups which share the same user-principal and client-id. In a single user cluster, this retains the current semantics of client-id quotas.

Configuration Options

Two new configuration options will be added to specify default producer and consumer quotas for users. The existing default configuration options for client-id quotas will be applied only if default user quota is unlimited.

...

Default quotas for users will be added as dynamic properties.

Changes to existing properties

quota.user.producer.default, quota.user.consumer.default: Default quota for producers/consumers of users without a user quota override. This will be set to unlimited quota (Long.MaxValue) by default.

Changes to existing properties

quota.producer.default, quota.consumer.default: Default client-id producer/consumer quota  is currently applied to each unique client-id across all users. client-id producer/consumer quota  is currently applied to each unique client-id across all users. This will be modified to be a per-user quota for each unique client-id of each user. This client-id default will is applied only if default user quota is unlimited.

Default user quota

Default user quota will be stored in Zookeeper at the top level config for /users. If not specified, user quota will be unlimited. Default user quota can be updated dynamically.

Default configuration

  • All clients have unlimited quota by default
  • If quota.user.producer.default, quota.user.consumer.default are setdefault quotas are configured for users, these default quotas are allocated to each user principal.
  • If quota.user.producer.default, quota.user.consumer.default are default user quota is unlimited, quota.producer.default, quota.consumer.default are allocated to each unique client-id of each user.

...

  • producer_byte_rate : The total rate limit for the user’s producers without a client-id quota override
  • consumer_byte_rate : The total rate limit for the user’s consumers without a client-id quota override

Quotas for clients of a user can be configured by specifying entity types "users" and “clients”  in the same command line . For example, the following command sets quotas for <user2, clientA>:

bin/kafka-configs  --zookeeper localhost:2181 --alter --add-config 'producer_byte_rate=101024,consumer_byte_rate=202048' --entity-name clientA user1 --entity-type clients --entity-name user2 users

Default quotas for users can be configured by omitting entity name.

bin/kafka-configs  --zookeeper localhost:2181 --alter --add-config 'producer_byte_rate=10000,consumer_byte_rate=20000' --entity-type users

The existing entity type "clients" will be retained to set client-id quotas which are used when user quotas are not overridden.

Proposed Changes

User Principal 

Quotas for clients of a user can be configured by specifying entity types "users" and “clients”  in the same command line . For example, the following command sets quotas for <user2, clientA>:

bin/kafka-configs  --zookeeper localhost:2181 --alter --add-config 'producer_byte_rate=10,consumer_byte_rate=20' --entity-name clientA --entity-type clients --entity-name user2 --entity-type users

The existing entity type "clients" will be retained to set client-id quotas which are used when user quotas are not overridden.

Proposed Changes

User Principal 

Authenticated user principal will be obtained from the Session object. URL-encoded Authenticated user principal will be obtained from the Session object. URL-encoded string version of the Principal will be used so that it can be used as a node name in Zookeeper and in metrics without placing any restrictions on the characters allowed in the principal. Characters that cannot be used for Zookeeper node names or metrics (eg. *) will be percent-encoded. Encoded user principal will be cached in Session. For PLAINTEXT, the principal is "ANONYMOUS" by default and quotas will be applied for that principal. But principal can be overridden using a custom principal builder even for PLAINTEXT, enabling different user quotas, for example, for connections from different IP addresses.

...

  1. If quota override is defined for <userN, clientX> this quota is allocated for the sole use of <userN, clientX>.
  2. If user quota override is defined for userN, clientX shares this quota with other clients of userN
  3. If quota.user.producer.default is not default user quota is unlimited, clientX shares this default quota with other clients of userN
  4. If client-id quota override is defined for clientX, this quota is allocated for the sole use of <userN, clientX>
  5. If quota.producer.default is configured, this default quota is allocated for the sole use of <userN, clientX>
  6. Client is not throttled

Use cases:

  • Simple client-id based quotas are configured using client-id quota override and quota.producer.default : (steps 4, 5, 6)
  • Simple user-principal based quotas are configured using user quota override and quota.user.producer.default : (steps 2, 3, 6)
  • More specific <user, client-id> quotas and defaults for users and client-ids can be configured if required: (steps 1 - 6)

...

cases:

  • Simple client-id based quotas are configured using client-id quota override and quota.producer.default : (steps 4, 5, 6)
  • Simple user-principal based quotas are configured using user quota override and user quota default : (steps 2, 3, 6)
  • More specific <user, client-id> quotas and defaults for users and client-ids can be configured if required: (steps 1 - 6)
Code Block
languagejava
titleSample configuration: Default user quota
// Default user quota
// Zookeeper persistence path /users
{
    "version":1,
    "config": {
        "producer_byte_rate":"10000",
        "consumer_byte_rate":"20000"
    }
}

Code Block
languagejava
titleSample configuration: User quota without client-id overrides
// Quotas for user1 (without client-id overrides).
// Zookeeper persistence path /users/<encoded-user1>
{
    "version":1,
    "config": {
        "producer_byte_rate":"1024",
        "consumer_byte_rate":"2048"
    }
}

...

  1. Total rate limits for all clients with user principal user1 is (1024, 2048).
  2. Total rate limits for all clients with user principal user2 without additional client-id quota is (4096, 8192).
    • The rate limits for clients with user principal user2 AND client-id clientA is (10, 20).
    • Clients of user2 with client-id other than clientA and clientB share the quota (4096, 8192).
  3. Total rate limits for all clients of user3  is (quota.user.producer.default, quota.user.consumer.default) configured in server.propertiesthe default (10000, 20000), since no config override is specified.
  4. If default user quota quota is not specified or is unlimited, clients of user3 use client-id quota configuration. For example quota for client-id clientA of user3 is (100, 200). And quota for client-id clientB of user3 without a client-id override is (quota.producer.default, quota.consumer.default)
    • In a single-user cluster, this provides the same semantics as the current client-id implementation
    • In a multi-user cluster,  quotas are now per-user, treating clientA of user4 as a different group from clientA of user2.

...

Client-id based quota configuration overrides will continue be stored under /config/clients, but these will be applied only to clients of users without a quota override and only if default user quota is unlimited. Quota configuration overrides for user principals will be stored under /config/users/<user>. Note that url-encoded version of the user principal will be used as node name under /config/users to cope with Zookeeper naming restrictions. Default user quotas will be stored under /config/users. Quota overrides for clients of a user will be stored under /config/users/<user>/clients.

Configuration change notifications will be generated for changes to quota configuration similar to the current notifications for client-id quotas. JSON for change notification will be modified to provide entity path instead of specifying entity type and name separately.

Code Block
languagejava
titleSample configuration change notification
java
titleSample configuration change notification
// Change notification for default user quota
{
    "version":2,
    "entity_path": "users"
}
// Change notification for user quota of user1
{
    "version":2,
    "entity_path": "users/user1"
}
// Change notification for quota of <user2, clientA>
{
    "version":2,
    "entity_path": "users/user2/clients/clientA"
}
// Change notification for client-id quota of clientA
{
    "version":2,
    "entity_path": "clients/clientA"
}

...

kafka-configs.sh will be extended to support a new entity type "users". Quota configuration for users will be provided as key-value pairs to be consistent with other configuration options. Hence no new command line arguments will be added to the tool. The tool will parse the key-value pairs specifying rate limits, validate these and convert them to the equivalent JSON for persistence in Zookeeper. The existing entity “clients” will continue to be supported to set client-id quotas for users with unlimited quota. The tool will be extended to accept multiple entity types to configure <user, client-id> quotas. The tool will also be updated to configure default user quotas at the top-level (/users).

Compatibility, Deprecation, and Migration Plan

...