ISUCON7 予選1日目を1位で通過しました。


大会運営者の皆様ありがとうございました。 本戦もよろしくお願いいたします。

まとめ

決勝に行くことはできたけど、打倒組長は達成できず...

  • 勝因: /icons/*/fetch をなんとかできたこと
  • 敗因: nginxを2台にしていたこととswap対策できなかったこと

参加経緯

ISUCONの存在は同僚の組長が無双していたこともあり最初から当然知っていて、 自分も出たら結構いいところまでいけそうだなあみたいな気持ちはあったのだが、 惨敗したときの恐怖が勝って、あれこれ言い訳をして出てこなかった。

今年も、本番当日がつくばマラソンかぶっているので「参加できないわー残念!!」と言いながら心のなかでホッとしていたけど、 うっかりつくばマラソンのエントリーをし忘れてしまい、本番当日が空いてしまったということで言い訳ができなくなってしまった。。。

そんななかここ2年くらい業務で一緒にやっているGoの実装がクソ早い @mizukei が新卒の@jet_zousanと残り1名のメンバーを探しているという情報をつかんだので、それに食いついたというのが参加した経緯。

結果的にかなりいいメンバー構成でチームが組めてラッキーだった。

チーム編成

  • @jet_zousan 弊社インフラの期待の新人 あの組長の弟子
    • インフラを一任
    • 最初は環境構築を担当する
  • @mizkei11 Goを愛しGoに愛された男
    • アプリ担当(主にGoの言語依存の問題を潰す)
    • 最初はコードリーディングを担当する
  • @ken39arg 10年戦士
    • アプリ担当(主にDBの使い方の問題を潰す)
    • 最初はslowlogの解析とIndexチューニングを担当する

とにかく自分と @mizkei11 はコードを書くのが早いというのが強み

インフラ面について@jet_zousanの知識は申し分ないけど業務経験が少ないのが不安要素 (経験的に俺がインフラ補えれば良いのですが最近さっぱりで…)

そういうチームなんで、とにかく当たり前の事を当たり前に積み上げて、手数でぶん殴ろうというのが唯一の作戦。

事前準備

  • チーム組んだ瞬間に Slackとgithubのprivate repoを作った
  • 1週間前に集まって、決勝に絶対に行くこと、打倒組長を誓いあった
  • issueにsnipetsとTODOを各自書き込んでおいた
  • infra担当の @jet_zousan がなんかchefで準備してた(よくわからん)
  • 自分たちのいつものフィールドで戦うことを決めておいた(nginx,golang,mysql,redis)
  • apache→nginxやpostgresqlmysqlの移行ブログなどのリンクをブクマ

当日競技前

開始が遅れたので、作戦とマニュアルの確認をクドいほど行った。

  1. ホワイトボードに「おちつく」とでかく書いた
  2. ホワイトボードに「チャレンジしない」とでかく書いた
  3. 事前に決めたチェックポイントでタイマーのアラートを設定した。内容は記憶が曖昧だがこんな感じ
    • 30分 達成指標
      • いじるファイルのgit管理
      • alp用nginx-logの設定
      • slowlogの設定
      • アプリをgoに切り替える
      • 最初のベンチが終了
      • pt-query-digestとalpでボトルネックを立て作戦を立て直す
    • 2時間 達成指標
      • 自分たちの当たり前を終わらせる
        • Index
        • N+1を解消
        • 言語依存の基本的な改善
    • 7時間 達成指標
      • 基本これより先はいじらない
      • 再起動テストなどを行う

競技開始

13:13 ~ 14:15頃

  • まず全員で当日マニュアルを読み込んだ。
  • とりあえず1人1台サーバーに入り構成を確認
  • nginxの設定を手で書き換えてalpで集計できるようにlogformatを変更
  • mysqlはクライアントでログインしset globalでslowlogを出力するように変更
  • systemdでアプリをgoに切り替える
  • 1回目ベンチ
  • githubにgoのコードをコミット
  • alp, pt-query-digestを実行
  • pprofを仕込む
  • buildを1台でできるようにする

ここまでで当初の想定より30分ほど送れていたけど、「おちつこう」と声を掛け合って冷静になれていた

ここで、/icons/をどうにかしないとslowlogすらまともに見れないという事になり、一度立ち上がって作戦会議

(ちなみにこの後最後までpt-query-digest は見れなかった...)

たてた作戦

下記をそれぞれサクッとやってしまおうということになる

  • @mizkei11
    • 画像を静的ファイルに保存する
    • 初期画像を取り出す
  • @jet_zousan
    • DBサーバーでアプリを動かし各appサーバーからPOST /profileGET /icons をDBサーバーに回し画像サーバーを1台にする
  • @ken39arg
    • slowlogがまともに見れないのでコードリーディングをして自明なIndexを張る

14:15頃〜19:30

僕に割り振ったMySQLにIndexは、必要なのが少なくてすぐに貼り終えてしまった(messageとimageのみ)

暇になったのでやることリストを確認しながら静的ファイルをgzにしgzip_staicで配信するなどをやった。

そうこうするうちに、15:30くらいに画像の静的ファイル化が完了してスコアが上がりだしたと思う。

ぼくは簡単に出来そうな最適化が見当たらないので/fetch の修正に取り掛かることにした。

この時たしか16時前で17時までにキメるぜ!と宣言して16:30くらいに書き終えた。

ただそこから、くだらないタイポとかでなんやかんやと時間が過ぎて結局投入したのが17時過ぎになってしまった。(今回僕に限らず3人とも普段しないようなくだらないミスが目立った。パスを間違えたり、タイポしたり、、、)

ここでスコアが一段階跳ねたところで、インフラ担当の@jet_zousanが、cacheヘッダーを入れたら、スコアが爆上げして、超盛り上がった。

この結果、DBサーバーが完全なるボトルネックになって、isu1と2でtry_file&proxyでプロキシしあう構成(通称クロス)に移行するが、またしてもくだらない設定ミスとかでなかなかすんなりいかない時間を過ごしてしまい実投入は少し先になった。

nginxの設定に手間取っている間に jsonyfy みたいな名前でに隠された /messages/history のループクエリの解消が@mizkei11 により投入されて確かトップにたったと思う。

そしてクロス構成が決まったところで46マンまで伸びて2位以下とダブルスコアがついてきたので、予選突破の安全策を取りに行くことにした。

そう、僕たちの作戦は「チャレンジしない」

19:30

ここまで手をつけていなかったmysqlのチューニングに取り掛かろうととりあえずinnodb_buffer-pool-sizeの調整をしたところ、スコアが半分くらいになってしまった。

さらにベンチを回すとさらに半分くらいに。。。

ここで設定を戻したりしたが、一向によくならない。

何をしたのか振り返るが、よりにもよってmysqlの設定に関してのみコミットしておらずdiffが不明。

絶対にinnodb-buffer-pool-sizeしかいじってないとのことだが@jet_zousanを信じきれずDBサーバーばかりをガン見するという状態がしばらく続いたところで、ようやくアプリがswapしていることに気づいた。

画像ファイルの名前を画像ののsha1で生成していたのだが、readallで画像を一度に読み込んでいたのだ。

よく考えてみると、今までベンチを回す時は必ずコード修正後でアプリをビルドし直していたからメモリが解放されていたのだが、DBのチューニングの時はDBしか再起動しなかったため、メモリを食いつぶしたままのアプリでベンチがかかっていたため性能が著しく劣化してしまったと予想。

ようやくそこに気づいたので、アプリを再起動すれば少なくとも30万はスコアが出るということが確認できたので、再起動後はちゃんとスコアが出るだろうと判断し、対策しないことにした。

20時の時点で30万まで行っていたのはチームは他にいなかったので3位以内には入れるという判断だった。

そういうわけで、余計なことはやめておこうと、ログもそのまま、欲を出さずに20:30には競技をやめて反省モードに入った。

結果として、この判断は正しく、ベストスコアとの隔たりは大きかったものの1日目1位をキープしたまま決勝の切符を手に入れることができた。

めでたしめでたし。

感想

判断は正しかった。ただ、本当にいつも通りできていたらあと2手くらいは打てたし、冷静になっていたら最後チャレンジではなく当たり前の判断でswapの解消ができたと思う。

いや、そもそもモニタリングしていたらもっとはるかに早くswapに気づけたはず、、、

決勝は同じミスをしないように、そして決勝はチャレンジします。勝つだけなので

10月のトレーニング計画

1/28の館山若潮マラソンに出ることにしました。

そこでサブスリー達成します!

 

さて、そのための練習ですが4カ月前の10月はポイント練は週一くらいにして、無理せずしっかりと距離を踏んでいこうと思います。

ここ1カ月はダラダラ過ごしましたが、それでも心拍はスイムで鍛えてたので4ヶ月前としては問題ないはずです。

 

10月の基本メニュー

 

月 : スイム (ジムのマスターズクラス) 3km弱

火 : ラン (帰宅コース) 15km

水 : ヨガ&バイク(片道15km×2)

木 : ラン (帰宅コース) 15km

金 : スイム (ジムのマスターズクラス) 3km弱

土 : ラン 20km 又は 3時間走

日 : off (土曜日と入れ替わりあり)

 

平日のランは基本スピードを気にせず気分で走る。

速く走りたい気分なら速く走るしのんびりでもOK

 

ポイント練は週末朝で距離を踏む系の練習LSDな感じで、11月にスピード練習できる下地を作る。

ただ、もしスピード練習する気分になったらその時はやる。

とにかく気分を優先する。

 

あまり月間距離は気にしないことにしているけど、計算上は200kmくらい走るはず。

量より質派だけど、怪我しないようにここで下地をしっかり作るのが10月のノルマ。

 

11月から1月前半ははインターバルとペース走のポイント練二本立てに切り替える予定。

 

達成できると良いけど明日は早速雨予報??

 

湘南OWS

一昨日、湘南OWS10kmに参加した。

 

この大会にエントリーしたのは2回目で1回目は5年前。

その時はまあまあくらいの練習で、完泳を目標にしてたんだけど、1ヶ月前にビーチフットっていう砂浜でやるラグビーをしてハムストリングスの肉離れをしてDNFとなった。

 

それからずっと頭に引っかかってはいたんだけど、水泳の練習はどんどん減り、子供も生まれてさらに減りぜんぜん泳がない日々が続いていた。

 

それからしばらくして、紆余曲折あってランニングにハマりマラソンでサブスリーを目指すようになった昨年、夏場の練習の一環としてまた泳ぐようになり、たまたまfacebookで目に付いた富津アクアスロンに申し込んだ。

それが沼の入り口だった。

 

小学生の頃、陸のスポーツは全然ダメだけど泳ぐのだけは得意で僕の支えだった水泳。

中学生では水泳部で市の大会で入賞もした水泳。

大好きだった水泳の新しい楽しみ方というか35歳でも成長出来る伸び代に出会ってしまった。

 

海で泳ぐのは楽しい。そして、また早くなる喜びを感じることができる。

もっと早くなりたい、逗子から江ノ島まで泳ぎたい。頭の中はそんな気持ちでいっぱいになった。

 

夏は海、冬は陸、どちらもサブスリーを達成したくなった。

そして今年の目標を水陸でのダブルサブスリー達成と決めた。

 

1月のフルマラソンは3時間8分あと少し足りなかった。でもスイムがあるから切り替えて、週に2回1時間で3000m泳ぐキツイメニューを組んでPDCAを回しながら追い込んだ。

追い込みすぎて声が出ちゃうので、マスターズクラスのおばちゃん達に笑われた。

 

この夏、2つの大会と1つの練習会、長水路での練習、海での自主トレと家族にわがままを言って週末の午前中を何度も使って準備をした。

2週間前の5kmの大会では1時間21分で泳げた。

フルマラソンでサブスリーを狙うならハーフのタイムとしては十分なタイムだ。

俺の中で海でのサブスリーはほぼ確定していた。

 

湘南OWSの前日は事前登録もあったし、万全を期すため仕事を休み21時には寝た。

朝は4時に起きうどんを食べ、1時間おきに炭水化物をとり、30分おきにOS1を飲みローディングした。

体調は万全、天候も良好。最高のスタートを迎えた。

 

500人が一斉にスタートするというのは初めてでだったけどバトルの激しさが桁違いだった。

ドラフティングで後ろにつかれるのはものすごいストレスだった。

うねりも大きかった。何度も人が上から降ってきた。ゴーグルも蹴られた。OWSの洗礼を受けてる気分だった。

 

逗子の海を一周まわった頃、船に乗る沢山のスイマー達を見た気がした。

3kmのわけないし1km?多すぎないか?いや気のせいだろ?そんな感じ。

3km地点で初めての給水をした。どんな船が待ってるんだろう?どうやって飲むんだろう?ちゃんと見つけられるだろうか?と不安でいっぱいだったけど、大きなゴムボートが二台あって同じキャップの人達が群がってたのですぐにわかった。

ボランティアのおばちゃん達に水をもらった。3kmは水だけと聞いていたけどエネルゲンのゼリーももらえた。ボートにつかまりながらしっかり飲んで離れる時「59分」という声が聞こえた気がした。

 

???

 

そんなわけないよな?

いくら何でも3kmにそんなかかるわけないよね?しかも俺は絶対に比較的前の集団にいるはずだ。ペースも悪くないし。

頭の中がモヤモヤした。

ブイは全く見えなかった。

波が高すぎクロールの流れのヘッドアップでは全然見つからない。ガードの方達のシャツを目印にしたが左右にいて結構幅があった。

それにそれすらもすぐに見失う感じだった。

 

思い返せば違和感は他にもあった。

すぐ横にいた人との距離が一瞬にして大きく離れたり、誰もいなかったはずなのに急に真横にいたり。多分うねりに流されてたんだと思う。

 

目印のブイや船は見つからないけど、他のスイマーやガードを頼りに進んでいくと突然バンと現れる。現れるとそこに向かって安心して進めるので心が休まる。それを4回繰り返して5kmの給水にたどり着いた。

今度は中学生くらいの子供のボランティアが水とエネルゲンをくれた。

思い切ってモヤモヤを聞いてみた。

 

「今何時?」

 

「10時40分くらいです」

 

ヤバい!マジだった。

何でこうなったのかわからないけど、間違いなく足切りの当落線上にいることを理解した。

ウソだ!と思った。

ただ泳ぎを止められることもなかったので前に突き進んだ。

ここからは江ノ島がはっきり見えるようになったので、ブイを追うのを諦めて江ノ島灯台をヘッドアップで確認しながら泳ぐことにした。

 

固定の目標物が出来たので、うねりで体がずらされてることにもようやく気づいた。

人ではなく灯台。強いうねりが来たらすぐヘッドアップで修正するようにした。

 

7km地点一緒に給水した人が、タイムアップまでどのくらいか聞いていた。

現実を受け入れたけど答えを聞きたくなくて、すかさずボートを離れた。

シックスビートにしようとしたけど足は攣りかけてて無理だった。

 

うねりは相変わらずだった。

江ノ島灯台を目指す作戦はここからは失敗だった。

距離が近くなるとその方向は進路から左にずらてしまうようだった。

何度も平泳ぎをする羽目になった。

腕もきつくなってきて何人かに抜かれた。悔しいけどついていけなかった。

 

9kmのボートの前に小さめのオレンジブイがあった。

最終ブイと勘違いして右肩で回って陸を目指したが、感覚的におかしくてものすごく不安になった。次のブイもゴール見えない。

ここに来てどこにいけばいいのか全然わからなくなった。

結論から言うとそのブイは最後の部位ではなかった。その先に黄色い四角ブイがあった。

 

最後の力を振り絞って陸を目指したがゴールは全然わからなかった。

ゴールよりだいぶ離れたところに上陸して結構走った。

 

どうやら制限時間内にゴールはできたようだった。

タイムが気になった。3時間24分。

しばらく受け入れることができなかった。

 

受け入れることができなくて、完泳者の数が少ない事にしばらく気づかなかった。

 

facebookには悔しい!と書き込んだ。

 

さて、冷静になってリザルトを見ると完泳者の数が異常に少ない事に気付いた。

facebookTwitter、インスタなんかを見て何が起きたのか把握した。

 

今年の湘南OWSは大波乱だったようだ。

まず完泳した事に胸を張ろうと思う。

 

そして、もしかすると5kmはギリギリすぎていたのかもしれない。でもあまりの状況に見逃してもらえたのかもしれない。

そう考えると、考えな甘さ未熟さ力不足にまた悔しくなった。

 

本当はOWSはこれっきりにすることも考えていた。

だって練習キツイから。

 

でもやりますよ。

必ずやりますよ。

来年こそサブスリーそのためにこれからも苦しい練習をします。

マラソンもやりますよ。二刀流になるけど来年はこの悔しさをバネにダブルサブスリー達成します。

 

FacebookはOWSばかりでキモいしTwitterもキモいしで、でもどこかにこの気持ちをぶつけたくて未使用だったここに書いたら、ずいぶん長くなってしまった。

2014年1月1日

あけましておめでとうございます。

2011年以来書いて無かったですが、今年はブログを書こうと思います。

というわけで2014年の目標は

1. ブログを書く
2. 痩せる(見た目に)

の二つです。

仕事の目標はありません。
今年は流れに身を任せて人のためになろうと思います。
なのでせめてブログ書きます。

腹がまた出てきました。
何度目のあれかわかりませんが、自転車乗ってますけど食べ過ぎてて太ってきてしまいました。
食べる量を減らして筋肉も少し鍛えます。



さて、月が変わったので、2014年1月の目標は

1. 昨年2月頃に携帯アドレスが変わったことを皆様に謝りつつ連絡する

の一つです。

昨年の初めに携帯をドコモから、auに変えたので、所謂メアドが変わったのですがメアド変わりましたメールを誰にも送っていませんでした。
これはそのうちと思って今日にいたったわけです。
結果あけおめメールが一件も来ませんでした。
教えてても来たかわかりませんがちゃんと連絡します。

以上。

うっかり

8月に穴をあけてしまった。。。

8月は怪我をしました。
OWSにでたことを記事にするつもりでしたが、怪我をして出れませんでした。

来年がんばるぞー