Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 一种作业队列自重组方法_Perl_Design Patterns_Parallel Processing_Amazon Sqs_Job Queue - Fatal编程技术网

Perl 一种作业队列自重组方法

Perl 一种作业队列自重组方法,perl,design-patterns,parallel-processing,amazon-sqs,job-queue,Perl,Design Patterns,Parallel Processing,Amazon Sqs,Job Queue,我有一个作业队列(使用AmazonSQS),它将作业交给许多机器,以便通过HTTP获取和处理各种文档。有数百个不同的主机被访问,并且没有可预测的作业顺序 为了礼貌起见,我不希望我的系统在一台主机上反复运行。因此,如果我得到一个作业#123从example.com获取一些东西,但我发现我在过去的X秒内刚刚从example.com获取了另一个东西,那么我应该转到其他作业,并将作业#123保存到以后 问题是,实现这种模式的好方法是什么 第一步似乎是让工作负责人在某个地方保存一个所有域的列表,以及上一次

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

为了礼貌起见,我不希望我的系统在一台主机上反复运行。因此,如果我得到一个作业#123从example.com获取一些东西,但我发现我在过去的X秒内刚刚从example.com获取了另一个东西,那么我应该转到其他作业,并将作业#123保存到以后

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

第一步似乎是让工作负责人在某个地方保存一个所有域的列表,以及上一次访问该域上的某些内容的时间。我想这可能是一个简单的DB表

如果消息处理器得到一个必须延迟的作业,那么有许多可能的选项来做什么

  • 只需将消息的副本推送到队列的末尾,然后在不执行它的情况下将其丢弃。希望到下一次它出现的时候,足够的时间已经过去了。这可能会导致大量冗余的SQS消息,特别是当同一域的大量作业同时通过时

  • 睡眠多少秒是必要的,直到礼貌地表明作业可以执行为止。这可能导致许多队列处理器同时无所事事

  • 接受作业,但将其保存在每个队列处理器上的某个本地队列中。我想每个处理器都可以通过这种方式“声明”一些作业,然后选择以任何顺序处理它们,以达到最大的礼貌。这仍然是不可预测的,因为每个队列处理器都需要知道所有其他队列处理器所访问的域

  • 为每个域建立单独的队列,并为每个队列指定一个进程。每个进程在执行每个任务之间都必须暂停X秒,因此会有大量休眠进程开销,但这可能不是一件坏事


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

    我建议为每个域设置一个队列,每个队列设置一个处理器

    大多数服务器对于连续不断地发出的请求应该没有问题,只要您关注总传输量(例如,您应该避免索引超过几百KB的文件,除非您确实需要它)


    我假设您也遵守robots.txt规则。

    为每个域和域队列分别设置队列

    每个处理器应:

  • 从域队列中选择一个域
  • 如果域最近未更新,请从域队列中选择顶部任务
  • 将域放回域队列的末尾
  • 如果我们有任务要执行,就去做
  • 睡眠,直到检查域队列头或更新域队列
    如果您将域队列组织为时间优先级队列,则可能会有所帮助-按下次更新时间的顺序存储域。

    您是否100%停留在SQS上?有一些很好的设计不会强迫您进入每个域队列解决方案,但它们要求您直接控制队列,我假设SQS不提供这种控制(准确地说,是“浏览”的能力)队列不使用top元素,并且能够使用第n个元素而不是top元素-基本上,将队列视为没有插入的双链表,而不是纯队列)。如果您有足够数量的不同域,并且您预期域队列上会发生争用,您可以让处理器将域放回自己的本地队列。然后将步骤1修改为“如果本地\u队列\u大小<某个\u阈值,则从域的全局队列中选择一个域,否则从域的本地队列中选择一个域”。每当处理器试图从全局队列中获取作业,但发现没有剩余作业时,触发全局“捐赠”例如,从所有本地队列返回到全局队列的域的50%。@j_random_hacker:不确定这是个好主意。本地队列使数据流复杂化,其好处令人怀疑。如果没有足够的处理器,请添加更多。如果您的域队列太大,请添加一些分片。@Alex:如果我理解您所说的“分片”的意思,那么我的建议将引入的唯一数据流复杂性——即,将本地域返回到全局队列——将恰好在普通分片使一个或多个处理器空闲时发生。它实际上是“自动分片”加上一个恢复机制。当然,对于一个更简单的实现,您可以省略恢复机制,该实现具有切分的所有好处(和低效率),而无需事先定义切分。@j_random_hacker:如果处理器将一个域窃取到一个私有队列,并在之后过载,该怎么办?谁会从中偷回域名?太复杂了。无论如何,我会留到以后再说——现在看来这是一个过早的优化。@Alex:是的,但我认为切分很容易受到同样的过载问题的影响——对吗?我假设“切分”的意思是“预先在处理器之间划分域”。如果不是,你能解释一下吗?谢谢