2021-09-18 に開催された ISUCON11 の本選に参加してきたときのメモ。
チーム構成
チーム名
Oops!
メンバー
- 2matzzz
- nyaa
- kjm
昔は同僚だったけど、いまはそれぞれ別の会社で働いているメンバー達。
選択言語
Go言語
スコア
- Best/Latest 93,716
UTC | Score |
---|---|
2021-09-18 01:09 | 31,969 |
2021-09-18 01:15 | 33,639 |
2021-09-18 01:25 | 35,112 |
2021-09-18 01:31 | 36,202 |
2021-09-18 01:38 | 35,662 |
2021-09-18 01:45 | 36,942 |
2021-09-18 01:56 | 36,154 |
2021-09-18 02:08 | 36,234 |
2021-09-18 02:10 | 36,840 |
2021-09-18 02:14 | 36,959 |
2021-09-18 02:21 | 39,465 |
2021-09-18 02:24 | 34,372 |
2021-09-18 02:27 | 39,810 |
2021-09-18 02:31 | 39,644 |
2021-09-18 02:33 | 42,591 |
2021-09-18 02:42 | 42,995 |
2021-09-18 02:44 | 43,226 |
2021-09-18 02:47 | 42,129 |
2021-09-18 03:07 | 44,199 |
2021-09-18 03:10 | 43,521 |
2021-09-18 03:15 | 44,035 |
2021-09-18 03:20 | 41,470 |
2021-09-18 03:22 | 40,860 |
2021-09-18 03:56 | 41,856 |
2021-09-18 04:18 | 43,468 |
2021-09-18 04:26 | 42,589 |
2021-09-18 04:28 | 41,903 |
2021-09-18 04:30 | 44,697 |
2021-09-18 04:34 | 43,812 |
2021-09-18 04:39 | 46,276 |
2021-09-18 04:42 | 43,960 |
2021-09-18 04:45 | 43,922 |
2021-09-18 05:00 | 44,102 |
2021-09-18 05:03 | 45,519 |
2021-09-18 05:05 | 44,340 |
2021-09-18 05:11 | 45,423 |
2021-09-18 05:17 | 45,323 |
2021-09-18 05:20 | 45,420 |
2021-09-18 05:36 | 43,768 |
2021-09-18 05:41 | 46,432 |
2021-09-18 05:43 | 46,718 |
2021-09-18 05:52 | 45,942 |
2021-09-18 05:58 | 45,169 |
2021-09-18 06:00 | 47,141 |
2021-09-18 06:07 | 69,966 |
2021-09-18 06:27 | 71,585 |
2021-09-18 06:31 | 69,999 |
2021-09-18 06:35 | 74,496 |
2021-09-18 06:38 | 69,043 |
2021-09-18 06:41 | 73,200 |
2021-09-18 06:56 | 69,506 |
2021-09-18 06:59 | 71,532 |
2021-09-18 07:02 | 72,975 |
2021-09-18 07:05 | 76,300 |
2021-09-18 07:35 | 92,244 |
2021-09-18 07:39 | 37,551 |
2021-09-18 07:47 | 42,048 |
2021-09-18 07:50 | 87,903 |
2021-09-18 08:07 | 81,574 |
2021-09-18 08:09 | 85,563 |
2021-09-18 08:13 | 91,592 |
2021-09-18 08:20 | 84,248 |
2021-09-18 08:24 | 81,615 |
2021-09-18 08:27 | 79,610 |
2021-09-18 08:29 | 90,119 |
2021-09-18 08:33 | 91,624 |
2021-09-18 08:41 | 51,328 |
2021-09-18 08:42 | 87,154 |
2021-09-18 08:46 | 90,508 |
2021-09-18 08:47 | 93,608 |
2021-09-18 08:52 | 92,235 |
2021-09-18 08:54 | 93,716 |
結果
(85,666) Oops! (提出課題のダウンロードが404)
ブラウザ動作確認失敗で失格でした!
TVer賞 新しいベストスコア - 今までのベストスコア が大きい4チームにChromecast With Google TVを人数分。 Oops! (22,825点差を更新)
TVer賞ありがとうございます!
最終的にチームでやったこと
10:00 - 最終スコア 36,154
- アプリケーションのビルド、ログのローテーション、サービスの再起動を行う Makefile を書いた
- #1 MySQL interpolateParams を true に設定(33,639)
- #2 AddAnnouncement(): UnreadAnnouncement の追加が複数のINSERT文だったのを一件のINSERT文にまとめる(36,942)
11:00 - 最終スコア 42,129
- #3
courses.status
,unread_announcements.is_deleted
にインデックスを追加 - #3
WHERE courses.status !=
をWHERE courses.status IN()
に変更(36,840) - #4 createSubmissionsZip(): 外部コマンドを起動していたのをGoネイティブでZipファイルを生成する(39,565)
- #5 echo frameworkのログ出力を停止(42,691)
12:00 - 最終スコア 41,856
- #6, #7 SubmitAssignment(): io.ReadAll() + os.WriteFile() を io.Copy() に書き換え(44,199)
- #10 archive/zip を github.com/klauspost/compress に変更(44,847)
- #13 GetCourseStatus(): コースの存在確認で
SELECT COUNT(*)
を実行していたのを削除し、UPDATE
文の RowAffected() の件数で確認するようにしたのとトランザクション排除(46,532)
13:00 - 最終スコア 43,922
- #9 GPAの統計値をSingleflightで処理する(46,376)
14:00 - 最終スコア 45,169
- #12 GetClasses() のトランザクションを排除(45,423)
15:00 - 最終スコア 71,532
- #8 GetAnnouncementList()の改善
LIMIT ? OFFSET ?
を排除しannouncements.id
でページング()unread_announcements
テーブルのuser_id
,is_deleted
にインデックスを追加
- #14 DownloadSubmittedAssignments() のトランザクションを排除(71,785)
16:00 - 最終スコア 87,903
- #15 db.SetMaxOpenConns() のチューニング (92,244)
17:00 - 最終スコア 93.716
- MySQL InnoDBの秘伝のたれ
- nginx の秘伝のたれ
- 再起動試験
2021-09-20追記: ブラウザ動作確認失敗に関して
(85,666) Oops! (提出課題のダウンロードが404)
提出課題のダウンロードというのは以下のEndpointだと思われます
GET /api/courses/:courseID/classes/:classID/assignments/export
提出済みの課題ファイルをzip形式で一括ダウンロード
Goのアプリ内の関数でいうと DownloadSubmittedAssignments()
です。
今回、3つほど修正を加えていたのですが、最後に行なった以下の修正に問題があったと思われます。
- #14 DownloadSubmittedAssignments() のトランザクションを排除(71,785)
この修正のうち Class が存在しているかのチェックする処理に問題がありました。
if result, err := h.DB.Exec("UPDATE `classes` SET `submission_closed` = true WHERE `id` = ?", classID); err != nil {
c.Logger().Error(err)
return c.NoContent(http.StatusInternalServerError)
} else if classCount, _ := result.RowsAffected(); classCount == 0 {
return c.String(http.StatusNotFound, "No such class.")
}
SELECT COUNT(*)
の代わりに、UPDATE
できた行数が0の場合にClassが存在しないという扱いにしておりました。
2度アクセスすると、既にClassの submission_closed
は true
に設定されているため result.RowsAffected()
は0になってしまい、
404がレスポンスされてしまう結果となりました。
ベンチマーカーでは1度しかアクセスしないため、Failにならずに済んでいたのだと思われます。 最終的にブラウザで試験を行うという重要なことをやっていなかったのが問題であったと反省しております。
また、二度目の UPDATE
の際は0行になるという点に関して仕様をきちんと把握できていなかったため、このようなコードを書いてしまいました。
ひとつ勉強になりました。