3

私の Heroku Rails アプリは、頻繁に変更されるキーワードの大規模なリストを保持しています。

このキーワードのリストを均等に分割し、再起動されるまで作業する N 個の量のワーカーを生成したいと考えています (キーワードのリストが変更されるたびに再起動します)。再開すると、彼らは再びキーワードを分割して離れていきます。

: 1,000 個のキーワードがあるとします。

  • ワーカーを 1 つ生成すると、そのワーカーは 1,000 個のキーワードを受け取ります。
  • 10 個のワーカーを生成すると、各ワーカーは 100 個のキーワードを受け取ります。
  • 1,000 個のワーカーを生成すると、各ワーカーは 1 つのキーワードを受け取ります。

ワーカーは基本的に、一連のキーワードについて Twitter との接続を開き、それらのキーワードに一致する受信ツイートを処理するだけです。

Profile を設定し、N 個のワーカー間で X キーワードを委任する方法についてのアイデアはありますか?


これは、デモンストレーションのためだけの単純な/疑似手動アプローチです。ただし、キーワードを自動的に分割する任意の数のワーカーを生成できるようにしたいと考えています。

プロファイル:

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

次に、私のアプリで、キーワード ワーカーを再起動する必要がある場合:

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

代わりに、これらのワーカーを N 個生成できるようにしたいのですが、ソリューションを分割するのに苦労しています。高レベルの概要の提案をいただければ幸いです。

4

1 に答える 1

3

一度に 1 つのキーワードを処理するだけで、特定の順序やグループ化を行わない場合は、キューを使用できます。

各ワーカーは、キューから次のキーワード (パフォーマンスのために、おそらく次のキーワードのバッチ) をフェッチし、作業を実行してから、結果をどこかに保存します。ワークロードの分割について心配する必要はありません。ワーカーは準備ができたら追加の作業を要求するだけなので、各ワーカーが利用可能なワークロードの合計サイズを知る必要なく、N 個のワーカーにスケーリングできます。

データのキューを実装する方法は多数あります。私が以前に使用したより専門的なものには、AMQP と Redis がありますが、これは完全なリストではありません。

Keyword.allサンプルコードがあり、Heroku を使用しているので、postgres を使用していると推測して言います。また、postgres でキューをエミュレートすることもそれほど難しくありませんが、専用のキューほどパフォーマンスが優れていないことは明らかです。

これを行う1つの方法は次のとおりです。

statusキーワードに列を追加します。準備完了、進行中、完了の 3 つの値があります。ステータス列のデフォルト値は ready です。

ワーカーの擬似コードは次のようになります。

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で完了です。

于 2012-11-01T21:53:31.167 に答える