perl - 自重排作业队列的方法

标签 perl design-patterns parallel-processing amazon-sqs job-queue

我有一个作业队列(使用 Amazon SQS),它将作业交给多台机器以通过 HTTP 获取和处理各种文档。有数百个不同的主机被访问,并且没有可预测的作业顺序。

为了礼貌起见,我不希望我的系统在单个主机上反复锤击。因此,如果我得到一份工作 #123 从 example.com 获取一些东西,但我看到我刚刚在过去 X 秒内从 example.com 获取了另一件事,我应该继续做其他事情并保存工作 #123之后。

问题是,实现这种模式的好方法是什么?

似乎第一步是让作业运行者在所有域的某处保留一个列表,以及该域上的某些内容最后一次被访问的时间。我想这可能是一个简单的数据库表。

如果消息处理器获得必须推迟的工作,则有许多可能的选择。

  • 只需将消息的副本推送到队列的末尾,然后将其丢弃而不执行它。希望下一次出现时,足够的时间过去了。这可能会导致大量冗余的 SQS 消息,尤其是在同一域的大量作业同时通过的情况下。
  • 无论多少秒都是必要的,直到礼貌要求可以执行工作。这可能会导致许多队列处理器同时无所作为。
  • 接受作业,但将其保存在每个队列处理器上某处的本地队列中。我想每个处理者都可以通过这种方式“声明”许多工作,然后选择以任何顺序处理它们,以实现最大程度的礼貌。这仍然是不可预测的,因为每个队列处理器都需要知道所有其他处理器命中的域。
  • 为每个域建立单独的队列,并有一个专用于每个队列的进程。每个进程在执行每项工作之间必须暂停 X 秒,因此有很多 sleep 进程开销,但这也许不是一件坏事。

  • 你有设计这种东西的经验吗?你会推荐什么策略?

    最佳答案

    每个域的单独队列和域队列。

    每个处理器应该:

  • 从域队列中选择一个域。
  • 如果域最近没有更新,请从域队列中选择最重要的任务。
  • 将域放回域队列的末尾。
  • 如果我们有任务要执行,那就去做吧。
  • 休眠直到检查域队列的头部或域队列更新的时间。

  • 如果您将域队列组织为时间优先队列可能会有所帮助 - 按照下一次更新时间的顺序存储域。

    关于perl - 自重排作业队列的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4577204/

    相关文章:

    http - Camel : outgoing connections limit for http component

    perl - 使用 Perl 模块 Image::ExifTool 从 PDF 中读取元信息

    ruby - ruby 中类似界面的设计模式

    用于强制执行类先决条件的 java 设计模式

    design-patterns - 带有 REST API 的 CQRS 组件角色和职责

    python - 如何并行处理数据库中的: 6 machines, 800万个独立文档

    Perl删除目录中的所有文件

    perl - 正则表达式重复: how to match expressions of variable lengths?

    mysql - 如何从 SQL 查询中获取多列并将它们存储在 perl 的二维数组中

    python - 基于 Pandas 优化/并行计算一个简单但大的循环