我如何产生Heroku工作者来划分和征服关键词列表?

时间:2012-11-01 17:39:05

标签: ruby-on-rails ruby heroku process

我的Heroku Rails应用程序维护了一个经常更改的大型关键字列表。

我希望产生N个工作人员,这些工作人员会平均分配这个关键字列表并对其进行处理,直到重新启动它们为止(每次关键字列表更改时重新启动它们)。重新启动后,他们会再次对关键字进行分割,然后流失。

例如:假设我有1,000个关键字。

  • 如果我产生1名工人,该工人将获得1,000个关键字。
  • 如果我产生了10个工人,每个工人将需要100个关键字。
  • 如果我产生1,000名工人,每个工人将获得1个关键字。

工作人员基本上只是打开与Twitter关联的关键字集,并处理与这些关键字匹配的传入推文。

有关如何在N个工作人员之间设置Procfile和委托X关键字的任何想法吗?


这是一个仅用于演示的天真/伪手动方法。但是,我希望能够产生任意数量的工作人员,这些工作人员会自动将关键字分开。

Procfile:

keywordstreamer0: bundle exec ruby keyword_streamer.rb 0
keywordstreamer1: bundle exec ruby keyword_streamer.rb 1

keyword_streamer.rb

streamer_id = ARGV.shift # 0 or 1

# Split all keywords into array of two groups and take the group
# that matches this worker id (so the two workers take different groups)
keywords = Keyword.all.split_into_groups_of(2)[streamer_id]

# Example work loop
TwitterStream.track(keywords).each do |incoming_tweet|
  process(incoming_tweet)
end

然后,在我的应用程序中,当我需要重新启动关键字worker时

["keywordstreamer0", "keywordstreamer1"].each do |streamer|
  restart(streamer)
end

我希望能够产生N个这样的工人,但我在解决问题方面遇到了麻烦。我很感激任何高级概述建议!

1 个答案:

答案 0 :(得分:3)

如果你一次只处理一个关键字,没有特定的顺序或分组,你可以只使用一个队列。

每个工作人员只是从队列中提取下一个关键字(或者可能是下一批关键字,以获得性能),是否正常工作,然后将结果保存在某处。您无需担心分区工作负载,因为工作人员只需在准备就绪时要求更多工作,允许您扩展到N个工作人员,而无需每个工作人员了解可用工作负载的总大小。 / p>

您可以通过多种方式为数据实施队列。我之前使用的几个更专业的是AMQP和Redis,但这不是一个详尽的清单。

我会猜测一下,因为你的示例代码中有Keyword.all,而你是Heroku,那你就是在使用postgres。你也可以毫不费力地在postgres中模拟一个队列,虽然它显然不会像专用队列一样好。

这是一种方法:

在关键字中添加status列。它将具有3个值:就绪,正在进行和完成。状态列的默认值已准备就绪。

您的工作人员的伪代码如下所示:

loop do
  keyword = Keyword.where(:status => "ready").limit(1).first
  keyword.update_attributes!(:status => "in-progress")

  result = process(keyword)
  save_result_somewhere(result)

  keyword.update_attributes!(:status => "complete")
end

我遗漏了一堆实现细节,例如优雅地处理队列为空,队列的初始设置,批处理等等。但这就是它的要点。这适用于适度大小的N,可能至少10名或更多工人。除此之外,您可能需要考虑专门构建的排队技术。

一旦设置了队列,每个工作人员都是相同且自主的。只需heroku ps:scale worker=N即可完成!