17
Twib 一人で作るはてブもどき編 yusukebe Yokohama.pm #5 2010/3/4

Twib in Yokoahma.pm 2010/3/5

Embed Size (px)

Citation preview

Twib 一人で作るはてブもどき編

yusukebe Yokohama.pm #5

2010/3/4

Twib ‒ Twitterホットエントリー

Twitterのツイートを元にしたはてブもどき(今のところ) 2009年8月公開

はてブ数1204 users

Twibは、Twitterで話題になっているURLを集計し、ランキングを出してくれるサービス。どんなサイトが紹介されているかをリアルタイムで把握できます。そのURLが紹介されたつぶやきも一緒に見ることができるので、紹介された理由や評価も分かります。

ハードウェアリソース •  Appサーバ x 1 •  DBサーバ x 1 •  どちらも自宅内サービス共有

当初のシステム構成 •  収集プログラムとクローラーの単純構造

Web Page DB Twitter API

FeedReader AnyEvent::Feed

Crawler LWP::UserAgent +

cron

FeedReader sub run {     my $self = shift;     my $cv          = AnyEvent‐>condvar;     my $feed_reader = AnyEvent::Feed‐>new(         url      => $self‐>url,         interval => $self‐>interval,         on_fetch => sub {             my ( $feed_reader, $entries, $feed, $error ) = @_;             if ( defined $error ) {                 warn "ERROR: $error\n";                 $cv‐>send;                 return;             }             for (@$entries) {                 my $entry = Twib::CLI::Feed::Entry‐>new( $_‐>[1] );                 if( my $post = $self‐>create_post( $entry ) ){                 }             }         }     );     $cv‐>recv; } 

問題点 •  ツイートの数が増えてきた – URLを含む日本語ツイート – 2400万/6ヶ月=1.5/秒 – (それでも取りこぼしあるけど…)

•  クロールする対象が増えてきた

クローラー増やしたいよね

Q4Mの導入, 非同期処理

Web Page DB Twitter API

Q4M

FeedReader +StreamReader

AnyEvent::Twitter::Stream Crawler

クロール対象 のURL

画像APIサービス •  http://image.twib.jp/counter/http://twib.jp/

•  http://image.twib.jp/user/yusukebe –  Redirect to : http://a1.twimg.com/profile_images/15300142/profile_childfood_normal.jp

•  http://image.twib.jp/favicon?url=http://yusukebe.com/

ギズモード・ジャパンさん

構成 use Noe; #Plack based WAF use DBIx::Skinny; use Imager; use WWW::Favicon; use LWP::UserAgent; use Cache::Memcached::Fast; 

Apache Squid Starman

Noe •  2クラス + HTTPx::Dispatcher •  http://github.com/yusukebe/Noe package MyApp::Controller::Root; 

sub root {     my ( $self, $c  ) = @_;     $c‐>render('index', { message => $c‐>config‐>{message} } ); } 

sub hi {     my ( $self, $c ) = @_;     my $name = $c‐>req‐>param('name') || 'nanashi';     $c‐>render('hi', { name => $name } ); } sub redirect { 

    my ($self, $c ) = @_;     $c‐>redirect( $c‐>base ); } 1; 

その他チューニング •  DBIx::Class が吐くクエリを観察して見直し

•  被正規化 •  likeの廃止 •  count を使わないような Pager •  それでもまだ遅いので頑張る

     my $rs = $self‐>schema‐>resultset('Link')‐>search(         $args,         {             order_by => 'tweet_count DESC',             page     => $page,             rows     => $rows,             prefetch => $prefech,         }     ); 

    if (wantarray) {           my $next_page =             $self‐>schema‐>resultset('Link')             ‐>search( {}, { columns => [qw/me.id/], page => $page + 1, 

rows => $rows } )‐>next             ? $page + 1             : 0;           return ( $rs, $next_page );     }     else {         return $rs;     } 

取りこぼしという問題 •  API制限ぎりぎりまで •  Parallel::ForkManager を使って複数デーモン起動

•  topsy API を使って上位100位までは取りこぼしの無いように…

Google の インデックス サイトマップの適切な配信 + pubsubhubhub(?) でかなりインデックスされるようになった

今後 •  はてブもどきを極める? •  マーケティング的な何か •  これ系では、国内では一応知名度のあるサービスなのでがんばりんごしたいです