イベント駆動とノンブロッキング #hokkaidopm
DESCRIPTION
2013/08/31 に行われた「Hokkaido.pm #10」 http://atnd.org/events/41429 で20分トークしたスライドです。TRANSCRIPT
イベント駆動とノンブロッキング
尾形 鉄次 (OGATA Tetsuji)
Twitter: @xtetsuji2013/8/31 Hokkaido.pm #10
自己紹介
• 尾形 鉄次 (OGATA Tetsuji)
• Twitter: @xtetsuji
• Blog: http://post.tetsuji.jp/
• Hokkaido.pm は #5から6回連続参加中
• 北海道とPerlが好きな、地元が北海道の人
今回は私の勉強不足とその挽回の話です
会社の部内勉強会で• 後輩と部内勉強会でAnyEvent::IRC::Client
とTwiggyの勉強をしていたときの話
• ライブコーディングでAE::timerなどとも連携してイベント駆動を実感
• 後輩「今つくっているIRCボットが時々応答しなくなることがあるんです」
勉強会中の模索• 後輩「色々調べてはいるのですが…」
• 僕「何かがブロッキングしてる?」
• 後輩「ところでブロッキングとかノンブロッキングとかイベント駆動とかって具体的に何なんでしょう?」
あ、知ったかぶりしてて分からない…
こっそりググる
I/Oブロッキング• ブロッキングの代表例、I/O
• ググって見ても出てくるのはこれ
• 以前のYAPCでAnyEventが流行った時、IO::Socket::INETを使っている事例系で「それブロ(ry」と言われていたやつ
先輩=私の回答• 一つのプロセスがマルチタスクをしているように見せかけるために、時間を細かくスライスして、それ用にタスクを分割してやらせているんだよきっと
• 「それ用」なのがノンブロッキング、そうじゃないやつがブロッキング
色々実験• AE::timerのcbでsleep 10; とか書いてみる
• IO::Socket::INETで待たされるコードをわざと書いてAnyEvent全体を止めてみる
• 普通にIO::Handleで巨大ファイルを複数開いて渾然一体と読めない事を確認
コードリーディング• 後輩「AnyEventのコード読めば分かるんじゃないですかね?」
• 僕「そうだね(うわ、マークレーマン氏のコード、読むの大変そうだ)」
• でも読む
AnyEvent 読む
• AnyEvent.pm から流し読みする
• 僕「根底は while(1) じゃないかな」
• AnyEvent/Loop.pm に迷いこむ
AnyEvent::Loop 読む• なんとなく分かったこと
• 最も解像度の高い場合でも1ミリ秒の時間でスライスしている
• I/Oや時間等のイベントを分割管理
• sub run { one_event while 1; }
AnyEvent::Loop 読む• 時間取得呼び出し(timesシステムコール)
をなるべく抑えるっぽい絶妙な仕組み
• 効率化なのか、すごいリファレンス
• 慣れないと分からないビット演算
• 読んで理解すれば充実感にひたれる?
ここまでのまとめ• 「イベント駆動」は並列処理・マルチタスクを実現するための手法の一つ
• その他、「fork」や「スレッド」など
• マルチCPUとかの知識は別として、OS
レベルで何らかの並列処理はある
イベント駆動ウェブサーバ
イベント駆動ウェブサーバ
• 最近はイベント駆動ウェブサーバ全盛
• C10K問題への対処
• Nginx、Perl製各種ウェブサーバの登場
• prefork MPMが常識だったあのApacheもevent MPMを2.4から正式リリース
Apache prefork MPMの頭打ち問題
Nginx HttpPerlModule
• 早くも現在最新バージョン1.4
• 0.8時代はEmbeddedPerlModuleと呼ばれていた
• mod_perl1の書法の影響が見られる
• 今の名前の通り、HTTPに特化したもの
Nginx HttpPerlModule
Nginx HttpPerlModule
• Known Problemにイベント駆動ならではの注意点が書いてあるけど問題点ではないと思う
• ネットワークI/Oで止めないように気をつけるのは昨今の他のウェブサーバと同様 → ジョブキューへ依頼!
Nginx HttpPerlModule
• Nginx(0.8時代?)に本体にパッチをあててPSGI対応するものはある
• 簡単なPSGI実装であればHttpPerlModule
でできるのでは → 探したけどなかった
Apache event MPM
• 2.2でexperimental、2.4で正式版に
• prefork MPMだと越えられないC10K問題などの壁に立ち向かう、Nginxへの対抗
• ベンチマークを取った人の評判だと、まだ期待したほどのパフォーマンスは出ないらしい
Apache event MPMand mod_perl
• 検討材料となりうる実績は無いはず
• mod_perlがApache 2.4対応していない
• 注意点はNginx HttpPerlModuleと同じか
• これでConnectionフェーズを書いたらどうなるか興味深くはある
宣伝: ModPerl::PSGI
ModPerl::PSGI
• mod_perl2で書かれたのPSGI実装
• Plack::Handler::Apache2をベース
• P::H::A2で対応していないprefork以外のMPMへの対応や、Perl本体とmod_perlのコア以外への依存をなくす等の意欲作
宣伝: ModPerl::PSGI
• Middleware等の資産活用のためにPlack
依存しないWAFではそのまま使える
• MojoliciousではPSGI環境として使える
• 実績が出たらP::H::A2へcontribute予定
workerモデル• preforkとスレッドやイベント駆動とのハイブリッドモデル
• Nginxや最近のPerl製ウェブサーバではこのモデルを採用している
• Twiggyやmorbo等は単一プロセスなので少し注意しておくべき
ちゃんと理解したい• Linuxプログラミングインタフェースを読まないといけないかもしれない
• イベント駆動以前に、forkとかスレッドに関しても造詣を深めておきたい
• 新たなイベント駆動サーバの時代に向けて理解しなきゃいけませんね
まとめ• イベント駆動をちゃんと理解するのは意外に難しいけど、楽しい
• イベント駆動の考え方はウェブプログラマーに必須になっている(e.g. Ajax)
• 続きはGitHubやブログ、YAPCで!
ご清聴ありがとうございました