Status

Current state: "Under Discussion"

Discussion thread: here

JIRA: KAFKA-19577

Please keep the discussion on the mailing list rather than commenting on the wiki (wiki discussions get unwieldy fast).

Motivation

Partition replicas placement is a important topic in Kafka. Depending on different use cases, users may prefer different placement strategies. Currently, Kafka uses the default StripedReplicaPlacer, which implement round-robin algorithm to distribute replicas. This approach works well for the majority of scenarios.

However, there are still special cases—such as internal testing or experimental features—where users may want to define a custom placement strategy. Therefore, we propose providing a mechanism that allows users to implement their own ReplicaPlacer.

Previously, KIP-660: Pluggable ReplicaPlacer proposed making the ReplicaPlacer pluggable, but the proposal was rejected. The main concern was that an intelligent placement strategy might require a full view of the cluster, which could be prohibitively expensive in large deployments. Furthermore, such implementations could become overly complex and might introduce latency that impacts the controller thread, thus affecting system stability.

The issue of KAFKA-19507 shows a real-world need for solving custom replica assignment problems. It reinforces the point that different usage scenarios often come with unique assignment needs.

Nevertheless, we can make the ReplicaPlacer an internal pluggable component. This means the mechanism would not be exposed to external users, but could be utilized in internal testing, special-purpose scenarios, or controlled experiments. By allowing different implementations to be injected internally, we can make the placement logic more flexible for testing purposes, without compromising the stability of the controller.

Public Interfaces

New internal broker configuration:

Proposed Changes

Add a new internal configuration: internal.replica.placer.class.name. This configuration allows users to define a custom ReplicaPlacer implementation.

    public static final String REPLICA_PLACER_CLASS_NAME = "replica.placer.class.name";
    public static final String REPLICA_PLACER_CLASS_NAME_DEFAULT = StripedReplicaPlacer.class.getName();     
	public static final String REPLICA_PLACER_CLASS_NAME_DOC = "The fully qualified class name of the ReplicaPlacer implementation. " +
            "This class is used by the broker to determine the placement of replicas when topics or partitions are created. " +
            "This configuration is not intended for external users and should be used in the following scenarios: " +
            "internal testing environments, experimental feature development, performance evaluation or benchmarking. \n " +
            "Custom implementations must be lightweight and efficient to avoid negatively impacting controller performance " +
            "and overall cluster stability.";

The ReplicaPlacer interface has been updated to extend both Configurable and Closeable to support proper configuration and resource cleanup.

package org.apache.kafka.metadata.placement;

/**
 * The interface which a Kafka replica placement policy must implement.
 */
@InterfaceStability.Unstable
public interface ReplicaPlacer extends Configurable, Closeable {
    /**
     * Create a new replica placement.
     *
     * @param placement     What we're trying to place.
     * @param cluster       A description of the cluster we're trying to place in.
     *
     * @return              A topic assignment.
     *
     * @throws InvalidReplicationFactorException    If too many replicas were requested.
     */
    TopicAssignment place(
        PlacementSpec placement,
        ClusterDescriber cluster
    ) throws InvalidReplicationFactorException;
}

Compatibility, Deprecation, and Migration Plan

This KIP adds internal config which doesn’t break compatibility.

Test Plan

Add new test for new internal config internal.replica.placer.class.name

Rejected Alternatives

KIP-660: Pluggable ReplicaPlacer, but the proposal was ultimately rejected due to the following concerns:

Using Admin API for Post-Creation Reassignment

Users could create topics with default placement and then use kafka-reassign-partitions or Admin API to reassign partitions, but rejected due to the following concerns:

Specifying Assignment During Topic Creation 

Users could use Admin API's CreateTopicsRequest with explicit ReplicaAssignment when creating topics, but rejected due to the following concerns: