在Apache Kafka 2.0中是否可以对消息进行优先级排序?

时间:2019-03-27 16:05:49

标签: apache-kafka priority-queue apache-kafka-streams

编辑

在其他人处于这种特殊情况的情况下,调整用户配置后,我得到的东西与我要找的东西相似。我创建了一个生产者,该生产者将优先级消息发送到三个单独的主题(针对高/中/低优先级),然后我创建了3个独立的使用者来消费。然后,我经常轮询优先级较高的主题,除非优先级高的空白为空,否则不轮询优先级较低的主题:

    while(true) {
        final KafkaConsumer<String,String> highPriConsumer = createConsumer(TOPIC1);
        final KafkaConsumer<String,String> medPriConsumer = createConsumer(TOPIC2);

        final ConsumerRecords<String, String> consumerRecordsHigh = highPriConsumer.poll(100);
        if (!consumerRecordsHigh.isEmpty()) {
            //process high pri records
        } else {
            final ConsumerRecords<String, String> consumerRecordsMed = medPriConsumer.poll(100);
            if (!consumerRecordsMed.isEmpty()) {
                //process med pri records

轮询超时(.poll()方法的参数)确定没有轮询记录时要等待多长时间。对于每个主题,我都将其设置为很短的时间,但是对于优先级较低的主题,您可以将其设置为较低,以确保在出现高pri消息时,不会浪费宝贵的等待时间

max.poll.records配置显然确定了一次轮询中可获取的最大记录数。对于更高的优先级,也可以将其设置为更高。

max.poll.interval.ms配置确定两次轮询之间的时间-处理max.poll.records消息应花费多长时间。澄清here

此外,我相信可以像这样实现暂停/恢复整个消费者/主题:

    kafkaConsumer.pause(kafkaConsumer.assignment())
    if(kafkaConsumer.paused().containsAll(kafkaConsumer.assignment())) {
        kafkaConsumer.resume(kafkaConsumer.assignment());
    }

我不确定这是否是最好的方法,但是我在其他地方找不到很好的例子

我同意下面的Senseiwu的观点,这并不是Kafka的正确用法。这是单线程处理,每个主题都有专门的使用者,但是我将在此处着手改进此过程。


背景

我们正在尝试改进我们的应用程序,并希望使用Apache Kafka在解耦的组件之间进行消息传递。我们的系统通常是低带宽的(尽管有时带宽​​可能会很高),并且包含小的,高优先级的消息,这些消息必须在较大的文件等待时进行处理,或者处理速度慢才能消耗较少的带宽。我们希望有不同优先级的主题。

我是Kafka的新手,但是尽管在论坛上的某些帖子似乎都说这是可行的,但尝试研究Processor API和Kafka Streams都没有成功。

处理器API

当我尝试Processor API时,我尝试通过检查KafkaConsumer是否为空来确定高优先级poll()当前是否正在处理任何内容,然后希望poll()与Med Priority Consumer合作,但第二个主题民意调查返回为空。似乎也没有一种简单的方法来使所有TopicPartition都在某个主题上才能调用kafkaConsumer.pause(partitions)

Kafka流

当我尝试KafkaStreams时,我设置了一个流来使用我的每个“优先级”主题,但是无法检查KStreamKafkaStreams实例是否已连接优先级较高的主题当前处于空闲或正在处理中。

我的代码基于this文件

其他

我还在这里尝试了以下代码:priority-kafka-client,但是由于运行下载的测试文件具有不同的优先级,因此它无法按预期工作。

我发现了this线程,其中一位开发人员说(着眼于为主题添加优先级):“ ...用户可以通过暂停和恢复来实现此行为”。但是我无法弄清楚他的意思是什么。

我找到了this StackOverflow文章,但是他们似乎使用的是非常旧的版本,并且我不清楚他们的映射功能应该如何工作。

结论

如果有人告诉我他们是否认为这是值得追求的事情,我将不胜感激。如果这不是Apache Kafka的工作方式,因为它破坏了从自动主题/分区处理中获得的收益,那就很好了,我将在其他地方找到。但是,在很多情况下人们似乎都成功了,我想尝试一下。谢谢。

1 个答案:

答案 0 :(得分:2)

这听起来像是您应用程序中的一个设计问题-kafka最初被设计为提交日志,其中每条消息都以偏移量写入代理,并且各种使用者以极低的延迟提交它们的顺序来消耗它们,并且高通量。考虑到分区而不是主题是Kafka工作分配的基本单位,因此很难在本地实现主题级别的优先级。

我建议您将您的设计调整为使用除Kafka之外的其他建筑组件,而不要尝试踩脚以适合鞋子。您已经可以做的一件事是让生产者将文件上传到适当的文件存储,并通过Kafka发送包含元数据的链接。然后,根据带宽状态,您的消费者可以根据大文件的元数据来决定是否明智下载。这样一来,您可能更有可能拥有可靠的设计,而不是错误地使用Kafka。

如果您确实只想坚持使用Kafka,一种解决方案是将大文件发送到固定数量的硬编码分区,并且只有在带宽良好的情况下,使用者才能从这些分区中使用。