多个主题及其优先级

时间:2018-10-22 13:57:46

标签: python apache-kafka kafka-consumer-api pykafka

我正在使用pykafka来消费消息,现在我正在使用balanced_consumer来消费一个主题的消息。现在,我必须使用来自其他主题的消息,如果可以的话,可以优先使用来自其他主题的消息。我该如何处理?可能是python的其他库吗?

1 个答案:

答案 0 :(得分:0)

我刚刚发布了有关此问题的帖子。

即使我使用的是Java,您也可以在其中找到对您的案例有用的概念。

我们解决了优先考虑Kafka主题的问题-

我们开发了一种机制,可以优先考虑使用Kafka主题。这种机制将检查我们是否要处理从Kafka消费的消息,或将其保留以备后用。

我们在分区和布尔值之间进行了映射,这在必要时阻止使用每个分区topicPartitionLocks。阻止初步的话题,同时继续从迟钝的话题中消费,创建主题的优先级。 TimerTask更新此地图,我们的消费者检查他们是否“被允许”消费或必须等待-如您在方法waitForLatePartitionIfNeeded中所看到的。

public class Prioritizer extends TimerTask {
    private Map<String, Boolean> topicPartitionLocks = new ConcurrentHashMap<>();
    private Map<String, Long> topicPartitionLatestTimestamps = new ConcurrentHashMap<>();

    @Override
    public void run(){
        updateTopicPartitionLocks();
    }

    private void updateTopicPartitionLocks() {
        Optional<Long> minValue = topicPartitionLatestTimestamps.values().stream().min((o1, o2) -> (int) (o1 - o2));
        if(! minValue.isPresent()) {
            return;
        }

        Iterator it = topicPartitionLatestTimestamps.entrySet().iterator();
        while (it.hasNext()) {
            Boolean shouldLock = false;

            Map.Entry<String, Long> pair = (Map.Entry)it.next();
            String topicPartition = pair.getKey();
            if(pair.getValue() > (minValue.get() + maxGap)) {
                shouldLock = true;
                if(isSameTopicAsMinPartition(minValue.get(), topicPartition)) {
                    shouldLock = false;
                }

            }

            topicPartitionLocks.put(topicPartition, shouldLock);
        }
    }

    public boolean isLocked(String topicPartition) {
        return topicPartitionLocks.get(topicPartition).booleanValue();
    }
}

waitForLatePartitionIfNeeded方法

private void waitForLatePartitionIfNeeded(final String topic, int partition) {
    String topicPartition = topic + partition;

    prioritizer.getTopicPartitionLocks.putIfAbsent(topicPartition);

    while(prioritizer.isLocked(topicPartition)) {
        monitorWaitForLatePartitionTimes(topicPartition, startTime);
        Misc.sleep(timeToWaitBetweenGapToTardyPartitionChecks.get());
    }
}

使用此方法导致重新平衡增加,因此我们使用以下定义解决了该问题:

我们更改了Kafka中的下一个配置

request.timeout.ms: 7300000 (~2hrs)
max.poll.interval.ms: 7200000 (2hrs)

有关该问题的图表和一般描述,请查看我的帖子:

How I Resolved Delays in Kafka Messages by Prioritizing Kafka Topics

祝你好运!