Konboi Note

ISUCON13にチーム「流れ弾」として参加しました

· Konboi

ブログを書くまでが ISUCON なので!

はじめに

今年も前職の同僚である@hilotterと@tkuchikiとISUCON13にチーム「流れ弾」として参加しました。

結果から言うと全く歯が立たずで、ベストスコアは 12960。最終スコアは 10596 でした。

やったこと

自分がやった事としては大きく

  • 初期状態の DB に index を追加
  • stats 系の高速化

の 2 つ。

初期状態の DB に index を追加

コード見ながら SELECT ... で始まるクエリを探して適切な index を張っていき、3,000 点台だったスコアが 1 万点近くまで伸びた。

開始1時間のピークの様子

開始1時間のピークの様子

stats 系の高速化

index 張った後は access log から */statistics の endpoint を改善することにした。

初期のalpの結果
+-------+-----+------+-----+-----+-----+--------+--------------------------------+--------+--------+---------+--------+--------+--------+--------+--------+-----------+------------+---------------+-----------+
| COUNT | 1XX | 2XX  | 3XX | 4XX | 5XX | METHOD |              URI               |  MIN   |  MAX   |   SUM   |  AVG   |  P90   |  P95   |  P99   | STDDEV | MIN(BODY) | MAX(BODY)  |   SUM(BODY)   | AVG(BODY) |
+-------+-----+------+-----+-----+-----+--------+--------------------------------+--------+--------+---------+--------+--------+--------+--------+--------+-----------+------------+---------------+-----------+
| 1     | 0   | 1    | 0   | 0   | 0   | GET    | /api/livestream/\d+            | 0.004  | 0.004  | 0.004   | 0.004  | 0.004  | 0.004  | 0.004  | 0.000  | 1482.000  | 1482.000   | 1482.000      | 1482.000  |
| 1     | 0   | 1    | 0   | 0   | 0   | POST   | /api/initialize                | 11.968 | 11.968 | 11.968  | 11.968 | 11.968 | 11.968 | 11.968 | 0.000  | 27.000    | 27.000     | 27.000        | 27.000    |
| 1     | 0   | 1    | 0   | 0   | 0   | GET    | /api/payment                   | 0.004  | 0.004  | 0.004   | 0.004  | 0.004  | 0.004  | 0.004  | 0.000  | 21.000    | 21.000     | 21.000        | 21.000    |
| 1     | 0   | 1    | 0   | 0   | 0   | GET    | /api/user/test                 | 0.004  | 0.004  | 0.004   | 0.004  | 0.004  | 0.004  | 0.004  | 0.000  | 235.000   | 235.000    | 235.000       | 235.000   |
| 2     | 0   | 2    | 0   | 0   | 0   | GET    | /api/livestream/.+/statistics  | 3.544  | 3.620  | 7.164   | 3.582  | 3.620  | 3.620  | 3.620  | 0.038  | 100.000   | 102.000    | 202.000       | 101.000   |
| 3     | 0   | 3    | 0   | 0   | 0   | GET    | /api/user/me                   | 0.000  | 0.000  | 0.000   | 0.000  | 0.000  | 0.000  | 0.000  | 0.000  | 235.000   | 247.000    | 729.000       | 243.000   |
| 9     | 0   | 9    | 0   | 0   | 0   | GET    | /api/user/.+/livestream        | 0.036  | 0.304  | 0.904   | 0.100  | 0.304  | 0.304  | 0.304  | 0.079  | 2453.000  | 10153.000  | 40426.000     | 4491.778  |
| 10    | 0   | 10   | 0   | 0   | 0   | GET    | /api/user/.+/theme             | 0.004  | 0.072  | 0.196   | 0.020  | 0.068  | 0.072  | 0.072  | 0.026  | 38.000    | 38.000     | 380.000       | 38.000    |
| 11    | 0   | 11   | 0   | 0   | 0   | GET    | /api/user/.+/statistics        | 0.576  | 7.900  | 66.300  | 6.027  | 7.496  | 7.900  | 7.900  | 2.174  | 133.000   | 153.000    | 1547.000      | 140.636   |
| 26    | 0   | 23   | 0   | 3   | 0   | POST   | /api/livestream/.+/moderate    | 0.248  | 8.324  | 100.948 | 3.883  | 6.856  | 7.640  | 8.324  | 1.616  | 0.000     | 23.000     | 529.000       | 20.346    |
| 46    | 0   | 46   | 0   | 0   | 0   | DELETE | /api/livestream/.+/exit        | 0.004  | 0.192  | 1.676   | 0.036  | 0.108  | 0.132  | 0.192  | 0.040  | 0.000     | 0.000      | 0.000         | 0.000     |
| 56    | 0   | 56   | 0   | 0   | 0   | POST   | /api/livestream/.+/enter       | 0.004  | 0.264  | 2.508   | 0.045  | 0.092  | 0.120  | 0.264  | 0.047  | 0.000     | 0.000      | 0.000         | 0.000     |
| 70    | 0   | 70   | 0   | 0   | 0   | GET    | /api/livestream/.+/ngwords     | 0.004  | 0.208  | 2.372   | 0.034  | 0.072  | 0.132  | 0.208  | 0.041  | 5.000     | 143.000    | 740.000       | 10.571    |
| 99    | 0   | 98   | 0   | 1   | 0   | GET    | /api/livestream/search         | 0.052  | 1.532  | 74.044  | 0.748  | 1.064  | 1.364  | 1.532  | 0.324  | 0.000     | 127619.000 | 6765168.000   | 68335.030 |
| 116   | 0   | 116  | 0   | 0   | 0   | GET    | /api/livestream/.+/report      | 0.004  | 0.220  | 4.356   | 0.038  | 0.108  | 0.156  | 0.188  | 0.046  | 3.000     | 11026.000  | 41626.000     | 358.845   |
| 122   | 0   | 122  | 0   | 0   | 0   | GET    | /api/tag                       | 0.004  | 0.280  | 5.352   | 0.044  | 0.120  | 0.184  | 0.256  | 0.055  | 6089.000  | 6095.000   | 743542.000    | 6094.607  |
| 139   | 0   | 135  | 0   | 4   | 0   | POST   | /api/livestream/reservation    | 0.120  | 0.732  | 36.168  | 0.260  | 0.408  | 0.488  | 0.532  | 0.147  | 0.000     | 1482.000   | 154546.000    | 1111.842  |
| 165   | 0   | 165  | 0   | 0   | 0   | GET    | /api/livestream                | 0.004  | 0.276  | 3.872   | 0.023  | 0.072  | 0.104  | 0.212  | 0.040  | 3.000     | 22542.000  | 172264.000    | 1044.024  |
| 226   | 0   | 223  | 0   | 2   | 1   | POST   | /api/register                  | 0.004  | 0.748  | 49.544  | 0.219  | 0.320  | 0.348  | 0.500  | 0.089  | 0.000     | 504.000    | 104643.000    | 463.022   |
| 228   | 0   | 222  | 0   | 1   | 5   | POST   | /api/icon                      | 0.016  | 0.352  | 20.456  | 0.090  | 0.188  | 0.228  | 0.312  | 0.066  | 0.000     | 154.000    | 4217.000      | 18.496    |
| 231   | 0   | 229  | 0   | 2   | 0   | POST   | /api/login                     | 0.004  | 0.248  | 7.080   | 0.031  | 0.088  | 0.128  | 0.228  | 0.044  | 0.000     | 64.000     | 128.000       | 0.554     |
| 550   | 0   | 550  | 0   | 0   | 0   | POST   | /api/livestream/.+/reaction    | 0.004  | 0.304  | 36.148  | 0.066  | 0.124  | 0.164  | 0.220  | 0.044  | 1552.000  | 2228.000   | 1016553.000   | 1848.278  |
| 618   | 0   | 615  | 0   | 3   | 0   | POST   | /api/livestream/.+/livecomment | 0.004  | 0.480  | 39.596  | 0.064  | 0.108  | 0.144  | 0.308  | 0.050  | 0.000     | 2683.000   | 1213009.000   | 1962.798  |
| 987   | 0   | 978  | 0   | 9   | 0   | GET    | /api/livestream/.+/livecomment | 0.000  | 0.876  | 126.432 | 0.128  | 0.376  | 0.456  | 0.628  | 0.161  | 3.000     | 54758.000  | 8460697.000   | 8572.135  |
| 1018  | 0   | 1010 | 0   | 8   | 0   | GET    | /api/livestream/.+/reaction    | 0.000  | 0.788  | 116.700 | 0.115  | 0.344  | 0.436  | 0.600  | 0.151  | 3.000     | 50891.000  | 7637399.000   | 7502.357  |
| 5106  | 0   | 5102 | 0   | 4   | 0   | GET    | /api/user/.+/icon              | 0.004  | 0.392  | 166.628 | 0.033  | 0.080  | 0.124  | 0.224  | 0.045  | 0.000     | 103174.000 | 258409729.000 | 50609.034 |
+-------+-----+------+-----+-----+-----+--------+--------------------------------+--------+--------+---------+--------+--------+--------+--------+--------+-----------+------------+---------------+-----------+

改善の方針としては専用のテーブルを用意してそこにstatisticsに必要なデータを保存するようにした。
この方法だと広範囲に渡って修正する必要がある事を修正しながら気付いたが後戻りはするには遅過ぎた…

手元に環境を用意せず本番にデプロイして確認する方法をとっていたが、途中ベンチマーカーの修正の影響でベンチが実行出来ないもあって修正にかなりの時間を費やしてしまった。

修正してパスしたのが 16 時近かったので 4 時間ぐらいかかった計算になる。(…遅すぎる)

他の人の結果を見る限りこのエンドポイントを修正する判断と自分の修正方法のアプローチは悪手だった…。

その後

この後 livestream/ 系のループクエリを修正しているところで最後は PASS して終わろうということで反映はせずタイムアップ。

その他

他にもメンバーの嵌っているところを一緒に直したりもした気もするけどあまり覚えていない。

振り返って

総評として何をやるにしても時間がかかってしまって実力不足/準備不足なのを痛感した。

アプリのログをひとつ見るのにも「アプリのログってどうやって見るんだっけ? journalctl でいいんだっけ?」とか、 「journalctl のログが見切れるんだけど…」からの画面共有して見てもらったり。本番でそれで時間潰してたら、時間無くなるわなという感じ。

去年はスコアこそ思ったほど出なかったけど、事前にいくつか過去問を解いてから挑んだのもあってもう少しやれてた気がする。

伸び代しかない事が今年も分かったので反省を活かしていきたい。

さいごに

ISUCON13 運営の方々、今年も楽しい ISUCON を提供していただきありがとうございました!!

集中して競技できるように配慮してくれた家族にも感謝。