個人的なメモ帳

個人的なメモを書いていきます。

ISUCON13で41位(最終スコア39,243)でした

結果

メンチカツというチームで1人参加して41位でした。
言語はGoで最終スコアは39,243点でした。
ISUCON13 受賞チームおよび全チームスコア : ISUCON公式Blog

感想

  • 予選通過のラインにすら入ってないので悔しい
  • 1人チームで上位目指すには明らかに手を動かすスピードが足りないし、守備範囲が狭すぎる
    • PowerDNS周りさっぱりわからなくてDBをサーバにする+TTL設定してみるくらいしかできなかった
    • 全体的にミスが多く、調査して解消するまで無駄な時間がかかっていた
  • 次々に改善したい場所が見つけられる+改善したら素直にスコアが上がってくれる解いてて楽しい問題だった
  • ベンチマークがWaitingとAbort多すぎて競技体験がちょっと良くなかった
    • ベンチマークが混雑するのを込みで競技準備しても良いんだけれど、それに対応するのは本質じゃない気がするのであまり気が進まない

やったこと

以下にやったこと並べます

いつもの

  • githubへのコードや設定ファイルのバックアップ
  • 計測用ツール(pprof、pt-query-digest、alp)の導入
    • ついでにpprofで見やすいようにmain.goに統合
  • サーバスペックの確認

改善内容

スコアをメモってなかったのでそれぞれどれくらい効いたか覚えてません。

1. slow_queryが出ているところにindexを貼っていく
  • 後で改善して消すかもしれないけど、徐々に改善してとりあえず早くしていく
2. icon_hashで参照時に都度SHA-256でhash計算してるところを無くす
  • DBにicon_hashというカラムを追加
  • 参照時ではなく登録時にicon_hashも計算しておくように変更
  • このときdefault_imageのhash化忘れていてFailする(1敗)
  • ついでにbuild用のmakefileの記載をミスっててビルドできてなかった(2敗)
3. icon取得の所にvarnish挟む
  • 変更が2秒以内に反映と書いてあったので何も考えずキャッシュ挟んで良いかなと挟む
  • 後でiconをfile化して直接返すように変更したので使わなくなる(3敗)
4. N+1を気づいたタイミングでなくしていく
  • slowquery見て上位に来たタイミングでN+1になってるものを順次対応
5. AdminPrepareを無くす
  • slowqueryの上位にAdminPrepareが出ていたのでInterpolateParams=trueにして無くす
6. PowerDNSで利用してるMySQLのCPU使用率が高いので別サーバに切り出す
  • 本当はPowerDNS+MySQLごと別サーバに切り出したかったけど調べる時間惜しかったのでとりあえずMySQLだけ移動
  • この時点の構成
    • Server1:App+Varnish+Nginx+MySQL(isupipe)
    • Server2:MySQL(isudns)
  • ついでにPowerDNSのTTL設定を追加
7. NGワード登録処理の無駄なNGワード判定なくす
  • コメント投稿時にNGワード判定でブロックされているのに、新規でNGワード追加したときに登録済みのNGワードでもチェックしていたので新規登録のNGワードのみでチェックするように変更
  • ついでにMySQLの負荷下げたかったのでApp側でNGワード含むかチェックするように変更(コメント投稿部分も)
8. UserのStatistics取得の負荷下げるためにreactionsとtipsを事前計算する
  • userテーブルにtipsとreactionsカラムを追加して、tipsとreactionsの登録時に更新するように変更
  • ここでSQLでtipsと書くところをtipと書いて取得できなくなる(4敗)
  • ついでにstructで小文字始まりにしててデータ取得できなかったりをする(5敗)
  • 初期データにreactionsがあることに気づかずに初期データ変更し忘れる(6敗)
  • 変更した初期データ(init_users.sql)にthemesテーブルの情報も入っていることに気づかずにthemesテーブルの初期化無くしてしまう(8敗)
9. 画像をファイルにしてNginxから返すように変更
  • ここでもdefault_imageのことを忘れていてFailする(9敗)
  • 304で返せるようにetag設定するも改善しなかったので多分うまく行ってなかった(10敗)
10. isupipeのMySQLのCPU使用率が高いので別サーバに切り出す
  • これ入れたタイミングで40,000点近くになる
  • この時点の構成
    • Server1:App+Nginx
    • Server2:MySQL(isudns)
    • Server3:MySQL(isupipe)
11. MySQLやNginxの細かい設定を追加
  • Nginxのkeepalive設定追加したり、MySQLのbuffer設定追加したり