More Related Content
Similar to AnyEventとEC2を使ったクローリングツールのご紹介 (20)
AnyEventとEC2を使ったクローリングツールのご紹介
- 2. 自己紹介
• 韓 松熙(@purewish)
• 荘野 和也(@miniturbo)
10/14/2010 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 2
- 3. 本セッションの内容
• 本セッションでは、
• EC2を用いたクローリングサーバのスケールアウト
• AnyEventを用いたインスタンス管理や前後処理の制御
についてご紹介します
• クローリングの対象や目的によって実装方法が異な
るため、特定のク ローリング処理というよりも、ク
ローリングをするための構成や設計を中心にお話
したいと思います
Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.
- 4. クローラー
• 先日、業務でPerlを使ったHoneybeeというク
ローラーを作成しました
• Honeybeeでは、クローリングに特化した
Honeybee::Beeと、クローリングの前後に行
う一連の処理フローを管理・実行する
Honeybee::Hiveの2パッケージで構成されて
います
Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.
- 6. AnyEventとは
• AnyEventのかんたんな説明
• イベント駆動プログラミングをまとめるためのインターフェイス
• I/O, Timer, HTTPなどのイベントが発生したタイミングで、非同期に
処理を実行することができる
• 今回使ったモジュール
• AE::timer
• AnyEvent::Socket
• AnyEvent::Handle
Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.
- 7. 全体的なイメージ
Hive
事前処理
クロール クロール クロール Bee
事後処理
Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.
- 9. シンプルなアプリケーション
• 今回のクローラーでは、クローリング部分を楽にス
ケールアウトできるように設計しました
• さまざまなホスティングサービスに設置できるように
するため、クローリング処理だけを切り出し、環境に
依存しないシンプルなアプリケーションになっていま
す
• そのクローリング部分こそがHoneybee::Beeです
Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.
- 11. スケールアウト
• シンプルな構成のアプリなので環境に依存せ
ず、設置することができます
• 今回は、Amazon Web ServicesのEC2を利
用し、複数のインスタンスに設置することでス
ケールアウトをはかりました
Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.
- 12. 連携のイメージ図
Hive パラメータを送信 Bee
EC2インスタンス
Crawler
EC2インスタンス
Daemon
他のレンタルサーバ
JSONで返す
Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.
- 15. Hiveの機能
• Honeybee::Hiveでは、
• クローリング対象のURLを生成し、データベースに格納
• クローリング処理(Bee側とHTTP通信)
• クローリング結果の重複対応
といった機能が実装されています
• この機能を実行するために、Hive側では2つのデー
モンが用意されています
Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.
- 16. 2つのデーモン
• Crawler Daemon
• インスタンスの管理
• クローリング処理の実行
• Flow Management Daemon
• 全体の処理を順次実行するための、メッセージの
受信と機能の実行を行う
Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.
- 17. Crawler Daemon
Hive Bee
事前処理
EC2インスタンス
クロール処理
Flow
Management Crawler
Daemon Daemon EC2インスタンス
事後処理 他のレンタルサーバ
Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.
- 19. インスタンスの管理
• 今回は、インスタンスの情報をデータベースに格納していま
す
• AnyEventのtimerで、定期的にインスタンスの状態をチェック
し、idleなインスタンスが存在すれば、そのインスタンスを
activeにし、リクエストを送るようにしています
• レスポンスが返ってきたら、使用したインスタンスをidleの状
態に戻します
Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.
- 20. Bee側へのリクエスト
• 取得したidle状態のインスタンスにリクエストを送り
ます
• インスタンスが複数存在する場合も考慮し、インスタ
ンスの数だけ子プロセスを立ち上げ、並列でリクエ
ストを送るようにしています
• 子プロセスは、レスポンスを処理し、インスタンスを
idle状態に戻して終了します
Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.
- 21. Bee側の処理フロー図
Hive Bee
Crawler Daemon
EC2インスタンス
子プロセス (idle)
EC2インスタンス
子プロセス (idle)
EC2インスタンス
(active)
Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.
- 22. インスタンスの管理
use AnyEvent;
use Parallel::ForkManager;
my $cv = AE::cv;
my $timer = AE::timer 0, 1, sub {
# idle状態のインスタンスをデータベースから取得
my $instances =
$api->logic('Instance')->get_idle_instances(1);
my $pm = Parallel::ForkManager->new(scalar @$instances);
foreach my $instance (@$instances) {
$pm->start and next;
・・・ # 次のページで詳細を記述
# インスタンスをidle状態に戻す
$api->logic('Instance')->idle_instance(
$instance->{instance_seq});
$pm->finish;
}
$pm->wait_all_children;
};
$cv->recv;
10/14/2010 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 22
- 23. Bee側とのやりとり
$pm->start and next;
my $crawl = $api->logic('Crawl')->get_crawl;
my $res = $ua->post($instance->{instance_url}, {
seq => $crawl->{crawl_seq},
url => $crawl->{crawl_search_url},
domain => $crawl->{crawl_search_tool_domain}
});
my $content = JSON::decode_json( $res->content );
if ( $content->{success} ) {
$api->logic('Crawl')
->succeed($crawl->{crawl_seq}, $content->{urls});
}
else {
$api->logic('Crawl')
->fail($crawl->{crawl_seq}, $content->{error});
}
$pm->finish;
10/14/2010 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 23
- 24. Flow Management Daemon
Hive Bee
事前処理
EC2インスタンス
クロール処理
Flow
Management Crawler
Daemon Daemon EC2インスタンス
事後処理 他のレンタルサーバ
Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.
- 25. 順次実行される仕組み
• Beeではスケールアウトが重要だったように、Hiveでは処理
フローが順に実行される点を重視しました
• 順次実行される仕組みとして、
• cronなどで定期的に処理のステータス(どこまで実行したか)を確認
することは避けたい
• 処理が実行された後、自動的に次の処理を実行するよう、メッセージ
やシグナルで通知を行う
• 通知を受け取ったとき、次の処理を実行する
という観点で設計を行いました
Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.
- 28. Hiveのイメージ図
Hive
メッセージを送信
事前処理
Flow
Management
クロール処理 Daemon
事後処理
次の処理を実行
Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.
- 29. イベントの処理
package Honeybee::Hive::Event;
use Storable qw/freeze/;
use IO::Socket::UNIX;
sub trigger {
my ( $self, $data ) = @_;
my $serialized = freeze($data);
my $sock = IO::Socket::UNIX->new(
Peer => $conf->{hive}->{socket}
);
$sock->send($serialized);
$sock->close;
}
sub execute {
my ( $self, $event, $args ) = @_;
eval { $self->$event($args); };
carp $@ if $@;
}
10/14/2010 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 29
- 30. メッセージの送信
#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use Honeybee::Hive::Event;
my $event = Honeybee::Hive::Event->new;
$event->trigger({
event => 'prepare_crawl',
args => {
process_seq => 1,
}
});
10/14/2010 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 30
- 31. メッセージの受信と実行
use Storable qw/thaw/;
use AnyEvent::Socket;
use AnyEvent::Handle;
use Honeybee::Hive::Event;
my $event = Honeybee::Hive::Event->new;
tcp_server '', $conf->{socket}, sub {
my ($fh) = @_;
my $handle;
$handle = AnyEvent::Handle->new(
fh => $fh,
on_read => sub {
my $buffer = $handle->rbuf;
my $data = thaw($buffer);
$event->execute($data->{event}, $data->{args});
}
);
};
AE::cv->recv;
10/14/2010 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 31
- 32. イベントの処理
package Honeybee::Hive::Event;
use Storable qw/freeze/;
use IO::Socket::UNIX;
sub trigger {
...
}
sub execute {
my ( $self, $event, $args ) = @_;
eval { $self->$event($args); };
carp $@ if $@;
}
sub prepare_crawl {
...
$self->trigger({ event => 'crawl' })
}
10/14/2010 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 32
- 33. 全体の流れ
Hive Bee
事前処理
EC2インスタンス
クロール処理
Flow
Management Crawler
EC2インスタンス
Daemon Daemon
事後処理 他のレンタルサーバ
Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.
- 35. 今までは...
• 一つのロジックに一連の処理の流れが書い
てあったため、処理の一部分だけをスケール
アウトすることが難しかった
• ロジックを分割したとき、状態遷移を管理する
ためには、定期的にチェックするしかなかった
• 例えば...状態を表すフラグをDBに設けそのフラ
グを定期的にチェックしたり...
Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.
- 36. 今回の設計で...
• 複雑なロジックを出来る限りシンプルに分割
することで、特定の処理をスケールアウトしや
すい設計にした
• crontabなどで定期的にチェックする構成をや
め、各処理の最後で自動的に次の処理を実
行させるようにした
• 今回は、ソケット通信にて実装した
Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.
- 38. まとめ
• 今回の実装コンセプトはほんの一例にすぎま
せんが、こういったアプローチもよいのではな
いかと思います
• ご意見ありましたら是非お聞かせ下さい
Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved.
- 39. 10/14/2010 Copyright Since 1999 © GaiaX Co. Ltd. All rights reserved. 39