プロセッサがスパイダーに大きく遅れをとらないようにする必要があるようです。これもスケールアウトできるようにしたいと思うでしょう。
クライアント/サーバー SQL データベースを使用してキューを実装することをお勧めします。この目的には、MySQL がうまく機能します。
設計目標
- スパイダーがプロセッサより先に進みすぎないようにする
- スパイダーとプロセッサ間のパワーバランスを考慮します (それぞれをビジー状態に保ちます)
- データをできるだけ最新に保つ
- 必要に応じてスケールアウトおよびスケールアップ
キュー:
スパイダーからのデータを処理する前に格納するためのキューを作成します。これはいくつかの方法で実行できますが、IO がボトルネックになっているとは思えません。
簡単なアプローチは、次のレイアウトの SQL テーブルを持つことです。
TABLE Queue
Queue_ID int unsigned not null auto_increment primary key
CreateDate datetime not null
Status enum ('New', 'Processing')
Data blob not null
# pseudo code
function get_from_queue()
# in SQL
START TRANSACTION;
SELECT Queue_ID, Data FROM Queue WHERE Status = 'New' LIMIT 1 FOR UPDATE;
UPDATE Queue SET Status = 'Processing' WHERE Queue_ID = (from above)
COMMIT
# end sql
return Data# or false in the case of no records found
# pseudo code
function count_from_queue()
# in SQL
SELECT COUNT(*) FROM Queue WHERE Status = 'New'
# end sql
return (the count)
クモ:
したがって、複数のスパイダープロセスがあります..それぞれが次のように言います:
if count_from_queue() < 10:
# do the spider thing
# save it in the queue
else:
# sleep awhile
repeat
このようにして、各スパイダーは休止中またはスパイダー中のいずれかになります。決定 (この場合) は、処理する保留中のアイテムが 10 未満であるかどうかに基づいています。これを目的に合わせて調整します。
プロセッサ
したがって、複数のプロセッサプロセスがあります..それぞれが次のように言います:
Data = get_from_queue()
if Data:
# process it
# remove it from the queue
else:
# sleep awhile
repeat
このようにして、各プロセッサは休止中または処理中のいずれかになります。
要約
すると、これを 1 台のコンピューターで実行している場合でも、20 台のコンピューターで実行している場合でも、キューは、すべてのパーツが同期し、互いに先を行き過ぎないようにするために必要な制御を提供します。