« Parallel::Prefork - Perl でマルチプロセスなサーバを書く方法 | メイン | Japanize for IE バージョンアップのおしらせ »
2008年04月07日
Q4M Version 0.4 で高速なクローラを書いてみた
本日、MySQL 5.1 のプラガブルストレージエンジンとして動作するメッセージキューQ4M のバージョン 0.4 をリリースしました。本バージョンでは、条件付購読 (conditional subscription) という、特定の条件を満たす行だけをメッセージキューから読み込む機能に対応したのですが、これを使って、クローラを書いてみました。
使い方は以下のとおりです。
# url テーブルを作成 % mysql -p test mysql> CREATE TABLE url ( id int(10) unsigned NOT NULL AUTO_INCREMENT, url varchar(255) NOT NULL, title varchar(255) DEFAULT NULL, PRIMARY KEY (id), UNIQUE KEY url (url) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; Query OK, 0 rows affected (0.03 sec) # クローラ用のキューを作成 mysql> CREATE TABLE `crawler_queue` ( `id` int(10) unsigned NOT NULL, `fail_cnt` int(11) NOT NULL DEFAULT 0, `failed_at` int(11) NOT NULL DEFAULT 0 ) ENGINE=QUEUE DEFAULT CHARSET=utf8; Query OK, 0 rows affected (0.03 sec) # url テーブルに挿入された URL を巡回するようトリガーを設定 mysql> DELIMITER | mysql> CREATE TRIGGER update_crawler_queue AFTER INSERT ON url FOR EACH ROW BEGIN INSERT INTO crawler_queue SET id=NEW.id; END; | Query OK, 1 rows affected (0.03 sec) mysql> DELIMITER ; # クローラ起動 % ./crawler.pl --dbi='dbi:mysql:test;password=PASS;mysql_enable_utf8=1' & # テーブルに url を追加すると自動的にクローラが走り、ページタイトルを保存 % mysql -p test mysql> insert into url (url) values ('http://q4m.31tools.com/'); ... mysql> select * from url; +----+-------------------------+---------------------------------+ | id | url | title | +----+-------------------------+---------------------------------+ | 1 | http://q4m.31tools.com/ | Q4M - a Message Queue for MySQL | +----+-------------------------+---------------------------------+ mysql>
これだけです。MySQL のトリガーと Q4M を組み合わせることで、複雑なシステムを簡単に構築できる、ということが伝われば幸いです。実際には、解析したい用途にあわせて crawler.pl を改造することになるでしょう。高々 100 行ちょっとの perl スクリプトなので、簡単にいじることができると思います。
また、Q4M を使ったこのクローラは、かなり高速でもあります。Perl ベースのイベントドリブン型クローラのフレームワークであるGungho と比較した場合、手元の環境におけるパフォーマンスの差は以下のようになりました注。
スループット (リクエスト/秒) | 使用メモリ量 | |
---|---|---|
crawler.pl | 168 | 43MB |
Gungho | 80.3 | 19MB |
表を見れば明らかなように、Gungho は比較的低速だが省メモリ、一方、本稿のクローラは高速だがメモリ消費量が大きい、ということがわかります。ただ、消費量が大きいといっても、1ワーカープロセスあたり 5MB 程度。並行処理数を 100 としたところで必要メモリは 500MB ですから、実際に問題になる可能性は低いでしょう。
少なくとも、メッセージキューを使うことで、このように、高速なクローラを簡潔に、きれいに実装できる、という点は、明確に示すことができたと思います。それでは have fun!
注: crawler.pl は --num-workers=10 で測定。Gungho は 64 並列 (spawn => 5, max_open & max_per_host => 64)。また、いずれも実行中 CPU 使用率は、ほぼ100%だった
投稿者 kazuho : 2008年04月07日 17:43
トラックバック
このエントリーのトラックバックURL:
http://labs.cybozu.co.jp/cgi-bin/mt-admin/mt-tbp.cgi/1843