« 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.pl16843MB
Gungho80.319MB

 表を見れば明らかなように、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