我正在探索Kafka是否支持任何队列或消息处理的优先级。
它似乎并不支持任何此类事情。我用谷歌搜索并发现了这个支持这个的邮件存档: http://mail-archives.apache.org/mod_mbox/incubator-kafka-users/201206.mbox/%3CCAOeJiJhVHsr=d6aSTihPsqWVg6vK5xYLam6yMDcd6UAUoXf-DQ@mail.gmail.com%3E
这里是否有人配置Kafka来优先处理任何主题或消息?
答案 0 :(得分:25)
Kafka的设计,分区和复制提交日志服务本质上是一种快速,可扩展的分布式。因此,主题或消息没有优先权。
我也面临同样的问题。解决方案很简单。在kafka队列中创建主题,让我们说:
1)high_priority_queue
2)medium_priority_queue
3)low_priority_queue
在medium_priority_queue中的high_priority_queue和中优先级消息中发布高优先级消息。
现在,您可以为所有主题创建kafka使用者和开放流。
val props = new Properties()
props.put("group.id", groupId)
props.put("zookeeper.connect", zookeeperConnect)
val config = new ConsumerConfig(props)
val connector = Consumer.create(config)
val topicWithStreamCount = Map(
"high_priority_queue" -> 1,"medium_priority_queue" -> 1,"low_priority_queue" -> 1)
val streamsMap = connector.createMessageStreams(topicWithStreamCount)
//this is scala code
你得到每个主题的流。如果主题没有任何消息,那么你可以先读取high_priority主题,然后回溯到medium_priority_queue主题。如果medium_priority_queue为空,则读取low_priority队列。
这个技巧对我来说很好。可能对你有帮助!!。
答案 1 :(得分:3)
Confluent 有一篇关于 Implementing Message Prioritization in Apache Kafka 的博客描述了如何实现消息优先级。
首先,重要的是要了解 Kafka 的设计不允许对消息进行优先级排序的开箱即用解决方案。主要原因是:
建议的解决方案是使用 Bucket Priority Pattern,该模式可在 GitHub 上获得,并且可以通过自述文件中的图表进行最佳描述。您可以通过自定义生产者的 partitioner 和消费者的 分配策略 来使用具有多个分区的单个主题,而不是针对不同的优先级使用多个主题。
根据消息键,生产者将消息写入正确的优先级桶:
另一方面,消费者组将自定义其分配策略,并优先从具有最高分区的分区读取消息:
在您的客户端代码(生产者和消费者)中,您需要启动并调整以下客户端配置。
# Producer
configs.setProperty(ProducerConfig.PARTITIONER_CLASS_CONFIG,
BucketPriorityPartitioner.class.getName());
configs.setProperty(BucketPriorityConfig.BUCKETS_CONFIG, "Platinum, Gold");
configs.setProperty(BucketPriorityConfig.ALLOCATION_CONFIG, "70%, 30%");
# Consumer
configs.setProperty(ConsumerConfig.PARTITION_ASSIGNMENT_STRATEGY_CONFIG,
BucketPriorityAssignor.class.getName());
configs.setProperty(BucketPriorityConfig.BUCKETS_CONFIG, "Platinum, Gold");
configs.setProperty(BucketPriorityConfig.ALLOCATION_CONFIG, "70%, 30%");
答案 2 :(得分:0)
您需要有一个单独的主题并根据其优先级流式传输
答案 3 :(得分:0)
您可以检出priority-kafka-client,以优先使用主题。
基本思想如下(复制/粘贴自述文件的一部分):
在这种情况下,优先级是优先级为0 < 1 < ... < N-1
的正整数(N)
PriorityKafkaProducer (implements org.apache.kafka.clients.producer.Producer):
该实现接受优先级为Future<RecordMetadata> send(int priority, ProducerRecord<K, V> record)
的附加arg。这表明产生该优先级记录。 Future<RecordMetadata> send(int priority, ProducerRecord<K, V> record)
将记录产生默认为最低优先级0。对于每个逻辑主题XYZ-优先级0 <= i
CapacityBurstPriorityKafkaConsumer (implements org.apache.kafka.clients.consumer.Consumer):
该实现为每个优先级0 <= i ABC-i
。这与PriorityKafkaProducer协同工作。
max.poll.records
属性基于maxPollRecordsDistributor
在优先主题使用者之间进行划分-默认为ExpMaxPollRecordsDistributor
。其余的KafkaConsumer配置将按原样传递给每个优先主题使用者。定义max.partition.fetch.bytes
,fetch.max.bytes
和max.poll.interval.ms
时要格外小心,因为这些值将在所有优先主题使用者中照常使用。
研究将max.poll.records
属性分配给每个优先主题使用者作为其保留容量的想法。从配置了分布式max.poll.records
值的所有优先级主题使用者依次获取记录。该发行版必须为更高的优先级保留更高的容量或处理速率。
警告1-如果我们在优先级主题中对分区进行了倾斜,例如优先级2分区中的10K条记录,优先级1分区中的100条记录,优先级0分区中的10条记录分配给了不同的使用者线程,那么该实现将不会在这些使用者之间进行同步以调节容量,因此将无法兑现优先级。因此,生产者必须确保没有倾斜的分区(例如,使用循环轮询-这“可能”意味着没有消息排序假设,并且消费者可以选择通过分离提取和处理问题来并行处理记录)。
警告2-如果我们在优先级主题中有空分区,例如在分配的优先级2和1分区中没有待处理的记录,在优先级0分区中的10K记录已分配给同一个使用者线程,那么我们希望优先级0主题分区使用者将其容量爆发到max.poll.records
而不是将自身限制于其基于maxPollRecordsDistributor
保留的容量,否则总容量将被利用。
此实现将尝试解决上面说明的注意事项。每个使用者对象都有单独的优先级主题使用者,每个优先级使用者具有基于maxPollRecordsDistributor的保留容量。如果满足以下所有条件,则每个优先级主题使用者将尝试突入组中其他优先级主题使用者的能力:
有资格进行突发-这是在max.poll.history.window.size
的最后poll()
次尝试中,至少min.poll.window.maxout.threshold
次接收到等于分配的最大轮询次数的记录。基于maxPollRecordsDistributor
分发的记录。这表明该分区有更多的传入记录要处理。
更高优先级级别不适合突发-根据上述逻辑,没有更高优先级级别的主题消费者可以突发。基本上让位于更高的优先级。
如果以上是正确的,那么优先级主题使用者将突入所有其他优先级主题使用者容量。每个优先级主题使用者的突发数量等于max.poll.history.window.size
的最后poll()
次尝试中未使用的最少容量。
答案 4 :(得分:0)
解决方案是根据优先级创建3个不同的主题。
一般而言,高优先级主题的消费者数>中优先级主题的消费者数>低优先级主题的消费者数。
通过这种方式,可以确保到达高优先级主题的邮件比低优先级主题的处理速度更快。