KAFKA-20897: Add broker pods and canary partition placement isolation (KIP-1095) - #23095
Open
ericzhifengchen wants to merge 9 commits into
Open
KAFKA-20897: Add broker pods and canary partition placement isolation (KIP-1095)#23095ericzhifengchen wants to merge 9 commits into
ericzhifengchen wants to merge 9 commits into
Conversation
…pec (1/n) Summary: Porting: https://code.uberinternal.com/D16273381 [[ https://docs.google.com/document/d/1UCkCMFyomM0pxVw6iC7MqNtJJHHmPfdQUPhGGtk5MyA/edit?tab=t.0#heading=h.9h4ggmvsh0g5 | Kafka Canary Isolation ERD ]]. The pod concept was introduced in the cluster to group a set of brokers for a specific purpose. In this diff, we are introducing pod as a tagged field in the Kafka proto to unify the response. The custom-uber client can still access the Pod information. With the open-source client, the Pod information won't be propagated. Port: https://code.uberinternal.com/D16273381 Test Plan: UTs Reviewers: #ldap_kafka_admins, #ldap_kafka_core_reviewers, kchandraprakash, yulan Reviewed By: #ldap_kafka_admins, #ldap_kafka_core_reviewers, kchandraprakash, yulan Subscribers: kchandraprakash Tags: #has_java JIRA Issues: DKAFC-5422 Differential Revision: https://code.uberinternal.com/D16483059
Summary: Introduce pod into kafka configuration and broker metadata to represent a kafka sub cluster. Porting: https://code.uberinternal.com/D13108811 Test Plan: UTs Reviewers: #ldap_kafka_admins, #ldap_kafka_core_reviewers, yulan, kchandraprakash Reviewed By: #ldap_kafka_admins, #ldap_kafka_core_reviewers, yulan, kchandraprakash Subscribers: kchandraprakash Tags: #has_java JIRA Issues: DKAFC-5178 Differential Revision: https://code.uberinternal.com/D16484465
Summary: Implement the flow to pass through pod information during broker registration Porting: https://code.uberinternal.com/D13444957 Reviewers: #ldap_kafka_admins, #ldap_kafka_core_reviewers, yulan, kchandraprakash Reviewed By: #ldap_kafka_admins, #ldap_kafka_core_reviewers, yulan, kchandraprakash Tags: #has_java JIRA Issues: DKAFC-5422 Differential Revision: https://code.uberinternal.com/D16487217
Summary: Implementation to support pod value to be propagated to node for the client to be able to see the sub cluster Porting: https://code.uberinternal.com/D13495727 Test Plan: UTs Reviewers: #ldap_kafka_admins, #ldap_kafka_core_reviewers, yulan, kchandraprakash Reviewed By: #ldap_kafka_admins, #ldap_kafka_core_reviewers, yulan, kchandraprakash Subscribers: kchandraprakash Tags: #has_java JIRA Issues: DKAFC-5422 Differential Revision: https://code.uberinternal.com/D16489599
Reviewers: #ldap_kafka_admins, #ldap_kafka_core_reviewers, kchandraprakash Reviewed By: #ldap_kafka_admins, #ldap_kafka_core_reviewers, kchandraprakash Subscribers: kchandraprakash Tags: #has_java JIRA Issues: DKAFC-6702 Differential Revision: https://code.uberinternal.com/D20643021
The canary fraction was configured as a percentage and converted to a partition stride with floor(1/percentage). That conversion is lossy and silently misleading: 0.15 yields an effective 16.7%, and any value above 0.5 collapses to a stride of 1, designating every partition as a canary partition rather than the requested fraction. The reassignment command option had no range validation at all, so a value above 1.0 silently disabled canary placement instead of failing. The percentage was never continuous, since floor(1/p) quantizes every input to some 1/N. Configuring the stride directly expresses exactly the same set of behaviours without the lossy conversion or the unreachable inputs. canary.partition.percentage (double, 0.0-1.0) becomes canary.partition.interval (int, >= 0), and --canary-percentage becomes --canary-interval. Selection semantics are unchanged: partition index i is a canary partition when i % interval == interval - 1, so a topic with fewer partitions than the interval has none.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements the broker-side placement portion of KIP-1095. Adds an optional
broker attribute,
pod, and a replica placement layer that can confine aconfigurable subset of partitions to a single pod.
https://cwiki.apache.org/confluence/display/KAFKA/KIP-1095%3A+Kafka+Canary+Isolation
Motivation
A bad broker deployment can affect any partition hosted on the brokers being
upgraded, and operators have no way to bound that set in advance. Confining a
known fraction of partitions to a designated pod makes the blast radius of a
regression a deployment-time decision rather than an after-the-fact
discovery.
Rack-awareness cannot express this: rack means "spread replicas across these
groups", whereas this requires "confine these partitions to this group".
Changes
Broker pods. New broker config
broker.pod(string, default null),exposed as
AbstractKafkaConfig.pod(). The value travels through brokerregistration into the metadata log and out through
MetadataandDescribeCluster, where it becomesNode.pod(). APodfield is added asa tagged field to four messages, so no message version is bumped:
BrokerRegistrationRequestRegisterBrokerRecordDescribeClusterResponseMetadataResponsePod isolation.
PodReplicaPlacerdecorates the configuredReplicaPlacerwith a map of pod name to a predicate over partition index.A partition matching exactly one rule is placed only on brokers in that pod;
a partition matching none is placed across the pods carrying no rule.
Consecutive partitions resolving to the same broker set are coalesced into a
single
PlacementSpec, so the delegate still sees contiguous ranges and itsstriping and rack-awareness are unchanged.
A broker with no pod belongs to every pod, which allows incremental
adoption. A rule naming a pod with no live brokers is ignored and falls
through to default placement. A partition matching more than one rule raises
IllegalStateExceptionnaming the conflicting pods. A pod smaller than therequested replication factor fails with
InvalidReplicationFactorExceptionrather than spilling replicas outside the pod.
Canary isolation. Two controller configs install the single rule this
KIP configures:
canary.pod.name(defaultcanary-broker) andcanary.partition.interval(int, default 0). With interval N, partitioniis a canary partition when
i % N == N - 1, so a topic with fewer than Npartitions has none. 0 disables the feature.
Tooling.
kafka-reassign-partitions --generateaccepts--canary-nameand
--canary-intervalso that offline plans match controller placement.Without them a reassignment would silently undo isolation on the topics it
moves. This also fixes broker pod being dropped from generated plans when
rack-awareness was disabled.
Compatibility
Off by default. With
canary.partition.intervalat 0 the rule map is emptyand placement is byte-identical to
StripedReplicaPlacer.All protocol additions are tagged, nullable and default to null, so no
message version is bumped and no API version negotiation changes. Older
clients skip the unknown tag. A broker that does not set
broker.podbehaves exactly as it does today.
Note that isolation is only complete once every broker declares a pod, since
an unlabelled broker is eligible for every pod. A partially labelled cluster
is a migration state, not a supported configuration.
Testing
PodReplicaPlacerTest(13 cases): placement with zero, one and multiplepods; pod-less brokers; empty clusters; partition addition to existing
topics; and the overlapping-rule error.
CanarySpecTest(8 cases): interval-to-predicate conversion, including 0,negative, interval 1, and the property that a topic smaller than the
interval has no canary partition.
BrokerRegistrationTest,MetadataCacheTest,ClusterImageBrokersNodeTestand
BrokerLifecycleManagerTest: propagation through registration, themetadata log, the metadata cache and
Node.KafkaConfigTest: the new broker config and validation of the newcontroller config.
ReassignPartitionsUnitTest: generated plans with and without canaryplacement.