mod perl jobworker - ミクシィグループ新規に作成するにあたり •...

41
Copyright© 2008 mixi, Inc mod_perlをjob workerとして使う理由 ~RSSクローラの設計から~ 株式会社ミクシィ 開発部 長野雅広

Upload: others

Post on 05-Oct-2020

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc

mod_perlをjob workerとして使う理由~RSSクローラの設計から~

株式会社ミクシィ

開発部 長野雅広

Page 2: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 1

自己紹介

• 所属 株式会社ミクシィ開発部 システム運用グループアプリケーション運用チーム

• Blog http://blog.nomadscafe.jp/

• CPANID kazeburo

Page 3: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 2

アジェンダ

• mixiのRSSクローラができるまで

• mod_perlをjob workerとして使う(兼まとめ)

Page 4: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc

RSSクローラができるまで

Page 5: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 4

mixiでのRSS取得・表示

最新日記に表示最新日記に表示

外部外部外部外部ののののブログブログブログブログ等等等等

タイトル・URL・更新日付を取得しmixi上に表示

Page 6: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 5

mixiのRSSクローラ

• User-Agent– “mixi-crawler/2.00 (http://mixi.jp/)”

• mixiに登録されているBlogのRSSをクロール

Page 7: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 6

取得するRSSの数

22万件(2008年5月現在)19万3千件が正常に取得完了

2時間以内に全URLの巡回

Page 8: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 7

現在の構成

インターネット

kicker kicker

manager

script server

kicker kicker

manager

script server

LVS

Apache(mod_perl)

Apache(mod_perl)

RSS DB

Diary DB

memcached

Page 9: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 8

Member DB

以前の設計

fetcher

controller

fetcher

インターネット

RSS DB

Diary DB

cron

fetcher

controller

fetcher

cron

fetcher

controller

fetcher

cron

fetcher

controller

fetcher

cron

ID:0/Max:4 ID:1/Max:4 ID:2/Max:4 ID:3/Max:4

Page 10: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 9

以前の設計の問題点

• Fetcherサーバの耐障害性、Scalability

– Fetcherサーバの障害時

– Fetcherサーバの増設

• 処理速度

– 都度のプロセス起動

– 古いライブラリ

• DBへの長い接続時間

– 運用上好ましくない

Page 11: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 10

Fetcherサーバの障害時

• IDが固定なので、手作業でそのIDを別のサーバや新規サーバに振り替えないとRSSの取得が停止する

controller

fetcher

cron

controller

fetcher

cron

controller

fetcher

cron

controller

fetcher

cron

ID:0/Max:4 ID:1/Max:4 ID:2/Max:4 ID:3/Max:4

member IDの剰余が「2」のユーザのRSSが

処理されない

Page 12: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 11

Fetcherサーバの増設

• すべてのサーバで「全体の台数」の設定の変更が必要

controller

fetcher

cron

controller

fetcher

cron

fetcher

cron

controller

fetcher

cron

ID:0/Max:5 ID:1/Max:5 ID:2/Max:5 ID:3/Max:5

controller controller

fetcher

cron

ID:3/Max:5

NEW

全体の台数を全台で設定する

Page 13: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 12

処理速度

• 都度のプロセス起動

– DBI、XML系のライブラリを毎回読み込み直し

– Perlのプロセス起動自体重い

• 古いライブラリ

– XML::Parserベースのライブラリは処理速度が遅い

Page 14: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 13

新規に作成するにあたり

• クロール時間の短縮

– member idを全部なめることをやめる

– 2時間以内に1周する

• XML::LibXMLベース

• 対応するフォーマット

– Atom 1.0への対応

• 耐障害性とスケーラビリティ

Page 15: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 14

それPlaRSS ParserはPlaggerのそれを利用できるYo!

Page 16: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 15

「それPla」構想

• SubscriptionとPublish

• 非同期アクセス可能なAggregator

Page 17: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 16

非同期のAggregator

• XangoやGunghoよりも軽い実装としてHTTP::Asyncを使う

• Aggregator::Asyncの誕生

– 本家にcommit

Page 18: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 17

HTTP::Asyncとは

• Net::HTTP::NB(LWP同梱)を利用して非同期にHTTPアクセスする

use HTTP::Async;my $async = HTTP::Async->new;

$async->add( HTTP::Request->new( GET => 'http://mixi.jp/' ) );$async->add( HTTP::Request->new( GET => 'http://yapcasia.org/' ) );

while ( my $response = $async->wait_for_next_response ) {# Do some processing with $responseref $response ## HTTP::Response

}

Page 19: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 18

HTTP::Asyncの問題点

• オンメモリ処理

– RSSのURLが数GBのファイルだったら?

• connectは同期処理

– つながらないサーバがあるとブロックされてしまう

– 不特定多数のURLへのリクエストには使いにくい

HTTP::Asyncが適用しやすい場所1. アクセス先のコンテンツのサイズが確認できる

2. connectが一瞬で完了するローカル接続

Page 20: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 19

「それPla」構想

Page 21: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 20

mod_perlをworkerとして使う

Page 22: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 21

mod_perlを使うアイディア

• 最初のアイディアはメルマガの設計

Page 23: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 22

メルマガ「コミュニティニュース」

• 1通1通ユーザ毎に異なる内容のメルマガ

– mixiのホームの内容が主

– DBやmemcachedを参照しながら本文を作成して送信

Page 24: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 23

メルマガの効率化

• mod_perlで通常のページを作るように作る

– HTMLを書き出す代わりにメールを送る

– そのアプリケーションサーバにRequestをHTTP::Asyncで送る

– mod_perl1台でもMaxClientsの設定まで並行処理が可能

– Scalabilityについては、アプリケーションサーバ(mod_perlサーバ)を増やすだけ

Page 25: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 24

メルマガ「コミュニティニュース」

Apache(mod_perl)

Apache(mod_perl)

Apache(mod_perl)

HTTP::Async

script server

SMTP SMTP

インターネット

Page 26: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 25

RSSクローラへの展開

• リクエストを受けると、1つのFeedを取得し、解析、DBへの格納を行う

– シンプルな1つのjobに

• そのサーバに対して、HTTP::Asyncを使いリクエストを行う

– リクエストを行うプログラムをkickerと呼んでいる

Page 27: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 26

kickerの設計

• kickerの耐障害性をあげる

– 冗長性を確保

• Scalability

– サーバを足すだけを目指す

• DBへの長時間の接続はしない

– 運用上の理由

• 動作速度

Page 28: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 27

kickerとkicker manager

• 一定数処理したら終了するkicker

– 動作速度とDBとの接続時間の短縮の両立

• DBとの接続は行わずkickerを管理するだけのmanager

kicker kicker

manager

script server

RSS DB

Page 29: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 28

kicker managerの設計

• POE

– Wheel::Run

– Component::Server::TCP

• PoCo::Server::TCPで任意のportをlisten

– 簡単に状況を確認できる

– nagiosで外部から監視

Page 30: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 29

kicker manager(一部ソースコード)

sub wheel_init {my ($kernel, $heap) = @_[KERNEL, HEAP];$kernel->alias_set('wheel_ctl');$kernel->post('wheel_ctl','wheel_settimeout');

}

sub wheel_settimeout {my ($kernel, $heap) = @_[KERNEL, HEAP];my $procs = $STASH->{procs};my $time = time() - 10*60; #10minmy @freezed_procs;foreach my $id ( keys %$procs ) {

push @freezed_procs,$idif $procs->{$id}->[0] < $time;

}foreach (@freezed_procs) {

$procs->{$_}->[1]->kill(9);}if ( keys %$procs < $OPT{MAX_PROCS} ) {

$kernel->post('wheel_ctl','wheel_start');}$kernel->delay( 'wheel_settimeout', 1 );

}

sub wheel_start {my ($kernel, $heap) = @_[KERNEL, HEAP];

my $wheel = POE::Wheel::Run->new(Program => [qw/perl kicker.pl/],ErrorEvent => 'wheel_error',CloseEvent => 'wheel_close',StdoutEvent => 'wheel_stderr',StderrEvent => 'wheel_stderr',

);

my $pid = $wheel->PID;$kernel->sig( 'CHLD', 'wheel_sigchld' );$STASH->{procs}->{$wheel->ID} =

[time(), $wheel];}

Page 31: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 30

kicker managerの冗長性

• 2台以上のサーバで動く

– 処理が2重にならない工夫が必要になる

Page 32: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 31

処理が2重にならない工夫

CREATE TABLE `rss_data` (member_id int(10) unsigned NOT NULL default '0',url varchar(255) NOT NULL default '',last_crawl datetime NOT NULL default '1970-01-01 00:00:00',fetcher_seed tinyint(3) unsigned NOT NULL default '0',PRIMARY KEY (`member_id`),KEY `last_crawl` (`last_crawl`,`fetcher_seed`),

) TYPE=InnoDB;

DBの設計

urlをinsertする際にfetcher_seedに0~59までの整数を入れておく

Page 33: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 32

処理が2重にならない工夫(2)

SELECT * FROM rss_dataWHERE fetcher_seed=? AND

last_crawl < ? ORDER BY last_crawl LIMIT 1000

取得対象URLのSELECT

fetcher_seedはmemcachedのincrementで生成

my $incr = $memcached->incr( 'fetcher_seed' );my $seed = $incr % 60;$sth->execute(

$seed,DateTime->now->substract(hour=>2)->format(‘MySQL’),

)

Page 34: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 33

kickerのScalability

• kicker managerで複数個のkickerを同時起動

• kickerおよびkicker managerが動作するマシンを増やすことでrequestの回数を増やし続けていくことができる

Page 35: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 34

完成

インターネット

kicker kicker

manager

script server

kicker kicker

manager

script server

LVS

Apache(mod_perl)

Apache(mod_perl)

RSS DB

Diary DB

memcached

Page 36: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc

mod_perlをjob workerとして使う(兼まとめ)

Page 37: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 36

mod_perlを使った利点

• Apacheで並列処理をみてくる

• Apacheでメモリの管理もできる

– MaxRequestPerChild

– startup.plでのメモリ効率化

• Web Application Frameworkをそのまま活用できる

• デプロイツールがそのまま使える

• 監視も行いやすい

• サーバを足せばスケールする

• APIとしてもつかえる

Page 38: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 37

mod_perlを使うTips

• jobを細かく分割する

– 並行処理度を高める

– 障害時の範囲を狭くすることができる

• Requestを非同期に行うクライアントを用意

– HTTP::Asyncはお勧め

Page 39: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc

以上

Page 40: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc 39

エンジニア募集してます

• mixiでは一緒に働くウェブアプリケーション・エンジニア、システム・エンジニアを募集しています

採用サイト:http://mixi.co.jp/job/

Page 41: mod perl jobworker - ミクシィグループ新規に作成するにあたり • クロール時間の短縮 – member idを全部なめることをやめる – 2時間以内に1周する

Copyright© 2008 mixi, Inc

質問などありましたらお気軽にどうぞ