11

问题

我们的PROCESSING SERVICE为 UI、API 和内部客户端提供服务,并监听来自Kafka的命令。少数 API 客户端可能会在短时间内创建大量生成任务(一个任务是 N 条消息)。使用 Kafka,我们无法控制命令分发,因为每个命令都到达由一个处理实例(又名工作人员)使用的分区。因此,在处理 API 请求时,UI 请求可能会等待太久。

在理想的实现中,我们应该均匀地处理所有任务,无论其大小。处理服务的容量分布在所有活动任务中。而且即使集群负载很重,我们也始终明白,已经到达的新任务几乎可以立即开始处理,至少在所有其他任务的处理结束之前。在此处输入图像描述


解决方案

相反,我们想要一个看起来更像下图的架构,其中每个客户和端点的组合都有单独的队列。这种架构为我们提供了更好的隔离,以及基于每个客户动态调整吞吐量的能力。 在制作人的一边在此处输入图像描述

  • 任务来自客户端
  • 立即为此任务创建队列
  • 将所有消息发送到此队列

站在消费者一边

  • 在一个过程中,您不断更新队列列表
  • 在其他进程中,您遵循此列表并使用每个队列中的例如 1 条消息
  • 规模消费者

问题

这样的问题有什么通用的解决方案吗?使用 RabbitMQ 或任何其他工具。Н从历史上看,我们在项目中使用 Kafka,所以如果有任何方法使用 - 这太棒了,但我们可以使用任何技术来解决问题。

4

3 回答 3

2

为什么不使用 spark 来执行任务中的消息呢?我在想的是每个工作人员都会创建一个火花上下文,然后并行化消息。映射的功能可以基于用户正在消费的 kafka 主题。但是我怀疑您的队列可能包含包含消息、UI、API 调用等混合的任务。这将导致更复杂的映射函数。如果您没有使用独立集群并且使用的是 YARN 或类似的东西,您可以更改 spark master 使用的排队方法。

于 2020-06-16T18:32:07.373 回答
0

正如我理解的问题,您希望使用动态分配的队列创建与客户的请求隔离,这将允许每个客户任务独立执行。该问题类似于网络中的线头阻塞问题

动态分配队列很困难。这也可能导致队列数量激增,这可能成为基础设施的负担。此外,一些队列可能是空的或负载非常少。RabbitMQ 在这里帮不上忙,它是一个与 kafka 协议不同的队列。

一种替代方法是在 kafka 中使用自定义分区器,它可以查看分区负载并基于该负载平衡任务。如果任务本质上是独立的并且工作人员中没有维护状态存储,则此方法有效。

另一种选择是在客户级别进行负载平衡。在这种情况下,您为一组客户选择一组专用的预定义队列。具有特定 ID 的客户将得到一组队列的服务。这样做的缺点是某些队列的负载可能比其他队列少。该解决方案类似于网络中的虚拟输出队列

于 2020-06-11T08:54:16.890 回答
0

我的理解是消息的分区并不能确保均匀的负载平衡。我认为你应该避免创建过度工程和一些自定义的东西,这些东西会出现在 Kafka 分区器之上,而是考虑一个好的分区键,它可以让你以有效的方式使用 Kafka。

于 2020-06-11T09:04:17.593 回答