ラベル perl の投稿を表示しています。 すべての投稿を表示
ラベル perl の投稿を表示しています。 すべての投稿を表示

2010年1月29日金曜日

オープンソースで構築する非同期分散処理のプラットフォーム

先日のエントリでお伝えした通り、現在新しいビジネスの立ち上げに奮闘してます。

その中で、最近流行(?)の非同期に分散処理するようなプログラムを書きましたのでそれについてエントリを書きたいと思います。

今回作っているビジネスモデルは基本的にサーバーサイドのアプリケーションのリソースを切り売りしていくモデルで考えているのですが、その中で非常に重たい(時間のかかる)処理が存在します。

これを非同期分散処理を行う事で、待ち時間を感じさせないよう工夫しました。Movable Typeを使った事がある方は理解出来ると思うのですが、やっている事は本質的に静的構築とあまり変わりません。あらかじめキャッシュを生成するようなイメージです。

実際の処理の流れを、福岡ITベンチャーヌーラボさんのCacooを使って簡単に図にしました。



図のブルーの図形で囲まれたところが今回開発した処理の部分です。この部分をGearmanというフレームワークを使用して実際の処理を実装しました。本家の図が非常にわかりやすいので、これを用いて簡単にGearmanの説明を。



見ての通りGearmanを使うだけで、Client Application Code(呼び出すときのプログラム)と、Worker Application Code(呼び出されるときのプログラム)の二つを書くだけで非同期処理に必要なAPIやJobQueueの仕組みはすべてGearmanが面倒みてくれます。とても便利!

しかもClient Application CodeとWorker Application Codeは同一の言語で記述する必要がありません。現に今回はClient Application CodeはPHPで、Worker Application CodeはPerlで記述しています。

ではCacooの図に戻って、ブルーの図形の部分は順番に、

  1. APIサーバ: CakePHP, Gearman Client(Gearman PHP Extension)

  2. ジョブサーバ: Gearmand(C実装版)

  3. 変換サーバ: Gearman Worker(Perlで実装)

  4. ストレージサーバ: Apacheが稼働している

となっていて、今回書いた実際のコードはAPIサーバのコードと変換サーバ部分のコードだけです。

ジョブサーバのコードは一切書いていません。これはすごい便利ですよ!

といいつつ、これだけでは何故非同期処理や分散というキーワードが出てくるかわかりにくいのでもう少し突っ込んで解説します。

今回の処理で一番メインの処理は変換サーバの処理です。変換サーバは大きなあるデータを別のデータに変換する事をやってくれるのですが、これが非常に重たい。

そこでAPIサーバからジョブサーバに処理を委託した後、APIサーバはサービスサーバに受付が完了した情報を発行します。ジョブサーバには処理がたまっているので、変換サーバがひとつずつ処理し、結果をまたAPIサーバに返し、APIサーバがそれをサービスサーバに通知して一連の処理が完了します。これを繰り返しているのです。この時変換サーバの処理が重たくても、一時的にAPIサーバが受付完了をサービスサーバに発行するところがキモであり、レスポンス待ちを出来る限り発生させないところが一番オイシイところです。

まだわかりにくい?わかりにくいですよね(笑)

現実のものに例えば方がわかりやすいので、この仕組みを銀行を使って説明します。

銀行へ言って、窓口で口座を開設する時の事を思い浮かべて下さい。まずいきなり窓口へ行く事はなく、最初に整理券を取るでしょう。このときに既にお客さん10人待っていれば11人目になりますね。しばらく待って、整理券に記載された番号を呼ばれれば窓口へ出向き、口座開設の手続きをする。

まさにこの仕組みとそっくりなんです。

  1. 整理券を取る: APIサーバジョブサーバへ作業依頼

  2. しばらくまつ: ジョブサーバで順番待ち

  3. 番号が呼ばれ窓口で口座開設の手続きをする: 変換サーバが実際の処理をする

この通り、似てると思いませんか?

そしてここからが面白いところ。
実際に銀行の窓口は一つだけという事はなく、複数の窓口が設置されていたり、依頼内容によって窓口が異なっている場合が多々あります。
例えば預金口座の開設と借入の為の窓口は別だったりします。また、借入を希望する人が多いと予想される場合はローン申込の窓口を増やしたり、ニッチな要求かつクリティカルな要求(盗難や紛失など)は単独で窓口を設けていたりますよね。

変換サーバ(というかWorker Application Code)はまさにこれと同じであり、窓口を増やしたり減らしたりする事が出来ます。
例えばよくある最初に発生する膨大なスイッチングコストの発生時期だけ大量にWorker Applicationを起動させ処理し、落ち着いたら減らしてマシンリソースを節約。なんて事が可能です!

新機能を取り入れた一部の人にベータ公開したい時や、特急料金を払ってでも速く要求に答えて欲しいときなど、実際のビジネスシーンにおける様々な個別要件を実際にWorker Application Codeとしてあらかじめシステムとして組み込める事がとてもやりやすい。また、突発的に発生した特殊要件についても既存のClient, Worker処理を止めたりする事なく追加したり取り出したり出来るところも簡単に出来るようになっています。

このようにGearmanは大変手軽に組み込めて、各処理は自分の好きなプログラミング言語でかけるというとても素敵なプラットフォームというわけです。非同期に大量のデータを分散処理したいなら、まず検討してよいプラットフォームといってよいと思います。

参考までに現在の構成は、

ジョブサーバ: 1CPU
Client Application: 1CPU
Worker Applications: 6CPU

ですが、大変安定しています。既にジョブサーバはリブート無しで10万件近いジョブを処理しましたが至って安定しています。
非同期処理や分散処理に興味ある方、Gearmanは手軽でオススメですよ!

2008年11月24日月曜日

Shibuya Perl Mongers テクニカルトーク#10 パブリックビューイング 福岡サテライトも同時開催!

11/27に「Shibuya Perl Mongers テクニカルトーク#10」が開催されます。

発表者の一人であるYappoさんのShibuya.PM tech talk #10 の申し込み間に合わなかった人への提案とust時代の勉強会の関わり方というエントリをきっかけに、ここ福岡でも同日パブリックビューイングが開催されることになりました!

Fukuoka Perl Mongerlにて今回のパブリックビューイングが告知されています!
(上記案内ページから申込へ進めます)

今回の提案、そして会議室を快く提供してくれた株式会社Fusicさん、本当にありがとうございました。

codecheck.inのプチミーティングも隅っこで同時開催です。
一粒で二度おいしくなるといいなー。

2008年6月25日水曜日

TheSchwartzを使って重たい処理を非同期に行い、手元はサクサクに

昨日id:rytich経由でGearmanやTheSchwartzというキーワードを知りました。
調べてみるとこれがなんだかとても面白そうで、実装に必要なCPANモジュールも完備されてるので何かやってみようと思い、出来たのはWWW::YourFileHostを使った非同期なダウンローダーです。

codecheck.inに置いてます

これを使うと、こんな感じになります。


  • URLを指定してキューを追加して終了。軽くてサクサク(client.pl)

  • キューに登録されたURLを元にコンテンツをゲット。重たいけどきっちりこなす(worker.pl)



これの何がうれしいかというと、コンテンツをゲットする部分を待たずに、
どんどんゲットしたいURLを投げつける事が出来る事にあります。

通常はコンテンツをゲットする時にリクエストを投げた後、対象のゲットが完了するまで待つ必要があるわけですが、
こうやる事でリクエストを投げる部分においてはそのリクエストをさばいてくれるworkerに投げっぱなしでよいのです。
シェルもすぐ帰ってくるし、次々リクエストだけ先行して行えるわけです。

これは、回線があまり速くない僕のようなユーザーにはありがたい。
バンバン追加して寝て起きたら終わっているみたいな。
今ゲットしてる最中だから終わるまで待っていようとか新しくシェル起動しようとか、そういうのも不要になります。

このclient.pl部分をBookmarklet化して今見ているものをDLキューに登録する。
とか、なかなか便利になりそうな気がしますです(少なくとも僕はw)。

ブクマ登録やreblog等一見処理は単純だけど相手先の状況で処理時間が大幅に変動する。
みたいな場面に置いて、手元の自由がすぐ効くようになるのはとっても便利。

今回、以下のリンクが大変参考になりました。



多分よいこはまねしないほうがいいですヨ

2008年5月23日金曜日

Acme::EyeDrops使ってみた

Acme::EyeDropsという素敵なモジュールを使って、見事Acmeれました。


''=~('('.'?'.'{'.('`'|'%').('['^'-').
('`'|'!').('`'|',').'"'.('['^('+')).(
'['^')').('`'|')').('`'|'.').('['^'/'
).( '{'
^(( '['
))) .((
((( '\\'))))).'"'. (((
'{' ))^',').(('`')| '%') .+(
'`' |',').('`'|'#' ).("\`"| '/'
).( '`'| '-').('`' |((
'%' ))). ('{'^'[') .+(
'[' ^'/' ).( '`'|'/').( '{'
^(( '[') )).( "\`"| '#') .+(
'`' |'/' ).('`'|'$') .''. (((
'`' ))|+ '%').('`' |'#' ).(
'`' |'(' ).('`'|'%' ).+( '`'
|(( '#') )).('`'|'+') .'.' .+(
'`' |')' ).+( '`'
|(( '.') )).+ '!'
.(( '\\')).'\\'.('`'|'.').''. (((
((( '\\'))))))."\"". ';'.( '!'
^(( '+'))).'"'."\}". (( ')'
))) ;$:
=(( '.'
))^ '~'
;$~='@'|'(';$^=')'^'[';$/='`'|'.';$,=
'('^'}';$\='`'|'!';$:=')'^'}';$~='*'|
'`';$^='+'^'_';$/='&'|'@';$,='['&'~';


使い方は上記をa.plとか適当な名前で保存して、
perl a.pl

です。

Welcome!

2008年5月2日金曜日

VimでHTML/CSSを保存と同時にFirefoxのリロードを実現する MozRepl使用バージョン

本日の#codecheckin@irc.codecheck.inでの話題。

k1LoWタンもEmacsでブラウザリロードがやりたげ。でも彼はうぶんつぁーなのでAppleScriptは使えない

mizzyさんからMozReplのご提案

俺も便乗してMozRepl経由のリロードに書き直した

書き直したchangesetは下記です。
VimからFirefoxリロードする処理をMozLabベースに書き換えた
MozReplモジュールを使うように変更した

k1LoWタンも無事に完成したようだ(【Emacs】ファイルを保存したときにFirefoxのアクティブページを更新させる

codecheck.inではこんな感じで楽しくお話をしていますよ!

2008年4月15日火曜日

正規表現に迷ったらRegexp::Assemble

perl -MRegexp::Assemble -E "say Regexp::Assemble->new->add('ab+c')->add('ab+-')->add('a\w\d+')->add('a\d+')->re"

って感じのワンライナーが使える事にたった今気づきました。
上記を実行すると、
(?-xism:a(?:\w?\d+|b+[-c]))

って感じで出力されるので、
$hoge =~ /(?-xism:a(?:\w?\d+|b+[-c]))/

みたいな感じですぐに使えます。

こんなんまでワンライナーでいけるってのが面白いですよねー。

2008年3月11日火曜日

DBD::mysqlがMacPortsでビルドされたMySQLを使う為のオプション

MySQL5はMacPortsでインストール。
Perl5.10.0は/usr/local/perl5.10.0 に野良ビルド。
な環境における、DBD::mysqlのインストール。

普通に
$ cpan -i DBD::mysql

とかやっても、

Can't exec "mysql_config": No such file or directory at Makefile.PL line 76.

Cannot find the file 'mysql_config'! Your execution PATH doesn't seem
not contain the path to mysql_config. Resorting to guessed values!
Can't exec "mysql_config": No such file or directory at Makefile.PL line 466.
Can't exec "mysql_config": No such file or directory at Makefile.PL line 466.
Can't exec "mysql_config": No such file or directory at Makefile.PL line 466.
Can't exec "mysql_config": No such file or directory at Makefile.PL line 466.
Can't exec "mysql_config": No such file or directory at Makefile.PL line 466.
Can't exec "mysql_config": No such file or directory at Makefile.PL line 466.
Failed to determine directory of mysql.h. Use

perl Makefile.PL --cflags=-I<dir>

to set this directory. For details see the INSTALL.html file,
section "C Compiler flags" or type

perl Makefile.PL --help
Warning: No success on command[/usr/local/perl5.10.0/bin/perl Makefile.PL]
CAPTTOFU/DBD-mysql-4.006.tar.gz
/usr/local/perl5.10.0/bin/perl Makefile.PL -- NOT OK
Running make test
Make had some problems, won't test
Running make install
Make had some problems, won't install
Failed during this command:
CAPTTOFU/DBD-mysql-4.006.tar.gz : writemakefile NO '/usr/local/perl5.10.0/bin/perl Makefile.PL' returned status 512


とかむっちゃ怒られます。
シンボリックリンクをはってダマしてもいいんですが、perl Makefile.PL するときに--mysql_config=/path/to/mysql_config というオプションが書ける事に今更気づいたのでメモしておきます。

$ perl Makefile.PL --mysql_config=/opt/local/bin/mysql_config5
$ make && make test && make install

2008年2月27日水曜日

pQuery

Deliciousで知ったのですが、jQueryのPerl版、その名もpQueryってモジュールがあるようです。
なんだよそれ使えばワンライナーでスクレイピングとか出来るのけ?とか思って書いてみたらあっさり出来た。
$ perl -MpQuery -e 'pQuery("http://blog.cohtan.org")->find("h3")->each( sub { print pQuery( $_ )->text() . "\n"; });'

こんな感じで動かせた。おもしろいー。
参考:面白そうだったのでpQueryを使ってみたよ!

久しぶりにブログを書く

最初ログインできなくて焦った。 いや、ログインはできたのだが、ログイン後に自分のブログの管理画面に遷移できず、新しいブログを作成する画面になってしまったからビビッてしまった。 どうやら、Google+(現在はサービス終了)に紐づいたプロフィールを設定しているとこのような状況に陥る...