【问题标题】:Designing fair message consumption in a distributed system在分布式系统中设计公平的消息消费
【发布时间】:2016-04-24 09:32:11
【问题描述】:

我们有一个代表多个客户工作的分布式应用程序。现在,随着工作的到来,消息被放在一个队列中。消息按 FIFO 顺序拉出,这在大多数情况下都可以正常工作。

在某些情况下,我们会为单个客户端获取数千条消息,然后占用队列中的前一千多个插槽。这意味着在处理这些消息之前,无法为任何其他客户端完成任何(或很少)工作 - 这会使较小的客户端挨饿。

我的想法是,在我们每次引用客户端列表之前,在从队列中获取消息之前,我们都会查看消息以查看哪个客户端提交了消息。如果它是针对我们刚刚处理的同一个客户端,我们将其推回,直到我们找到另一个客户端的消息,或者我们迭代所有客户端并且找不到其他工作。

这是一个合理的解决方案吗?这是一个已经解决的问题吗?如果解决了怎么办?

我已经看过这个问题 (Is "fair queuing" possible with JMS),但我认为群组不是正确的答案,因为我不希望所有消息都发送到单个服务器。我只是想给其他客户的消息一个公平的处理机会,而不是在一个客户的一千条其他消息后面排队。

目前我们使用 ActiveMQ 作为我们的消息队列系统。

【问题讨论】:

    标签: activemq


    【解决方案1】:

    您的建议是合理的,但对于可以在多台机器上同时处理多条消息的分布式系统,我建议另一种选择:使用一次处理多条消息的线程池,您可以使用包含“溢出队列”。

    • 从主队列读取时,检查是否已经为客户处理了超过 X 条消息(您的公平阈值)。如果是这样,将消息放入溢出队列而不是处理它。
    • 保留少量线程 (Y) 来处理该队列,其余线程用于主队列。
    • Y 应该是可配置的,以便在溢出相对于主队列非常大时(或当主队列​​为空时)继续处理。或者,不是 Y 线程进行溢出处理,而是将其设为一个百分比 - 比如说 90% 的消息来自主队列,10% 来自溢出。

    这导致更公平的处理 - 大多数处理使用主队列(现在只允许“公平”消息通过),您的重度用户仍将获得超过 X 的一些吞吐量(使用溢出处理)。

    这不是“最佳”解决方案,但相当不错,而且实施起来仍然相对简单。

    确保有一些关于队列大小的指标,以查看是否存在大量积压(或空队列),并且理想情况下自动调整参数,以便在主队列流量低时给予更高的溢出优先级.

    【讨论】:

    • 解决方案中有三台服务器,每台可能一次处理 2-6 条消息。当每个都完成时,它将从队列中获得一条新消息。问题是单个客户的队列中可能有数千个,另一个客户可能有一个或两个,或者其他几个客户可能有一个或两个。这种情况不会经常发生,但确实会发生。我的希望不是迎合过载的客户,而是提供一种公平的循环方法。
    • 这样想:每个服务器将处理两个队列,从每个队列中获取一个百分比。主队列处理将始终接近“公平”(因为超出允许的“公平”的任何消息都将被发送到溢出)。溢出处理本质上是“低优先级”,只会包含超出“公平”限制的客户。这只是众多解决方案中的一种;我之前已经在更大的系统上成功使用过这个。我已经将它简化了很多,因为在构建分布式系统时需要考虑很多复杂性和变量。祝你好运!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-24
    • 2012-02-11
    • 1970-01-01
    相关资源
    最近更新 更多