かみぽわーる

kamipo's blog

優勝したらあの子に告白することばかり考えていた #isucon

ISUCON3本選お疲れさまでした!

うちのチームのことはだいたいgfxが書いてる通りなんですけど、おもに僕がやったこととか本選後に振り返ってみたことを書いておきます。

予選後の教訓で、最初にちゃんとコードを読んで方針を決めようって話してたので、最初に全員でざっと構成とかコードとか初期状態でのベンチとか回してみて全体を把握してから昼に作戦会議。

そのときに僕が話した見解は

  • このアプリケーションから何らかの方法で参照時の画像変換のボトルネックを取り除いたとき、次にボトルネックになるのは帯域になる
  • なので理想的な状態から逆算すると5台でWANにトラフィックを吐く構成になってる必要がある
  • 最悪、参照時にまったく変換しなくて済む理想的な高速化に失敗してすべての変更をrevertすることになっても、5台並べて参照時の画像変換して返せるようにできてれば単純に初期状態の5倍のCPUでスケールできるから5台で動かすのは必須
  • 画像変換がボトルネックになっている限りクエリのチューニングに手を付けるのは時間の無駄

我がチームの戦略上のミスは、画像変換を先に済ませておけば最速になるという推定をしていたのに多分無理だろうと変換が時間内に終わりきるか(容量は足りるか)ちゃんと見積もらなかったことだと思う。

昼以降、僕は全台nginxで受けて更新系を1台目に流す部分をやって、Yappoさんが変換した画像のローカルキャッシュと1台目以外で動くように改修する部分、gfxが画像変換のImager化をやってたけど、最終的にみんなの力がひとつになることなくずっとFailしたまま僕たちのISUCONは終了した…。

まぁあとから思うと木曜から体調死にかけで当日心が弱りまくってたとか、予選ではエラーみた瞬間1秒で気づいたことが本選では30分ぐらいドハマりするぐらいぜんぜん気づけなかったとか(413 Request Entity Too LargeとかMySQL server has gone awayとか)、nginxの設定でハマってるときにもっとはやくYappoさんに見てもらえばよかったとか、なんか22番と80番以外のポートで通信できないなと思ってiptables叩いてもルール空で(1台目以外は空だった)ずっとおかしいなって思ってたのももっとはやくなんかおかしいっていえばすぐ解決したのに(Yappoさんが1台目でiptables打ったら一瞬で解決した)、それで自分の作業に掛かりっきりで他の人の変更追えてなかったからアプリがずっとFailしてるのを弱り切った心でコードレビューする気力なくなっててラスト30分諦めてぼーっとしてたりまぁとにかく反省することはたくさんあったけど、終わってから一番後悔してるのは全ての変更をrevertしてでもベンチが通る状態で終わらなかったこと。去年は要件を誤って解釈していたせいで最後断腸の思いで全ての変更をrevertしてベンチが通る状態に戻して苦い思いをしたけど、Failして終わるというのはそれ以上に苦い思いであった。

僕のバックグラウンドは運用エンジニアなので、運用エンジニアの矜持として動いてるものを壊したらあかんという気持ちをとても強く持ってる。これを外科医に例えると、腹開いてみてすごい末期だけどダメ元で手術してみて死んでしまいましたじゃなくて、手術で死なせるわけにはいかんからダメ元ならなにもせずに腹を閉じようの精神かもしれない。それを心が折れてたとはいえ最後諦めてしまった。つらい。しかし愚者も経験から学ぶのである。もう絶対に諦めたりしない。

そして来年こそこの思いをあの子に伝えられたらと思う。

#mysqlcasual vol.5 で話してきたこと

先日オラクルで開催された MySQL Casual Talks Vol.5 に参加してきました。

mysql-build よもやま話

ありがたいことにいつも発表の機会を頂いてるので、なにか新しいネタをと思ってるんですが今回ちょっとネタも余裕もなくて、それでも聴いてる人がちょっとでもへぇって思えるようなことをざっくばらんに話せたらいいなと思っていて

ちょうどFacebookMySQLのmysqldumpを爆速にする話がタイムリーだったのでそれに絡めてInnoDBのFast Index Creationを狙ってリストアも爆速になる話をしようって流れで今回の発表を考えました。前者をmatsunobuさんのブログ、後者をsh2さんのブログと発表資料を使って説明させてもらいました。僕の発表資料にはURL貼ってあるだけなんで詳しくはおふたりの素晴らしいエントリーを参照してください。

Yoshinori Matsunobu's blog: Making full table scan 10x faster in InnoDB

MySQL 5.6における大量データロード時の考慮点 - SH2の日記

あと、発表で話した--innodb-optimize-keysオプションはバグがあるみたいなので使ってみようってひとは気をつけてくださいね!

mysql-buildもがんばってますのでお気軽に@kamipoどうぞ:)

参考

好きな子のことかslow query logのことばかり考えてほかのことがおろそかになる性格なおしたい #isucon

ISUCON3 予選おつかれさまでした!

うちのチームのことはだいたいやっぽさんが書いてる通りなんですけど、おもに僕がやったこととかAMI提出後に振り返ってみたことを書いておきます。

振り返りはコチラ。

【ISUCON3】予選の振り返り【ぶっちゅぶす】 - Togetter

まず今回ISUCON3でチームを組む段階で考えていたのは、チームメンバーの共通言語は揃えておいたほうがいい(当たり前と思うかもしれないけど前回バラバラすぎて死んだ)ということと、得意分野がかぶってないチームにしたいと思ってた。その点でいうと、まだ予選がおわったところだけど今まで参加してきた教訓を活かせたと思う。

あとは前回力を出し切れない結果で悔しい思いをしたというのがあって、予選通過すれば次につながるので、横着せずに普段やってることで着実にスコアを伸ばしたい、fujiwaraさんのような役割を目指したいと思ってた。 それも得意分野がかぶってないおかげかまずまずうまくいったのではないかと思う。

だいたい僕がログ見る係でやっぽさんがクソクエリなおしまくってくれてたけど、'/recent/:page'のページャのOFFSETをWHEREに変換するのは僕の得意分野だったんで、こういうことしたいっていってやっぽさんに全部実装してもらったりしてました。あとは基本的にORDER BY 狙いのキーにしていったらMySQLの負荷はなくなりました。

あとこれは別件ですが、世間にはORDER BY created_at DESCする人がとても多いと思ってるんですけど、挿入順に単調増加する値でソートしたいんだったらAUTO_INCREMENTしてるPRIMARY KEYがあるでしょう、なんでそっちでソートしてくれないんすか、created_atにINDEX張るのも空間効率の無駄なのでやめてほしいです。これは5年以上前からいってるけどまったく世間に伝わってないと思うんでORDER BY 狙いのキーといっしょにこれも言い続けていきたいです。

最後に、本選へ向けての教訓としては

  • 好きな子のことかslow query logのことばかり考えてほかのことがおろそかになる性格なおしたい
  • 最初にちゃんとコードを読んで高速化の指針を検討したい

というところですかね。

こちらからは以上です。

YAPC::Asia 2013でmysql-buildのLTしてきた

2日目のLTで、MySQLSQLというDSLをつかって様々なストレージエンジンを共通のインターフェースで抽象化して扱うことのできるフレームワークなわけですがということで、mysql-buildでMySQLプラグインも一緒にビルドする話をしてきました。

mysql-buildでQ4Mやmroongaもビルドしたい

これでQ4Mとか簡単に使い始められるようになるので、みんなMySQLプラグインもつかってくれるかな?

(いいとも!)

動機とか

mysql-buildはMySQL Casual Advent Calendar 2011のときに書いたやつで、そのときからすでにQ4MやHandlerSocketを入れる的なネタが3つも4つもかぶって投稿されて、みんなどんだけQ4M入れたいんだよな感じだったわけですが、僕もそもそもはローカルでLTネタのプラグインとか書くときにソースからビルドしたMySQL環境が頻繁に必要になってたので書いたというのがあります。

なので当時からやる気が出たらプラグインも入れれるようにしようと思ってたけど、MySQL 5.6 で Q4M を動かしたいをやってたときにMySQLのビルドがCMake化したあたりの対応でいろいろハマったりして(これとかこれ)、まぁMySQL 5.5以降のCMakeでのビルドに対応したプラグインは置くべき場所に展開してcmake叩くだけでビルドできるようになってて簡単なんだけど、それも、知らなきゃ簡単かどうか調べるまでが面倒なんでコマンドパツイチで入るほうが敷居下がっていいですよね。僕も忘れたころにまたハマったりするの嫌だし。

現時点だとmysql-buildで指定できるQ4Mとmroongaは、MySQL 5.5以降のCMakeを使ったビルドだけ対応してるんでMySQL 5.1には対応してません(Q4Mとmroonga自体はMySQL 5.1にも対応してる)。僕がMySQL 5.1を使わないんでめっちゃモチベーション低いですが10人ぐらいのおっさんか1人のかわいこちゃんがどうしてもっていうなら対応するかもしれないです。

こちらからは以上です。

Ubuntu で nano が立ち上がってしまうのをなんとかする方法

#mysqlcasual vol.4 でLTしてきました

4/17 に日本オラクルで開催された MySQL Casual #04 で話して来ました。

当日のスライドは以下になります。

SQLがむずかしくて生きるのがつらい

ちょいとまだ作り始めたばっかりで微妙なところも多々あるんですが、mruby_storage_engine のレポジトリは以下になります。

kamipo/mruby_storage_engine · GitHub

発表について

けっこう時間なくて準備にテンパってたので、あとで言及されてるのをみると説明たりてなかったなー(絞り込めないってLIMIT OFFSETの話じゃないの?的な)というところもあったけど、それがわかってる人は大丈夫な人なので大丈夫です!補足ありがとうございます!

mruby_storage_engine について

構想自体は一年前ぐらいからあって、よく同僚に「こういうことできたらうれしいとおもわへん?(でもめんどくさいので実装はしない)」というのを繰り返していたんですが、勉強会ドリブンで実装するチャンスをのがすとまた一年ぐらいめんどくさくてやらない病に陥るので、前日の晩に@さんに発表枠もらって後に引けない状態に追い込んでから徹夜でなんとかデモできるレベルまでもっていきました。

既存技術の組み合わせなんでやる気だせばすぐできると思ったんですが、なんかMySQL 5.6でうごかすことに変にこだわったせいで5.6から変わったところにけっこう苦しむことになって、いちばんやばかったのが、すでにテーブルをlockしてるクエリ内でさらに追加で他のテーブルもlockしようとするとassartに引っかかって落ちること。言い換えると、SELECT文とかのSQLはまず参照するテーブルのlockを取ってからテーブルを呼びにいくわけですが、そのテーブルの中からSQL側が知らない別のテーブルを参照しにいくことができなくなっていた。僕はMySQLの中の人でも開発者でもないので詳しいことはわからないが、作者の気持ちを考えなさいといわれるならば、これはおそらく、いままでは一貫性に問題のある使い方もすることができたけどこれからはAPIとしてはそういう使い方はしないでねってメッセージだと僕は思いました。

時間がなかったので発表のデモではかなり強引な方法で回避しているし、もともとやりたかったことの1割ほども実現できていないので、またやる気が出たタイミングでがんばりたいと思います。ぜんぜん作りかえちゃってもいいのでpullreqウェルカムです。

おわりに

@++, Oracle++
そして @++ (たい焼き的な意味で)

今回はかなり挑戦的なイベント運営でしたが、入れなかったひとが 1人だけど言う奇跡的な流れでした。

ただし、やはり水曜というだけあって飲みに行く人がぜんぜんいなくて、いろいろ話しできなかったのが残念やも!

というわけで、次回は @ さんの成果報告を楽しみにしております。

SEE ALSO

にひりずむ::しんぷる - MySQL Casual #04 で mysqlenv 作った的な話をしてきました

鎌倉幕府の年号が変わっていた

参考