« 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:
https://labs.cybozu.co.jp/cgi-bin/mt-admin/mt-tbp.cgi/1843