ホーム

へぼい日記

#isucon 4 予選参加してきました

  • 投稿者: chiba
  • 2014/9/29 月曜日 18:53:44
  • perl

毎年でているISUCONに今年も山形組として参加してきました。

今年もオンライン予選があり、9/27の一日目に参加し結果は暫定で7位でAMI審査に問題がなければほぼ予選通過はすると思われます。

で、今年は何をやったか、というとあいも変わらず去年と同じことをしておりました。去年と同じ方式でかくと

やったこと

静的ファイルはnginx serve
アプリ全書き換え
 1fileなPSGI
 データはすべてオンメモリ
 永続化はテキストファイルへ追記
nginx embedded perl + Plack::Handler::Nginx ←NEW!

最終形の構成をgithubにおいときました。

やれなかったこと

無し

最終提出スコア

–workload 8で
62145

コンテスト中の流れ

事前にHDD8G メモリ15Gのm3.xlargeインスタンスだとわかっていたので、それがボトルネックの解消につながるかは別として、インメモリDBアプリにすることは可能だとわかっていました。
で、蓋をあけてみたらいままでで最も簡単な内容のアプリだったため、いつもの通り全書き換えしつつのインメモリDBアプリをFeersumで動かす方針に決定。
もう一人のメンバーにクエリ書き換え等の王道チューニングを進めてもらいつつ、14:10ごろに書き換えとバグとりが完了。workloadの調整などをおこない、14:20ごろにworkload:5 58000ぐらいのスコアで提出。この時点では2位。nginxによるキャッシュをいれて、14:28ごろ、workload:6 60806で提出。1位。
この時のチャットログ

9/27 14:28 
workload:6
tag:benchmarker type:score      success:281500  fail:0  score:60806
で提出完了
9/27 14:28
もうほぼ限界だとおもう
...中略...
9/27 14:31
もう10チーム以上6万台の誤差勝負とかにならない限りは大丈夫だとおもう

というわけでしばらくのんびりしていたら、いつのまにか7万点台のスコアを叩き出すチームが現れ…。

16:13
うおおおおおおおおおおおおおお
16:13
7万ごえきた
16:13
YABAI!
16:18
まじか…
16:21
nginx embededやるか…

と、この時点では、nginx->feersumというリバースプロキシ構成だったので、nginx embeded perlで完全に1プロセスにしてしまうことに。
で、nginxのビルドやPlack::Handler::Nginx自体への修正なども行い、新たなバグとも戦いつつ

17:47
tag:benchmarker type:score      success:287690  fail:0  score:62145

で、フィニッシュとなりました。もっとスコアが上がって7万点台に届くとおもっていたので、トップの人はどうやってるのか謎すぎる状態での終了でした。
結果も更に順位が落ちて7位となっていました。

感想

で、workload解法があったということだったのですが、まあこういうことも含め競技だとは思っていますので結果には納得していますし、その後の運営の対応も素晴らしいものでよかったと思っています。

出題内容は、過去のパターンと比較しても優しすぎて、参加人数が増えている今となっては上位スコアが団子状態になってしまってるんじゃないかなぁと。いろいろな制約の上での出題だと思いますので、難しいところではあるとは思いますが。

本戦はもちろんそういったことにはならないと思っていますので、(出場できるであれば)準備を万全にして臨みたいと思っています。

なにはともあれ、出題されたクックパッドの皆様、主催・共催のLINE、DATAHOTEL、Amazonの皆様、ありがとうございました。
本戦の出場が正式に決定しましたら、その際はまたどうぞよろしくお願いいたします。

はてなブックマーク - #isucon 4 予選参加してきました

#isucon 負けてきました

  • 投稿者: chiba
  • 2013/11/10 日曜日 18:30:30
  • perl

ISUCON3本戦に毎度おなじみ山形組で参加してきました。結果は過去2回の出題者チームであるLINE選抜チームが圧倒的スコアで優勝という結果で、さすがでした。

うちは一応本番計測で完走したため5位という結果でしたが、途中経過では11位ぐらいをさまよっていましたので惨敗といって良いと思います。
ちなみに、予選も含めた過去4回の本番計測すべてを完走しているのはうちだけじゃないでしょうか。パーマネントなチーム自体が少ないので個人単位ならいるかもしれませんが。

やったこと

nginx化
serve static
x-accel-redirect
既存画像の事前リサイズ
新規画像のPOSTはオリジナルを置くだけにして、リサイズをApp::watcherで実施
明らかに無駄なコードの最適化

やれなかったこと

インメモリDB化
画像ファイルのストレージ分散
新規画像のリサイズ処理のCPU分散

コンテスト中の流れ

いつもどおり開始から1時間ほどは現状分析を行い作戦会議をしたのですが、初期画像データがだいたい3Gあり、そのSML版を作ると最大12Gになるからこれをメモリ4Gの4台でうまくすべてをファイルキャッシュにのせるようにしましょう、で、変換もそれぞれの分散先のサーバ自身で変換するようにしましょうと話していました。のちにimageのL版はなく、さらにオリジナルの劣化版をつくっておけば(LINEチームはそれで画像サイズを1/3ぐらいにしたそうです)1台でもそれなりにキャッシュにのることを知ることになるわけですが。

あとは、転送量制限が最終的には問題になるからフロントは5台にして内部のアプリケーションサーバ(1台)にPrivate IPでリバースプロキシしましょう、という戦略でした。(アプリケーションサーバが1台なのはインメモリDB化を見据えていたため)

画像の転送はNFSという話もあがったのですが、アプリケーションサーバを画像ストレージ用のサーバにも置いてそこにPOSTすれば楽にいけそうですねとなりました。

あとはいつもやっているアプリケーションの書き換えは今回はさすがに他にやることが多すぎて無理っぽいので部分書き換えで、最終的にはmysqlのデータのインメモリ化までいけたらいいね、といっておりました。

結果、最初にたてた戦略の半分も実行できず、既存画像の事前リサイズで6800ぐらいを出したところでボトルネックを見失い、timeline等のmysqlのクエリチューニングに走ってしまい、そこからはたいしてスコアがあがらずに時間の浪費。

終了30分前ぐらいに、そういえばworkloadをあげてなかったと、あげてみたところ新規画像のリサイズのCPUボトルネックになってFAILすることがわかったのですが、もう時間的に根本対策は無理で終了。

感想

予選のあとにインメモリDBどうなの話の流れで @methane さんが

っておっしゃってたのを見ていたので、「あ!ここtwitterでやったやつだ!」となりました。

アプリケーションロジックやMySQLのチューニングがボトルネックになるのは多分まだまだ先の話で、まずは画像の配信時の処理を速くすることと、workloadをあげていった時に新規画像の生成(CPUボトルネック)をいかに矛盾なく速くするかという戦いだったように思います。(自分は後者の戦いにはほぼ参加できていませんが)

あとはアプリケーションの複雑性があがっていたり、まっさらのサーバが4台あったり、既存データの処理を別途する必要があったりで、発想と瞬発力だけではなく、きちんとチームとして機能していないと勝てないようになっているように感じました。(正直二人ではきつかった)

ということで、かなり悔しい思いでいぱいですので、来年またあったら3人目の組員と共に参加したいとおもいます。

主催/共催のカヤック、LINE、DATA HOTELの皆様ありがとうございました。

はてなブックマーク - #isucon 負けてきました

#isucon 3 予選総合3位でした

  • 投稿者: chiba
  • 2013/10/7 月曜日 2:41:23
  • perl

毎年でているISUCONに今年も山形組として参加しております。

今年からオンライン予選があり、10/5の一日目に参加し結果は現在のところ暫定で3位で予選通過の予定です。
暫定なのは使ったサーバの運営側による検査が残っているためです。

で、今年は何をやったか、というとあいも変わらず去年と同じことをしておりました。去年と同じ方式でかくと

やったこと

アプリ全書き換え
 1fileなPSGI
 https://gist.github.com/nihen/6852251
 feersum(1プロセスマルチスレッド)
 データはすべてオンメモリ
  スレッド間でシェア
 永続化はテキストファイルへjsonで追記
html renderのキャッシュ(といってもmarkdownぐらいか)
リバースプロキシをnginxにして静的ファイルもそこでserve

やれなかったこと

benchmark –workloadの試行
さらなるhtml renderのキャッシュ(メモリストの各liとか)
POST後に与えられている1秒間の猶予の活用
nginx embedded perl
 Plack::Handler::Nginx
 二年ぶりにnginx,perlそれぞれ現在の最新バージョンでやろうとしたらまったく原因不明のbugった挙動になっており、断念

コンテスト中の流れ

まず始まる前から決めていたのは、外部要件をブラウザで丁寧に確認するということでした。
予定通りこれを時間をかけて行い、その後それに対応したコードの読み込みを行い予め取り決めていた11:30にそれを打ち切って作戦会議。ここまでコードやサーバに変更は一切なし。ベンチマークは初期状態で実行しました。

作戦会議の結果、前回と同じ手法が使えるはずと決まり、実装開始。今回は前回よりアプリケーションとして複雑というのもあり途中少し諦めかけるも、14時ぐらいには完成。意気揚々とtestを実施するもFAIL。まあ一発で成功するとおもってもいなかったので出てきたメッセージを元にひたすらデバッグ。しかしだいたいめぼしいバグとれただろう…という段階になっても原因不明なFAILがまったくとれなくなり、ここでひたすら時間を浪費する。

2013/10/05 16:58:11 [FAIL] Post http://localhost/mypage: EOF
2013/10/05 16:58:11 [FAIL] Post http://localhost/mypage: EOF
2013/10/05 16:58:12 [FAIL] Post http://localhost/memo/41324: use of closed network connection
2013/10/05 16:58:12 [FAIL] Post http://localhost/memo/41326: use of closed network connection
2013/10/05 16:58:12 [FAIL] Post http://localhost/memo/41325: EOF
2013/10/05 16:58:12 [FAIL] Post http://localhost/memo/41328: EOF
2013/10/05 16:58:12 [FAIL] Post http://localhost/memo/41327: EOF
2013/10/05 16:58:21 [FAIL] Get http://localhost/recent/35: EOF
2013/10/05 16:58:41 [FAIL] Get http://localhost/recent/89: EOF
2013/10/05 16:58:45 [FAIL] Get http://localhost/recent/31: EOF
2013/10/05 16:58:46 [FAIL] Get http://localhost/recent/60: EOF
2013/10/05 16:58:56 [FAIL] Get http://localhost/recent/168: use of closed network connection

出てたエラーはこんな感じ。ログに書かれている時間を見ると分かるように、この状態で残り1時間を切るという状態に追い込まれておりました。もうこれはだめかもわからんね、という話をし、ここから1時間王道チューニングで足掻こう…と既存アプリのチューニングを始める。

計測はしていないものの全要件をコーディングしていたおかげでボトルネックはなんとなく把握していたので、ボトルネックの解消自体は順調に進められたのだけれども、いかんせん時間が足りそうになくその頃既に1位は3万点台を計測しており、もうこれはやはりFAILを取ることに全力を傾けたほうが後悔はないだろう、と再度17:30ごろにFAILをとることに舵を切り直す。

で、実はFAILをしていたときはテストがしやすかろう、とFeersum単独で80ポートをlistenしていたのだけれども、Apacheからリバースプロキシというもとの構成にもどしてみる。しかしまだFAIL。ここで静的ファイルをApacheでServeをやっていないことに気づくもAliasの書き方等をぐぐる時間も無かったので、豊富にローカルに設定を持っているnginxに切替え、静的ファイルのserveをしたところ…Success!。急いで本番用のbenchmarkコマンドを実行し、32270点を出したのがたしか17:45ごろ。あとはちょこちょこアプリを修正しつつ終了。正直いまだにFAILの原因は分かっておりませんのでベンチマークツールが公開されたらじっくりしらべてみようと思います。

というわけで長々と書いてしまいましたが、つまりギリギリまでスコア提出をほとんどしていなかったのは高度な情報作戦でもなんでもなく単純にFAILしていたからなのでした。

感想

前回参加からのこの一年の間に、幸運にも負荷を要因としたスケールアウトが必要になるような案件に携わらせていただいており、そういった王道チューニングもいいだろうなぁと思いつつも、いまの自分の実力的にはやはりこの飛び道具を使わざるを得なかったというのが実情ではあります。

今回はKlabさんのチームも似たようなアプローチで2位にはいっており、運営のfujiwaraさんも対策すると言明されているので、本戦でまったく同じアプローチが通じるとは思っていません。本戦まで本業のほうも含め王道チューニング的な経験値、やはり増やして臨みたいところですね。

主催されたfujiwaraさんをはじめKayacの皆様、LINEの皆様、いつもこんなに熱く楽しいイベントを開催していただきありがとうございます。
本戦の出場が正式に決定しましたら、その際はまたどうぞよろしくお願いいたします。

はてなブックマーク - #isucon 3 予選総合3位でした

#ISUCON2 で特別賞を頂いて来ました

  • 投稿者: chiba
  • 2012/11/4 日曜日 14:08:29
  • perl

というわけで前回に引き続き山形組として参加してきました。

まとめブログはこちら

結果は、スコア18万切りに最初に到達すると頂ける特別賞を16時ごろ10万ちょうどぐらいのスコア(スコアは低いほうが優秀)で頂いたものの、その直後に藤原組さんにさくっと8万あたりのスコアで抜かれ、こちらも9万台のベストスコアはだしたものの、最終結果は10万あたりで、藤原組さんは8万台で2位で終了。

スコア的には僅差だったので正直かなり悔しいですが、藤原組さんは「実運用に突っ込んでも運用が破綻しない状態」を維持されていたようで、うちはかなりチート手法でしたのでこれはもう完敗ですね。次があったら正攻法で戦えるように経験値を上げて望みたいなと思いました。

やったこと

アプリ全書き換え
 1fileなPSGI
 https://gist.github.com/4006644
 feersum(1プロセスマルチスレッド)
 データはすべてオンメモリ
  スレッド間でシェア
 部分的なhtmlのキャッシュ
 永続化はテキストファイルへjsonで追記
リバースプロキシだけでアプリも立ち上げ
 つまり動いてたのは一台だけ
  DBサーバがスペックよかったのでそっちでアプリうごかせばよかったかも。
リバースプロキシをnginxに

やれなかったこと

永続化の遅延
リバースプロキシでstatic serve
 なぜかやるとFAILした
  これがkazeburoさんの罠とざわつく
nginx -> feersum間をkeepalive
nginx embedded perl
 Plack::Handler::Nginx
 上記のFAIL問題で焦ってて時間なくなってできなかった
TIME_WAIT対策
 reuseつかったらFAILした
  他の問題かも

コンテスト中の流れ

前回の感想ブログエントリに書いた通り一人Isucon1をやっていたときに、nginx embedded perlでデータはすべてオンメモリが最速という結論を得ていたので、その方法がとれるようであれば今回もやろうと事前に考えていました。

今回は最初にぱっと構成をみたときにstockデータがそれなりに大きかったのでこれはオンメモリは無理か?と思ったもののvariationごとの64*64の単純なデータ構造だったのでこれは計算でいける、とオンメモリ化でいく決断を開始一時間後ぐらいにする。

であれば用意されているアプリとはまったく考え方が違うので、一から実装のほうが早いと判断し、がりがりとコードを書き始める。で、途中お昼食べたりしつつ4時間ほどでできたのがこれ。今回の参加者中キータイプ数なら間違いなく一位だったと思う。KINESIS最高!作り方としては既存アプリのコードはなるべく見ないでブラウザから外部仕様の動作確認をしつつ移植という感じ。

オンメモリデータの一枚psgiなので手元の環境のplackupのみで簡単に動作確認できるというのは一つの強みだったとおもう。

で、それをデプロイしていくつかの移植ミスによるFAILをクリアしたところで10万スコアがでて特別賞。

その後nginx embeddedに進むためにもstatic serveをnginxでしたところなぜかFAIL。
このあたりから完全に迷走し、いろんなことに手をだし(nginxの最新バージョンを試したりtime_wait問題の解決を図ったり)何が原因でFAILしてるのかも見失う状態になり肝心のnginx embedded perlの作業に入れず、とりあえずFAILを解消しよう!といろんなことをrollbackしてなんとか完走するようになったところでタイムアップ。

感想

普段負荷を要因としたスケールアウトを必要とするような仕事をほとんどしておらず、安易なスケールアウト戦略に疑問をもっているというのもあり、世間で王道とされていることに対するアンチテーゼとして、この実装で優勝するということを密かに狙っていました。

会場では「業務には役に立たないチートです」と言いましたし王道な藤原組さんに結局負けてるわけですが、「なぜスケールアウトするのか」という点を考えるきっかけになってもらえたらいいなぁと思っています。

インフラチームが4台用意してくれてるんだからとりあえず4台使って分散してみるか~という安易な考えではなく、ボトルネックの解消や冗長性のためなど具体的な測定結果や理由によりスケールアウトするべきなんだろうなぁと。

まあ負け犬の遠吠えですが!

主催されたNHNのスタッフのみなさん、こんなに楽しいイベントを開催していただき、本当にありがとうございました!

はてなブックマーク - #ISUCON2 で特別賞を頂いて来ました

YAPC::Asia Tokyo 2012に参加してきました

  • 投稿者: chiba
  • 2012/9/30 日曜日 20:13:06
  • perl

参加してきました。YAPC::Asia Tokyo 2012

初発表してきました

Tengにpull requestをよく送っていたからか、nekokakさんにやりませんかとIRCで声をかけて頂いて、やりますーと軽く答えて参加申し込みをしたはいいものの、ちゃんとした話ができるのか不安でしかたがなく、直前は緊張で吐きそうになるなどしつつ、発表者席に向かったところ目の前にnekokakさんが陣取っており(その場ではじめましてのご挨拶(!))、プレッシャーでクラクラしながらも、なんとか発表させていただきました。

反省点は多々ありますが、なんとか最後まで喋りきることはできたので一応満足はしています。今後は自分のプロダクトでの発表や、40分枠で喋れるような濃い発表ができるように日々意識して活動していこうと気持ちを新たにしました。

プレゼン資料公開しておきます。

追記: 2012/10/6 動画アップロードされたみたいです。

聞いてきた

もろもろのお仕事の事情により、参加は発表日の午後から。(発表日午前いけなかったのは起きれなかっただけだけど!)

Perl 今昔物語

僕はYAPCは2007年の津田塾以降の参加。ここ数年(PSGI/Plack以降って感じなのかな)新しいPerlのプロダクトとかでてきてないよねーという話はまあそうなのかもなと。
他の言語でも最近は落ち着いてるんじゃない、という話もあったけど印象としてRuby界隈は活発に見えるし、実際RubyGemsの数がCPANモジュール数を超えている(count方法に異議はあるとのこと)という話をその後のLTでcharsbarさんがされていましたね。

10 more things to be ripped off

スライドはこちらのようです
裏番組のPerl と SQL のいろいろは自分の発表と内容も関係ありそうだし、場合によっては発表中で触れるためにも見ておきたかったんですが、miyagawaさんのこのトークはmiyagawaさんだからってのを差し引いても、内容的にやっぱりどうしても見ておきたかったので。
bundler to Cartonの話は今一番興味がある話で(これの話とかcpanfileの100%実装とか)、未実装の部分を開発してくれる人歓迎というようなことをおっしゃっていたので一念発起してみるつもりです。他のプロダクトも興味あるものがいくつかあったので要チェックでしたね。

Perlハッカーは息をするようにCPANモジュールを書く。

まとめが、githubに眠っているモジュールをドキュメントをちゃんとかいてCPANにアップしよう!というような話だったので、勢い余って質問で「githubに眠っているPath-AttrRouterはいつCPANにアップされますか?」という嫌がらせのような質問をしてしまい、流れでドキュメントを書きますと宣言をしてしまいました…。や、やりますよ!そ、そのうち!

— 発表が近づきおぼつかない足取りで外をふらふらとうろつくなど記憶が曖昧な時間帯 —

Lightning Talks Day 2

あいかわらずみなさんおもしろい。正直あそこには一生立てる気がしないです。あ、途中karupaneruraさんがTengを絡めた話をされてましたが、自分の理解力が足りず内容が半分も理解できなかったのでスライドの公開を待ちます!

How Perl Changed My Life

やっぱりmiyagawaさんには影響されちゃいますよねー、あるあるという感じでした。

また来年?

また来年も開催されるのかはやはり明言されなかったみたいですが、あるときに備えておきます!
こんなに素晴らしいイベントを運営されているボランティアスタッフの皆様、本当にお疲れ様でした!

ところで、このブログはすっかりイベント参加報告ブログと化していますが、最近はheboi blogのほうでカジュアルに書いています。

はてなブックマーク - YAPC::Asia Tokyo 2012に参加してきました

YAPC::Asia Tokyo 2011に参加してきました

  • 投稿者: chiba
  • 2011/10/16 日曜日 19:36:39
  • perl

YAPC::Asia Tokyo 2011に参加してきました。

ブログ書くまでがYAPCというわけで印象にのこったセッションを中心に参加報告を。

前夜祭

myfinderさんの「サービス運用者のための継続的監視」はさすが日本で1番目か2番目か3番目のSNSの運用をされてるだけあってさすがという感じでした。自分は小規模システムばかりやっていて開発者も運用についてかなりコミットしなきゃいけない状況で働いているのですが、ここまできちんとできてないなーと痛感。さっそく監視項目をどんどん増やしていこうと思いました。

会場外のプチ懇親会的なものでは、ほぼボッチでしたが夏菜子推しTを装備していたsugyanさんと初めて挨拶させていただくなど。

一日目

寝坊&体調不良で昼から参加。Jesse Vincentさんの「Perl 5.16 and beyond」とmalaさんの「Webアプリケーション高速化」が聞けなかったのが残念。動画とか公開されるのかな。

onishiさんの「新はてなダイアリーの裏側」では、はてなダイアリーが今秋Hatena Blogになることが発表されたりしていて、ユーザ毎サブドメイン運用でjavascript解禁なんて話があってセキュリティ対策とかどーなのかなーと興味深かったです。二日目のcho45さんの「ぼくがかんがえたさいきょうのうぇぶあぷりけーしょんふれーむわーく 」でそこらへんの話も詳しくされたぽいのですが裏セッションを聞いてて見れなかったです。

徳丸さんの「Webアプリでパスワード保護はどこまでやればいいか」ではレインボーテーブルの原理を丁寧に説明されていて(徳丸本にも書いてあるのですが読み飛ばしてしまっていたので)、なるほどなーと思ったり、高速化するGPUの脅威に対抗するためにサービス側でもGPUを使ってハッシュ生成(ストレッチング回数を増やす)するという対策を示しておられたのが印象的でした。

makamakaさんの「Perl Mongerなりきりカードゲームの考案と実践」はとにかく面白すぎましたw会場のウケをとった回数だけならきっとベストスピーカー賞なんじゃないでしょうか。

懇親会ではほぼボッチでしたが、miyagawaさんに僕のビール持って行っちゃってませんかという(濡れ衣の)難癖をつけるなどしました。(わざとじゃありません。すみません)

二日目

若干遅刻気味だったので大岡山駅からダッシュで会場に向かい、ぎりぎりkazuhoさんの「続 Unix Programming with Perl」の開始に間に合いました。昨年の発表もそうでしたが正しくプログラミングするとはどういうことなのかということを徹底的に意識されている感じで非常に勉強になりました。

Ricardo Signes(rjbs)さんの「闇のEメール伝説」はEmail::モジュールの話をするのかなーと思って行ってみたら、SMTPやMIMEのRFCにまつわるメールのカオス状況をおもしろおかしく発表されるという感じでした。英語は正直ほぼ聞き取れてなかったのですがスライドを見るとだいたいは把握できたし、メールアドレスの正規表現をやってたときにRFCがupdateされて古いRFCがobsoleteになっても新しいRFC自体にobsなsyntaxが残ってたりしてカオスってるのを把握してたのでそうそうそうだよねーという感じで楽しく聞けました。

スイーツエリアで開催されたmotemenさんの「Teto でニコニコ音声ストリーミング 」は便利そうだし、技術的にも面白そうなので是非使ってみてコードも読みたいなーと思いました。

勝手に後夜祭では、ほぼボッチは回避しつついろんな方と話すことができました。途中YappoさんとEmail::Senderの非Moose化てどうなんでしょうねーという話をしていたらcharsbarさんに折角本人がいるんだから直接いいなよとrjbsさんの前に連れていかれcharsbarさんに通訳をしてもらいながらお話を聞くことができました。RoleがMooseとMouseで完全に共通化されてないからAny::Mooseは使えないよねーという話だと理解したのですが正直完全には理解できず。英語ェ…。周りに集まってきたPerlHackerの面々が直接英語で議論しているのを目の当たりにしてほんと英語どうにかしないと駄目だなと再度感じた次第。charsbarさんその節はありがとうございました。力不足で大して議論を深める役には立てませんでしたが貴重な経験になりました。

というわけで三日間非常に楽しめました。
牧さん櫛井さんをはじめJPAのみなさん、ボランティアスタッフのみなさん、スピーカーのみなさん、お疲れ様でした&ありがとうございました。
来年はスピーカーとして若干でも貢献したいとおもいます!

はてなブックマーク - YAPC::Asia Tokyo 2011に参加してきました

ISUCONに参加してきました

  • 投稿者: chiba
  • 2011/8/30 火曜日 3:18:58
  • perl

なんでもありのWebアプリケーション高速化バトル、#isuconに山形組として参加してきました。
結果はみなさんご存知の通り、藤原組さんの圧勝という感じになりました。
自分はというと、DBボトルネックの解消までは藤原組さんとほぼ同じ手法で解決して、4700req/minあたりのbest scoreを出した後には有効なチューニングが行えずにnginx導入の罠にひっかかって200req/minとかになってしまって泣きながらapacheに戻したりしつつ、最後はサイドバーのcacheをmmapにいれる作業をしていたらバグでfailするようになってしまってぎりぎりでDBのボトルネック解消直後にロールバックして、10000req/3minくらいがたしか最終スコアだったと思います。failしたチームを除けば下から数えたほうが早い感じになってかなり悔しい結果でした。

DBボトルネック解消直後にappサーバを一つにしぼったところたいして結果は変わらず、ああたかが10並列だしサーバ分散するほうが無駄なのかなとリバースプロキシでplackで直接80番ポートをlistenするとどうなるかなーと思ったりもしていたのですが、debianでdaemontools慣れしていた自分はceontosでsupervisordという構成にひるんでしまってそこまで踏み込めなかったので、帰ってきてからPSGI単体のアプリでどこまでチューニングできるかってのをやってみました。

で、できたのがhttps://gist.github.com/1178857これです。Feersumで動かしてあげると、自分の環境で96550req/minのベストスコアがでました。一応永続化もしているので(デーモン化の設定さえすれば)再起動後も有効な、ISUCONレギュレーション完全対応なPSGIアプリになっています。ISUCONアプリの全体像を簡単に見通したい方にもオヌヌメです。といってもこのやりかたはたかが10並列でたかが3分間のアクセス(とpost数)とわかっているからできる構成なので実際の運用にそのまま生かせるような内容にはなっていませんので、そこのところご注意くださいです。

こんなわくわくするイベントを開催してくださったlivedoorの担当者の皆様ありがとうございました!

追記: その後nginxとも組み合わせてやってみたところ(psgiもこんなかんじに修正して)

までいきました。nginxでは静的ファイルをserveして、keepalive,gzipオフ。

追記: nginx embeded perlで242686req/minでました。https://gist.github.com/1181564
nginx +proxy cacheでexpireしないようにして試すと、(当然FAILするけど)fetchesが30万前後だったのでまぁここらが自分的には限界

はてなブックマーク - ISUCONに参加してきました

DBD::mysql 4.020がリリースされました

  • 投稿者: chiba
  • 2011/8/22 月曜日 2:56:45
  • mysql | perl

DBD::mysqlの4.020が昨日リリースされました。
このリリースにはmysql_server_prepare=1を使っている場合のバグの修正が5件ほど含まれています。(ChangeLog)

DBD::mysql で mysql_server_prepare=1 のとき TEXT 型の欄が自動 utf8::decode されなくなる

こちらのブログで指摘されていた件を直してパッチを送ろうと思っておもむろにmysql_server_prepare=1の状態でDBD::mysqlのテストを実行したら失敗しまくったため、もう駄目かもしれないと思ったのですが、何故かmysql_server_prepareと心中する腹をくくり一応すべてのテストを通すようにパッチを送りまくってみたところ取り込まれたという感じになりました。(リリース後に2つほどさらにpull reqしていますが…。)

TEXT型がdecodeされない件はユーザ側で回避できない話ではないんだと思いますが、LONGBLOBで4GBのメモリをアロケートしようとする件はDB構成によっては回避のしようもなく、mysql_server_prepare=1はほとんど使われてないんだなぁという印象を持ちました。

一応改めて整理しておくと、mysqlのサーバーサイドのPrepared Statementは以前はクエリキャッシュがされないというかなり致命的なデメリットがありましたがバージョン5.1.17以降でC API等から利用されるバイナリプロトコルではキャッシュされるようになり、また5.1.22以降からはテキストプロトコル上でのPREPARE, EXECUTEでもキャッシュされるようになっています。(詳細はクエリキャッシュの動作を参照してください。)

mysqlのPrepared Statementはbind値を展開した後のクエリの結果をキャッシュしてくれるいわゆるQueryCacheのみの対応となっています。パラメータ値に依存しない実行計画をキャッシュしてくれるわけでは無いのでメリットは薄いと思われる部分はあるとは思うのですが、通信データが大きい場合には速いというメリットも持っています。(今回のDBD::mysqlのバグはそのメリットを享受するべきLONGBLOBがほぼ動かないというひどいものではありましたが)

memory leakのような現象が起きるという中の人の指摘もあったりしますが、これはステートメントハンドルやコネクションの管理をクライアント側できちんと行えば問題ないと思っていたりもします。(大規模環境でどうなのかというわれるとちょっとどうなのかなと思わなくもないですが)

というわけで、やはりまあ積極的に利用を勧める理由も無いのですが、積極的に回避する理由も無いとも思ってますので是非使えるかたは使ってみてください。で、DBD::mysql的にもMySQL本体的にも枯れてくれるとうれしいなと思ってます。

はてなブックマーク - DBD::mysql 4.020がリリースされました

Gearmanのはまりどころ

  • 投稿者: chiba
  • 2011/1/22 土曜日 21:19:36
  • perl

最近Gearmanに入門しているのですが、いろいろとはまったのでメモ。

$worker->workは”Do one job”ではなくDo job loop

Gearman::WorkerのPODには

$worker->work while 1;

みたいなサンプルが書いてあったり

Gearman::Job->work(%opts)

Do one job and returns (no value returned). You can pass "on_start" "on_complete" and "on_fail" callbacks in %opts.

って書いてあるのですが(しかもこれは、Gearman::JobではなくてGearman::Workerだし、、、)
workはオプション無しで呼ばれた場合はwhile 1なんかなくてもloopします。
work_once的な動きにしたいのであれば

$worker->work(stop_if => sub { 1 });

とすればいいです。stop_ifをmax_requests_per_child的な動きにしたい場合はkazeburoさんのgearman-starter.plを参考にするといいです。

ちなみにこれは作者にメールでパッチも送ったりもしたのですがこのRTが同じ内容。1年半ぐらい放置みたいなので直る気配なし。

Gearman::Client->job_serversはArrayRefを受け取れるけど、Gearman::Worker->job_serversは受け取れない

結構はまりました。

my $clinet = Gearman::Clinet->new;
$client->job_servers(['127.0.0.1']);

はokだけど

my $worker = Gearman::Worker->new;
$worker->job_servers(['127.0.0.1']);

は駄目。正しくは

my $worker = Gearman::Worker->new;
$worker->job_servers('127.0.0.1');

としなければならない。これもRTにあがってますね。

Gearman::Workerはfork safeじゃないんでfork後生成

まぁDBIのdbhとかと一緒ですね。いくつかのネット上の例でParallel::Preforkなんかと組み合わせて使う時に
親プロセスで$worker作って共有している例注1があったのですが、ちゃんとやるなら子供で生成すること。
一見普通に動いちゃうのですが通信がまざって変になるかもしれないです。

まとめ

あたらしくCPANモジュールを使い出す時にはPODと共にRTも一緒に見ておくとよい。

注1
ここの11pとかここ(もう直ってる)とか。ちなみにkazuhoさんの書いたものだと去年のadvent calendarのWriting a prefork server / daemon using Parallel::Preforkは子供でworker生成してます。この記事は、graceful shutdownやSIGHUPによるconfig reloadへの示唆が含まれているので必見ですです

はてなブックマーク - Gearmanのはまりどころ

X-Content-Type-Options: nosniffのつけ方

  • 投稿者: chiba
  • 2011/1/6 木曜日 12:49:29
  • security

Apache

mod_headersでできます

Header set X-Content-Type-Options nosniff

Nginx

add_header X-Content-Type-Options nosniff;

但し、上記だとproxyなんかで既にX-Content-Type-Options: nosniff;が付いていると

X-Content-Type-Options: nosniff, nosniff

のようなヘッダになってしまう。問題ないかもしれないが気になる場合はNginxHttpHeadersMoreModuleを使って

more_set_headers 'X-Content-Type-Options: nosniff';

とすると良いのかも。

Plack

Plack::Middleware::Headerを使うと簡単です。

enable 'Header', set => ['X-Content-Type-Options' => 'nosniff'];

参考: X-Content-Type-Options: nosniff つかわないやつは死ねばいいのに!

はてなブックマーク - X-Content-Type-Options: nosniffのつけ方

1 2 3 4 5 6 8

ホーム

検索
フィード
メタ情報

ページの上部に戻る