Search in sources :

Example 16 with Subscription

use of org.apache.kafka.clients.consumer.ConsumerPartitionAssignor.Subscription in project kafka by apache.

the class AbstractStickyAssignorTest method testAddRemoveTopicTwoConsumers.

@Test
public void testAddRemoveTopicTwoConsumers() {
    Map<String, Integer> partitionsPerTopic = new HashMap<>();
    partitionsPerTopic.put(topic, 3);
    subscriptions.put(consumer1, new Subscription(topics(topic)));
    subscriptions.put(consumer2, new Subscription(topics(topic)));
    Map<String, List<TopicPartition>> assignment = assignor.assign(partitionsPerTopic, subscriptions);
    assertTrue(assignor.partitionsTransferringOwnership.isEmpty());
    // verify balance
    assertTrue(isFullyBalanced(assignment));
    verifyValidityAndBalance(subscriptions, assignment, partitionsPerTopic);
    // verify stickiness
    List<TopicPartition> consumer1Assignment1 = assignment.get(consumer1);
    List<TopicPartition> consumer2Assignment1 = assignment.get(consumer2);
    assertTrue((consumer1Assignment1.size() == 1 && consumer2Assignment1.size() == 2) || (consumer1Assignment1.size() == 2 && consumer2Assignment1.size() == 1));
    partitionsPerTopic.put(topic2, 3);
    subscriptions.put(consumer1, buildSubscription(topics(topic, topic2), assignment.get(consumer1)));
    subscriptions.put(consumer2, buildSubscription(topics(topic, topic2), assignment.get(consumer2)));
    assignment = assignor.assign(partitionsPerTopic, subscriptions);
    assertTrue(assignor.partitionsTransferringOwnership.isEmpty());
    // verify balance
    verifyValidityAndBalance(subscriptions, assignment, partitionsPerTopic);
    assertTrue(isFullyBalanced(assignment));
    // verify stickiness
    List<TopicPartition> consumer1assignment = assignment.get(consumer1);
    List<TopicPartition> consumer2assignment = assignment.get(consumer2);
    assertTrue(consumer1assignment.size() == 3 && consumer2assignment.size() == 3);
    assertTrue(consumer1assignment.containsAll(consumer1Assignment1));
    assertTrue(consumer2assignment.containsAll(consumer2Assignment1));
    partitionsPerTopic.remove(topic);
    subscriptions.put(consumer1, buildSubscription(topics(topic2), assignment.get(consumer1)));
    subscriptions.put(consumer2, buildSubscription(topics(topic2), assignment.get(consumer2)));
    assignment = assignor.assign(partitionsPerTopic, subscriptions);
    assertTrue(assignor.partitionsTransferringOwnership.isEmpty());
    // verify balance
    verifyValidityAndBalance(subscriptions, assignment, partitionsPerTopic);
    assertTrue(isFullyBalanced(assignment));
    // verify stickiness
    List<TopicPartition> consumer1Assignment3 = assignment.get(consumer1);
    List<TopicPartition> consumer2Assignment3 = assignment.get(consumer2);
    assertTrue((consumer1Assignment3.size() == 1 && consumer2Assignment3.size() == 2) || (consumer1Assignment3.size() == 2 && consumer2Assignment3.size() == 1));
    assertTrue(consumer1assignment.containsAll(consumer1Assignment3));
    assertTrue(consumer2assignment.containsAll(consumer2Assignment3));
}
Also used : HashMap(java.util.HashMap) TopicPartition(org.apache.kafka.common.TopicPartition) Collections.emptyList(java.util.Collections.emptyList) ArrayList(java.util.ArrayList) List(java.util.List) Subscription(org.apache.kafka.clients.consumer.ConsumerPartitionAssignor.Subscription) Test(org.junit.jupiter.api.Test)

Example 17 with Subscription

use of org.apache.kafka.clients.consumer.ConsumerPartitionAssignor.Subscription in project kafka by apache.

the class AbstractStickyAssignorTest method testPoorRoundRobinAssignmentScenario.

/**
 * This unit test performs sticky assignment for a scenario that round robin assignor handles poorly.
 * Topics (partitions per topic): topic1 (2), topic2 (1), topic3 (2), topic4 (1), topic5 (2)
 * Subscriptions:
 *  - consumer1: topic1, topic2, topic3, topic4, topic5
 *  - consumer2: topic1, topic3, topic5
 *  - consumer3: topic1, topic3, topic5
 *  - consumer4: topic1, topic2, topic3, topic4, topic5
 * Round Robin Assignment Result:
 *  - consumer1: topic1-0, topic3-0, topic5-0
 *  - consumer2: topic1-1, topic3-1, topic5-1
 *  - consumer3:
 *  - consumer4: topic2-0, topic4-0
 * Sticky Assignment Result:
 *  - consumer1: topic2-0, topic3-0
 *  - consumer2: topic1-0, topic3-1
 *  - consumer3: topic1-1, topic5-0
 *  - consumer4: topic4-0, topic5-1
 */
@Test
public void testPoorRoundRobinAssignmentScenario() {
    Map<String, Integer> partitionsPerTopic = new HashMap<>();
    for (int i = 1; i <= 5; i++) partitionsPerTopic.put(String.format("topic%d", i), (i % 2) + 1);
    subscriptions.put("consumer1", new Subscription(topics("topic1", "topic2", "topic3", "topic4", "topic5")));
    subscriptions.put("consumer2", new Subscription(topics("topic1", "topic3", "topic5")));
    subscriptions.put("consumer3", new Subscription(topics("topic1", "topic3", "topic5")));
    subscriptions.put("consumer4", new Subscription(topics("topic1", "topic2", "topic3", "topic4", "topic5")));
    Map<String, List<TopicPartition>> assignment = assignor.assign(partitionsPerTopic, subscriptions);
    verifyValidityAndBalance(subscriptions, assignment, partitionsPerTopic);
}
Also used : HashMap(java.util.HashMap) Collections.emptyList(java.util.Collections.emptyList) ArrayList(java.util.ArrayList) List(java.util.List) Subscription(org.apache.kafka.clients.consumer.ConsumerPartitionAssignor.Subscription) Test(org.junit.jupiter.api.Test)

Example 18 with Subscription

use of org.apache.kafka.clients.consumer.ConsumerPartitionAssignor.Subscription in project kafka by apache.

the class AbstractStickyAssignorTest method testAddRemoveTwoConsumersTwoTopics.

@Test
public void testAddRemoveTwoConsumersTwoTopics() {
    List<String> allTopics = topics(topic1, topic2);
    Map<String, Integer> partitionsPerTopic = new HashMap<>();
    partitionsPerTopic.put(topic1, 3);
    partitionsPerTopic.put(topic2, 4);
    subscriptions.put(consumer1, new Subscription(allTopics));
    subscriptions.put(consumer2, new Subscription(allTopics));
    Map<String, List<TopicPartition>> assignment = assignor.assign(partitionsPerTopic, subscriptions);
    assertEquals(partitions(tp(topic1, 0), tp(topic1, 2), tp(topic2, 1), tp(topic2, 3)), assignment.get(consumer1));
    assertEquals(partitions(tp(topic1, 1), tp(topic2, 0), tp(topic2, 2)), assignment.get(consumer2));
    assertTrue(assignor.partitionsTransferringOwnership.isEmpty());
    verifyValidityAndBalance(subscriptions, assignment, partitionsPerTopic);
    assertTrue(isFullyBalanced(assignment));
    // add 2 consumers
    subscriptions.put(consumer1, buildSubscription(allTopics, assignment.get(consumer1)));
    subscriptions.put(consumer2, buildSubscription(allTopics, assignment.get(consumer2)));
    subscriptions.put(consumer3, buildSubscription(allTopics, Collections.emptyList()));
    subscriptions.put(consumer4, buildSubscription(allTopics, Collections.emptyList()));
    assignment = assignor.assign(partitionsPerTopic, subscriptions);
    Map<TopicPartition, String> expectedPartitionsTransferringOwnership = new HashMap<>();
    expectedPartitionsTransferringOwnership.put(tp(topic2, 1), consumer3);
    expectedPartitionsTransferringOwnership.put(tp(topic2, 3), consumer3);
    expectedPartitionsTransferringOwnership.put(tp(topic2, 2), consumer4);
    assertEquals(expectedPartitionsTransferringOwnership, assignor.partitionsTransferringOwnership);
    verifyValidityAndBalance(subscriptions, assignment, partitionsPerTopic);
    assertEquals(partitions(tp(topic1, 0), tp(topic1, 2)), assignment.get(consumer1));
    assertEquals(partitions(tp(topic1, 1), tp(topic2, 0)), assignment.get(consumer2));
    assertEquals(partitions(tp(topic2, 1), tp(topic2, 3)), assignment.get(consumer3));
    assertEquals(partitions(tp(topic2, 2)), assignment.get(consumer4));
    assertTrue(isFullyBalanced(assignment));
    // remove 2 consumers
    subscriptions.remove(consumer1);
    subscriptions.remove(consumer2);
    subscriptions.put(consumer3, buildSubscription(allTopics, assignment.get(consumer3)));
    subscriptions.put(consumer4, buildSubscription(allTopics, assignment.get(consumer4)));
    assignment = assignor.assign(partitionsPerTopic, subscriptions);
    assertEquals(partitions(tp(topic2, 1), tp(topic2, 3), tp(topic1, 0), tp(topic2, 0)), assignment.get(consumer3));
    assertEquals(partitions(tp(topic2, 2), tp(topic1, 1), tp(topic1, 2)), assignment.get(consumer4));
    assertTrue(assignor.partitionsTransferringOwnership.isEmpty());
    verifyValidityAndBalance(subscriptions, assignment, partitionsPerTopic);
    assertTrue(isFullyBalanced(assignment));
}
Also used : HashMap(java.util.HashMap) TopicPartition(org.apache.kafka.common.TopicPartition) Collections.emptyList(java.util.Collections.emptyList) ArrayList(java.util.ArrayList) List(java.util.List) Subscription(org.apache.kafka.clients.consumer.ConsumerPartitionAssignor.Subscription) Test(org.junit.jupiter.api.Test)

Example 19 with Subscription

use of org.apache.kafka.clients.consumer.ConsumerPartitionAssignor.Subscription in project kafka by apache.

the class AbstractStickyAssignorTest method testSameSubscriptions.

@Test
public void testSameSubscriptions() {
    Map<String, Integer> partitionsPerTopic = new HashMap<>();
    for (int i = 1; i < 15; i++) partitionsPerTopic.put(getTopicName(i, 15), i);
    for (int i = 1; i < 9; i++) {
        List<String> topics = new ArrayList<>();
        for (int j = 1; j <= partitionsPerTopic.size(); j++) topics.add(getTopicName(j, 15));
        subscriptions.put(getConsumerName(i, 9), new Subscription(topics));
    }
    Map<String, List<TopicPartition>> assignment = assignor.assign(partitionsPerTopic, subscriptions);
    assertTrue(assignor.partitionsTransferringOwnership.isEmpty());
    verifyValidityAndBalance(subscriptions, assignment, partitionsPerTopic);
    for (int i = 1; i < 9; i++) {
        String consumer = getConsumerName(i, 9);
        subscriptions.put(consumer, buildSubscription(subscriptions.get(consumer).topics(), assignment.get(consumer)));
    }
    subscriptions.remove(getConsumerName(5, 9));
    assignment = assignor.assign(partitionsPerTopic, subscriptions);
    assertTrue(assignor.partitionsTransferringOwnership.isEmpty());
    verifyValidityAndBalance(subscriptions, assignment, partitionsPerTopic);
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Collections.emptyList(java.util.Collections.emptyList) ArrayList(java.util.ArrayList) List(java.util.List) Subscription(org.apache.kafka.clients.consumer.ConsumerPartitionAssignor.Subscription) Test(org.junit.jupiter.api.Test)

Example 20 with Subscription

use of org.apache.kafka.clients.consumer.ConsumerPartitionAssignor.Subscription in project kafka by apache.

the class AbstractStickyAssignorTest method testReassignmentWithRandomSubscriptionsAndChanges.

@Test
public void testReassignmentWithRandomSubscriptionsAndChanges() {
    final int minNumConsumers = 20;
    final int maxNumConsumers = 40;
    final int minNumTopics = 10;
    final int maxNumTopics = 20;
    for (int round = 1; round <= 100; ++round) {
        int numTopics = minNumTopics + new Random().nextInt(maxNumTopics - minNumTopics);
        ArrayList<String> topics = new ArrayList<>();
        Map<String, Integer> partitionsPerTopic = new HashMap<>();
        for (int i = 0; i < numTopics; ++i) {
            topics.add(getTopicName(i, maxNumTopics));
            partitionsPerTopic.put(getTopicName(i, maxNumTopics), i + 1);
        }
        int numConsumers = minNumConsumers + new Random().nextInt(maxNumConsumers - minNumConsumers);
        for (int i = 0; i < numConsumers; ++i) {
            List<String> sub = Utils.sorted(getRandomSublist(topics));
            subscriptions.put(getConsumerName(i, maxNumConsumers), new Subscription(sub));
        }
        assignor = createAssignor();
        Map<String, List<TopicPartition>> assignment = assignor.assign(partitionsPerTopic, subscriptions);
        verifyValidityAndBalance(subscriptions, assignment, partitionsPerTopic);
        subscriptions.clear();
        for (int i = 0; i < numConsumers; ++i) {
            List<String> sub = Utils.sorted(getRandomSublist(topics));
            String consumer = getConsumerName(i, maxNumConsumers);
            subscriptions.put(consumer, buildSubscription(sub, assignment.get(consumer)));
        }
        assignment = assignor.assign(partitionsPerTopic, subscriptions);
        verifyValidityAndBalance(subscriptions, assignment, partitionsPerTopic);
        assertTrue(assignor.isSticky());
    }
}
Also used : Random(java.util.Random) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Collections.emptyList(java.util.Collections.emptyList) ArrayList(java.util.ArrayList) List(java.util.List) Subscription(org.apache.kafka.clients.consumer.ConsumerPartitionAssignor.Subscription) Test(org.junit.jupiter.api.Test)

Aggregations

Subscription (org.apache.kafka.clients.consumer.ConsumerPartitionAssignor.Subscription)89 HashMap (java.util.HashMap)50 ArrayList (java.util.ArrayList)49 List (java.util.List)45 Test (org.junit.jupiter.api.Test)44 GroupSubscription (org.apache.kafka.clients.consumer.ConsumerPartitionAssignor.GroupSubscription)39 Test (org.junit.Test)33 Collections.emptyList (java.util.Collections.emptyList)28 Assignment (org.apache.kafka.clients.consumer.ConsumerPartitionAssignor.Assignment)24 TopicPartition (org.apache.kafka.common.TopicPartition)20 TaskId (org.apache.kafka.streams.processor.TaskId)19 AssignmentInfo (org.apache.kafka.streams.processor.internals.assignment.AssignmentInfo)18 ByteBuffer (java.nio.ByteBuffer)15 MockKeyValueStoreBuilder (org.apache.kafka.test.MockKeyValueStoreBuilder)15 HashSet (java.util.HashSet)14 Map (java.util.Map)13 Cluster (org.apache.kafka.common.Cluster)9 Utils.mkMap (org.apache.kafka.common.utils.Utils.mkMap)9 MockInternalTopicManager (org.apache.kafka.test.MockInternalTopicManager)9 Collections.emptyMap (java.util.Collections.emptyMap)8