Perl 一种作业队列自重组方法
我有一个作业队列(使用AmazonSQS),它将作业交给许多机器,以便通过HTTP获取和处理各种文档。有数百个不同的主机被访问,并且没有可预测的作业顺序 为了礼貌起见,我不希望我的系统在一台主机上反复运行。因此,如果我得到一个作业#123从example.com获取一些东西,但我发现我在过去的X秒内刚刚从example.com获取了另一个东西,那么我应该转到其他作业,并将作业#123保存到以后 问题是,实现这种模式的好方法是什么 第一步似乎是让工作负责人在某个地方保存一个所有域的列表,以及上一次访问该域上的某些内容的时间。我想这可能是一个简单的DB表 如果消息处理器得到一个必须延迟的作业,那么有许多可能的选项来做什么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保存到以后 问题是,实现这种模式的好方法是什么 第一步似乎是让工作负责人在某个地方保存一个所有域的列表,以及上一次
你有设计这种东西的经验吗?您推荐什么策略?我建议为每个域设置一个队列,每个队列设置一个处理器 大多数服务器对于连续不断地发出的请求应该没有问题,只要您关注总传输量(例如,您应该避免索引超过几百KB的文件,除非您确实需要它)
我假设您也遵守robots.txt规则。为每个域和域队列分别设置队列 每个处理器应:
如果您将域队列组织为时间优先级队列,则可能会有所帮助-按下次更新时间的顺序存储域。您是否100%停留在SQS上?有一些很好的设计不会强迫您进入每个域队列解决方案,但它们要求您直接控制队列,我假设SQS不提供这种控制(准确地说,是“浏览”的能力)队列不使用top元素,并且能够使用第n个元素而不是top元素-基本上,将队列视为没有插入的双链表,而不是纯队列)。如果您有足够数量的不同域,并且您预期域队列上会发生争用,您可以让处理器将域放回自己的本地队列。然后将步骤1修改为“如果本地\u队列\u大小<某个\u阈值,则从域的全局队列中选择一个域,否则从域的本地队列中选择一个域”。每当处理器试图从全局队列中获取作业,但发现没有剩余作业时,触发全局“捐赠”例如,从所有本地队列返回到全局队列的域的50%。@j_random_hacker:不确定这是个好主意。本地队列使数据流复杂化,其好处令人怀疑。如果没有足够的处理器,请添加更多。如果您的域队列太大,请添加一些分片。@Alex:如果我理解您所说的“分片”的意思,那么我的建议将引入的唯一数据流复杂性——即,将本地域返回到全局队列——将恰好在普通分片使一个或多个处理器空闲时发生。它实际上是“自动分片”加上一个恢复机制。当然,对于一个更简单的实现,您可以省略恢复机制,该实现具有切分的所有好处(和低效率),而无需事先定义切分。@j_random_hacker:如果处理器将一个域窃取到一个私有队列,并在之后过载,该怎么办?谁会从中偷回域名?太复杂了。无论如何,我会留到以后再说——现在看来这是一个过早的优化。@Alex:是的,但我认为切分很容易受到同样的过载问题的影响——对吗?我假设“切分”的意思是“预先在处理器之间划分域”。如果不是,你能解释一下吗?谢谢