kariaの日記 @ Alice::Diary

ノリツッコミの鳩子がはてなブログ書いちゃうよ

ISUCON7の予選2日目に参加した話

前回(というか前日)のエントリ:

karia.hatenablog.jp

酒飲んだノリで深夜に記事を書くとろくなエントリにならないという教訓が得られたのが前エントリの反省でした。こんばんは、kariaです。

というわけでISUCON7の予選に出た話です。チーム名はLabALICE、メンバーは私と id:naught00id:macotasu でした。ISUCONって何よって人はいい感じにググって調べてください。

開始前

競技開始時間が遅れることが前日にアナウンスされていたので、台風接近で大混雑していた期日前投票を避け当日投票所に行く事ができました。投票用紙のデプロイマシーンで紙詰まりというトラブルが発生するといった出来事があったものの数分で解消し、無事に集合することが出来ました。

当初のアナウンスでは競技時間が12時-20時だったので、NEWDAYSのヘンなおにぎりを買って競技時間中に食べようと思っていたのですが、さらに1時間遅れることになったので待ち時間中に速攻で食べ終わってしまい、追加でカフェイン分を調達しに行きました。エスプレッソショットを普段よりもさらに+1しています(トータルで3ショット分になっている)。しかしこいつ紙撮るの好きだなおい。

このとき手持ちのiPhoneで本当にラジオ体操を流していたのが個人的にツボでした。

競技時間中

今回のお題はisubataというチャットツール風Webアプリ。似たようなツールをどこかで見たような……?

最初にコードをgithubに上げたり解析してもらうのは一旦他の2人に任せて、環境まわりの整備からスタート。これらはほぼ事前にやると決めていたことでした。

  • 参考実装をrubyに切り替える
  • SSHログインを鍵認証に変更
  • nginxのログをLTSVかつalpが読める形式に変更
  • MackerelとNew Relicの導入

SSHを鍵認証にするのはパスワードを何度も入力する手間を省けるというのもあるのですが、パスワードを間違えすぎるとログインできなくなるfail2banが最初から入っており(レギュレーションにも書いてあった)、実際ログインできなくなっている人達をサポートチャットで見かけたため事故防止として初期にやりました。

nginxのログはとりあえず詳細に出さないと何もわからんということで、真っ先に変更にかかりました。そこからalpに食わせるところまではお作法みたいなところがあるのですが、alpの結果をどこに貯めようかという話になり、標準入力を食べてSlackに吐くシェルスクリプトを事前に作っておきました。たとえば、 echoでとある文字列を食わせると

f:id:karia:20171023023222p:plain

こんな感じ。まあQiitaとか調べれば沢山出てくるやつです。

このスクリプトにalpの結果を出力するようにしていたので、nginxのログ解析結果がslack経由で即チーム内に共有されるようになっていました。またalp実行直前にnginxのアクセスログをローテーションしてからalp専用サーバー(※)に送るようにするのも事前にスクリプトを用意していました。

※alp専用というわけでは無かったのですが、今回提供されるさくらのクラウド+最新のUbuntuという環境に慣れる意味も含め、自前でさくらのクラウドを1台調達していました。ただ、解析以外の処理を肩代わりさせることはレギュレーション違反になってしまうため、実態としてはalpでのnginxログ解析専用サーバーと化していました。

MackerelとNew Relicは仕事用とは別に今回のチーム用にアカウントを事前に取得していたのですが、その数日後にNew Relicの営業さんから「導入に問題はございませんでしたか?」という電話がかかってくるという心温まる出来事があったのを覚えてます。

f:id:karia:20171023021257p:plain

そんなNew Relicさんが表示してくれる、いかにもダメそうなWeb Transactions timeの様子。タイムゾーンJSTじゃないのでいい感じに脳内変換してね。

f:id:karia:20171022233218p:plain

Throughputはこんな感じ。確か、ポータルサイト上での初期スコアは6000点台だったと思います。

そんなこんなで、環境整備が終わってから取り組んだのがこのあたり。

  • pumaが動作するサーバーとは別に、DBサーバーにnginxを立ててロードバランサー代わりにする
  • 画像をDBではなくローカルで保存するようにし、極力pumaではなくnginxから返すように
  • nginxでPOST /profileを1台で処理するよう仕向ける

みたいな事をして2万点届くか届かないかみたいなところでした。ここまでで16時頃だったかな。

画像ローカル保存化はほぼやってもらったので、自分はnginxおじさんを主にやっていた感じでした。今回は複数台構成ということで画像ローカル保存は結構悩みどころで、これが本物の商用環境なら迷わずAmazon s3にポイッと投げるでしょうけどISUCONのレギュレーション的にそういうわけにいかず、かといってどこか1台のサーバーに集約してNFSマウント……みたいな事をすると様々な地雷が待ち受けている(最悪OS再起動に失敗する恐れがある)ため、結局nginx芸で特定のパスだけ1台に集約する方針をとりました。

ここからしばしジリ貧な感じで、

  • MySQLのmax_connectionを増やす
  • nginxやMySQLが悲鳴を上げ始めたのでOSのlimitを変え始める
  • pumaのworkerやthreadを増やす
  • サーバー構成を nginx+puma( POST /profile 専用) 、puma(それ以外)、MySQL&redis に変更(役割が分かれて見通しがよくなった)
  • jsやcssgzipで返すようにnginxのconfigをかえる

等々色んな事を試したのですがスコアはほぼ変わらず。その間にひたすらコード改善やredis化やpumaのunix domain socket化などなど色々やってもらいつつスコア伸び悩みの原因を探り、事態が打開されはじめたのが18時か19時頃。

  • GET /fetchに含まれるsleep 1をやめる(正確にはやめたわけではないけど)
  • 画像やjs,css等に対して考え得る限り304 Not Modifiedを返すようにした

この辺が入った事により一気に8〜9万点台まで上がりました。後者がログを見る限り19:53の出来事。これが個人的には最大の反省点で、あまりにも遅すぎたと思っています。

というのも、nginxの設定によりベンチマーカーに304 Not Modifiedが返るようになり帯域等のリソースが大幅に節約できることを過去問題で練習した時に知っていたのですが、当初Chromeのdeveloper toolで様子見したときに304が返ってくる様子を目撃していたため、設定はそのままでも良いかと思い込んでいたのです。「本当に304返ってる?」と突っ込まれてよくよくログを調べると全然304を返しておらず、慌ててnginxの設定を再確認したのがこの時間でした。この辺はレスポンスコードの統計とか取っとけばもうちょっと早く気づけたね。

このあたりでベンチをガンガン回し始め、MySQLの載っているサーバーのLoad Averageが10を越えるようになり、CPUリソースをほとんど使い切った状況に。

f:id:karia:20171022233655p:plain

スロークエリは全然出てないし、max_connectionを極端に上げなくてはならない状況からするとクエリというかコネクション数自体が異常かなぁ、という辺りでタイムアップに。最後に再起動試験とか不要なプロセス止めたりとかしましたが、良くも悪くも大した影響はありませんでした。

結果

  • 最終スコア: 82619 79,590
  • ベストスコア: 94407

※自力で最後に撮ったベンチ結果のスクショと、公表された最終結果が異なったので最終結果のほうに修正しました(10/24 14:40追記)

んで本選出場権をゲットできたチームはこちら。

isucon.net

一般枠のボーダーラインは210472点でした。というわけで43位。うーむ、ざんねん。

感想

やるからには予選突破したかったなぁというのが正直なところですが、本番や練習を通じて普段触らないような部分に詳しくなれたり、逆にこれまでの経験が生きてきた部分もあるかなと思っていて(OS再起動時にプロセスがちゃんと上がって来るように気をつけようとか)、一定の成果は得られたかなーと思います。練習を繰り返すことで本番に向けて改善のプロセスを回すことも出来たしね。

足りなかった十数万点はおそらくひとつチューニングがハマると指数関数的に効果を発揮するものだと思っていて、そのあたりは他の方のエントリを参考にしようと思います。特にDBコネクションプールの辺りはタイムアップで消化不良感が出てしまったし、事前準備で盛り込み切れなかった点のひとつなので。チームの方針としてruby以外の他言語の実装を試す時間を省略したので、他言語の様子がどうだったのかなーというのも確認してみたいと思います。

最後に運営の皆さん、予選用の場所と練習用サーバーリソースを提供してくれたアニメイトラボ社、そして誘ってくれた id:macotasu と一緒に出場してくれた id:naught00 に感謝です。ありがとうございました!

ISUCON7に出場登録した話

なんかめっちゃ凝った記事書こうかと思ったけど気がついたらもう予選当日なので、簡潔に書きます。こんばんは、kariaです。

というわけで、名前も出てるんでご存じの方もいるかもしれないですが、LabALICEというチーム名で今日・明日に予選が行われるISUCON7に出場します。

isucon.net

チーム名の命名の由来ですが、検討を重ねた結果

  • メンバーそれぞれを磨くための、本番環境ではない実験場・研究所という意味での「Lab」
  • ISUCONをマスターするぞという意味を込めて、頼れるバンドマスター・御形アリシアナにあやかり「Alice」

という2つの単語を組み合わせた造語になりました。いやー、命名するの結構苦労したんですよねー。

……はい、大ウソです。

様々なウソがありますが、そもそもチーム名はノリで決まったような記憶があります。

まあ、楽しくやりましょう。目標は、本選出場権をゲット!!!

タイムズカープラスをより便利に活用する5つのコツ

カーシェア最大手のタイムズカープラスですが、駐車場がクソ高い&タイムズが数多く設置されている都区内住みということもあってそこそこ便利に使ってます。都区内ではさすがに公共交通機関でも何とかなる事も多いのですが、突然ニトリカインズホームで大荷物を買いたくなった時とか、免許取得後放置しすぎてさすがに余りにペーパードライバーすぎて不安とか、突然盗んだバイクで走り出したくなったけど違法行為はちょっと……みたいな事が時々発生します。なおバイクは借りられません。

というわけで、もっと便利に使うコツとか書き留めておきます。

予約開始時間の10分前から解錠できる

意外に知られていないようなのですが、予約した時間の10分前からクルマの解錠ができます。これは公式に記載があります。

解錠 | カーシェアリングのタイムズカープラス

※手順乗車の操作は予約いただいた開始時間の10分前から行えます(課金は、予約時の利用開始時間からとなります)。

なので、突然思い立って出かける際はこの10分の実質無料を考慮に入れて予約した方がオトクです。たとえば18:30頃に「よし、今から出かけるぞ!」と思い立ってステーションまでの移動に15分かかるとすると、

  • 最短で予約できる18:45~で予約する→18:35に解錠されてしまう
  • 19:00~で予約する→18:50に解錠可能になるので移動時間コミで5分ほど余裕が出来る

という事になります。

実際のところは毎回クルマの点検を行う事となっており、またBluetooth利用する場合カーナビとペアリングする手間などが発生するので10分間実質無料という設定は準備時間としてまあ妥当な感じがします。

予約時間は長めに取ったほうが安心

予約終了時間より早く返却しても、課金額は返却した時間を基準に計算されます。たとえば、返却予定時刻を21時にしていようが22時にしていようが、19:59に返却したら19:59までとして計算されます(ただし課金枠は15分刻みなので20:00迄の枠として課金)。ということは、返却予定時刻はできるだけ長く取っておいた方が安心です。

返却 | カーシェアリングのタイムズカープラス

万一に備え、返却予定時間の30分から60分程度の長めに予約し、余裕を持ってご利用いただくことをおすすめします。

と公式にはありますが、自分はだいたい2~3時間余裕を持つようにしています。一応、実際に乗車して「これは返却間に合わないな?」と思い始めてからカーナビで延長操作することも可能なのですが、すぐ後の時間帯を別の人が予約している場合は延長不可回答が返ってきて詰んでしまうので、最初から余裕が多い方が安全です。

ただ、あんまり枠を長く抑えすぎると会員規約に抵触する恐れがあるほか、下記のキャンペーンもおいて実利用予定時間より長すぎる予約は非グッドマナーと言われたこともあるので適宜節度を持ちましょう。

グッドマナーでプラスポイントキャンペーン | カーシェアリングのタイムズカープラス

給油割引は周辺の対象スタンドに気をつけろ

レンタカーと異なりガソリン満タンで返却する必要はないのですが、それなりにガソリンが減った時は給油してから返却する事が推奨されています。給油は専用カードで無料で給油され、また一定量以上給油すると15分割引してもらえる特典があるのですが(パック利用時などを除く)、ここに密かな落とし穴があります。

前述の通り専用カードで給油するため実質無料なのがレンタカーと違って嬉しいところなのですが、大手はほぼ対象かと思いきや昭和シェル石油が連携対象外です。1回気付かずにスタンドに入り断られた事もあります。

また、前述の様に尾崎豊の影響を受け深夜に走り出してしまった場合は、都心部に細々と存在している零細給油所が軒並み営業終了している場合があります。これをカーナビやGoogleマップで考慮した上で最適なガソリンスタンドを捜索するのは結構至難な技です。

私の経験上、スタート時点で残量が半分を切っている事が結構な割合であるのですが、割引が付与される15分以内に給油できるスタンドがそもそも存在しないためそのまま返してしまう、みたいなケースが多いのかなぁと思ったりもしました。

返却後に忘れ物に気付いた場合は1回だけ解錠できる

返却すると即座に返却確認メールが飛んできますが、ここに忘れ物発生時に1回だけクルマの鍵を再解錠できるURLが記載されています。

f:id:karia:20171006013814p:plain

レンタカーだとレンタカー屋のスタッフが忘れ物を発見して連絡してくれたりしますがカーシェアの場合は良心が全ての世界なので、万一忘れ物をしてしまった場合のために覚えておいたほうが賢明です。

ちなみに、前の利用者が忘れ物をしていたというケースにも2回ぐらい遭遇したことがあります。その場合はカスタマーサービスに電話連絡すると、形状などを聞かれた上でグローブボックスに格納しておくように指示があります。別途スタッフが回収しにくるのでしょう。

長時間利用の場合は普通にレンタカーがオトク

ここまで散々便利を連呼していたのですが、最後に落とし穴を一つ。

タイムズカープラスでは15分単位で課金されるショートプランのほかに●●時間パックといったパックプランが用意されているのですが、これらのパックはショートプランとは異なり大部分が走行距離に応じて追加料金が発生します。これらを考慮し比較すると、ニッポンレンタカーの24時間営業所へ行った方がオトクな場合が多く、厳密に損益分岐点は計算していませんが一泊二日の旅行みたいなときはだいたいレンタカーにします。

それでもパックを活用したい場合、たとえば12時間ぐらい使うような微妙なケースの場合、18時以降に設定されているナイトパックなら検討の余地があります。過去2回ぐらい終電を逃したときに、「会社近くのステーションからレイトナイトパック利用+はみ出る時間分を延長料金払って翌朝9時に返却&出社すればタクシー代より安くて最高なのでは?」というソリューションを試したことがありますが、翌朝通勤渋滞に巻き込まれて見事に遅刻しました。

こちらからは以上です。