我有一个作业队列(使用Amazon SQS),它将作业交给许多机器,用于通过HTTP获取和处理各种文档。有数百个不同的主机被访问,并且没有可预测的作业顺序。
为了礼貌,我不希望我的系统在一台主机上反复敲击。因此,如果我得到一份工作#123从example.com获取某些内容,但我发现我在过去的X秒内刚刚从example.com获取了另一件事,我应该转向其他内容并保存作业#123 for后面。
问题是,实施这种模式的好方法是什么?
似乎第一步是让作业运行者在所有域的某个位置保留一个列表,并且最后一次访问该域上的某些内容。我想这可能是一个简单的数据库表。
如果消息处理器获得必须延迟的作业,那么有很多可能的选项可供选择。
只需将邮件的副本推送到队列的末尾,然后将其丢弃而不执行它。希望在下一次出现时,足够的时间过去了。这可能会导致大量冗余SQS消息,特别是如果同一域的大型作业集合同时发生。
在礼貌要求可以执行作业之前,需要休息几秒钟。这可能导致许多队列处理器同时无所事事。
接受作业,但将其保存在每个队列处理器上某处的本地队列中。我想每个处理器都可以通过这种方式“声称”一些工作,然后选择以任何顺序处理它们以达到最大程度的礼貌。这仍然是不可预测的,因为每个队列处理器都需要知道所有其他队列所遇到的域。
为每个域建立单独的队列,并为每个队列分配一个进程。每个进程必须在执行每个作业之间暂停X秒,因此会有很多睡眠过程开销,但这可能不是一件坏事。
你有设计这类东西的经验吗?你会推荐什么策略?
答案 0 :(得分:2)
为每个域和域队列分隔队列。
每个处理器应该:
如果将域队列组织为时间优先级队列,则可能会有所帮助 - 按照下一个更新时间的顺序存储域。
答案 1 :(得分:0)
我建议为每个域设置一个队列,每个队列设置一个处理器。
大多数服务器应该对串行发出的请求没有问题,只要您密切关注总传输数量(例如,除非有实际需要,否则应避免将文件索引超过几百KB)为了它)。
我认为你也遵守robots.txt规则。