【问题标题】:How to evenly balance processing many simultaneous tasks?如何均匀地平衡处理多个同时执行的任务?
【发布时间】:2020-06-04 11:25:14
【问题描述】:

问题

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

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


解决方案

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

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

站在消费者一边

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

问题

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

【问题讨论】:

  • 尝试阅读 Apache Pulsar。与 Kafka 相比,它具有多种优势,其中之一是自动负载平衡。阅读:dzone.com/articles/….

标签: asynchronous apache-kafka parallel-processing rabbitmq concurrent-processing


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    据我了解,您希望使用动态分配的队列创建与客户的请求隔离,这将允许每个客户任务独立执行。该问题类似于网络中的Head of line blocking 问题

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

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

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

    【讨论】:

      【解决方案3】:

      我的理解是消息的分区并不能确保负载均衡。我认为您应该避免创建过度工程以及一些将出现在 Kafka 分区器之上的自定义内容,而是考虑一个可以让您以有效方式使用 Kafka 的良好分区键。

      【讨论】:

        猜你喜欢
        • 2016-04-24
        • 2023-03-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-22
        • 2020-04-12
        • 1970-01-01
        • 2018-11-05
        相关资源
        最近更新 更多