2020-10-11

ISUCON10 本選8位でした #isucon

概要

10月3日にISUCON10 本選にチーム名 hidekiy、チームメンバー @hidekiy, @kotaroy で参加して、結果8位でした。賞金圏内は逃しましたが、過去の本選出場時のやられっぷりに比べて、若干の進歩は感じました。

何をやったかメモ

10:00

レギュレーション、アプリ仕様確認
盛り沢山過ぎて過去の ISUCON 本選でほぼ何もできなかった悪夢が蘇って焦る。

11:00

アプリのコード確認、やはりボリューム感が凄くて気分が悪くなる。
予選と同じく Cloud Profiler, Cloud Trace 設定する。サーバー1号機がメモリ不足でアプリのビルドが遅すぎるので、仕方なくスペックが少し良さそうな2号機に移行したら行けた。

12:00

ホームディレクトリに作った Makefile から、make -C webapp/golang としていたら明後日の場所 ~/bin にバイナリが出来ていてデプロイ出来ていない事に気づく。(cd webapp/golang && make) として対処完了

13:00

ListNotifications の負荷が高いため、Web Push に移行する対応を行う。サンプルコードのおかげて特に難しい事は無く出来た。

14:00

Audience Dashboard はユーザーごとに変化させなくて良く、一律でキャッシュ可能なので、singleflight で一定時間内(1秒間)に来たユーザーには同じレスポンスを返しておく対応をする。シリアライズ後のバイナリを作るところまでを共通処理とした。

15:00

Leaderboard を対処するため、クエリ側からユーザー固有パラメーターを抜いて、ジョブ履歴とチーム一覧を全ユーザー共通で取得出来るようにし、ユーザー固有の調整(スコアフリーズ中のスコアなど)は後でアプリ側で行うことで、Audience Dashboard と同様にキャッシュ可能にする

16:00

ListNotifications で使っている loginRequired の負荷が高いので調べたところ、必ずしも getCurrentTeam しなくとも、contestant.TeamID が入っている事で判断出来るようなので修正

17:00

ListClarifications も同様に、全ユーザー共通でDBクエリ結果のキャッシュを、アプリ側でユーザー固有のフィルタをしようと修正したが、ベンチマーカーの不整合検知を解決できず元に戻す。
チームキャパシティを増やすとエラーが出て動かなくなるが、よう分からんので大丈夫な所まで減らして回避 (Envoy の Too many open files だった模様)。この影響により再起動しないと調子が悪くなる状態になり大変困る。再起動すれば動くであろう状態にして競技時間終了

反省点

  • インフラ
    • 3台の CPU コア数、メモリ容量がどうなってるか良く分かっていなかった。
    • 最後まで2号機のみを使っていて、複数台構成に出来ていなかった。
    • Envoy のトラブルシュートと設定修正が出来ていなかった。
  • アプリ
    • singleflight だけ使うんじゃなくて cache + singleflight が良かったかもしんない。
    • ベンチマーカー側のアプリのロックなどを改良出来ていなかった。
スコアフリーズ後の最終リーダーボードに、1時間ほど2位で載っていたのは嬉しかったです🤣

謝辞

いつも ISUCON を通して、何も出来なくて負けるのがとても悔しいから、日々精進するという貴重な機会を頂いていると思います。
運営の方々には、このような素晴らしいコンテストを開催いただき大変感謝しています。

2020-09-13

ISUCON10 予選通過しました #isucon

チーム名 hidekiy で、@kotaroy と ISUCON10 予選に参加して、何とか通過しました。
ブログ記事の募集期間が終わらないうちに、当日の行動について記録しておきます。

タイムライン

12:20

予選開始
仕様把握、なぞって検索が本丸っぽい予想。
不要そうな node_modules, target を抜いて、コードを Git 管理する。SSH のエージェント転送で連れてきた鍵を使って、サーバーから直接 GitHub にアクセスしてデプロイとかやる事にする。
サンプルの SSH の設定ファイルに、8081~8083 でそれぞれのサーバーのポート80を開けるようにする設定を入れた LocalForward を追加してチーム内に共有した。

14:00

去年のISUCON予選1位チームのありがたい記事 ISUCON9 予選を全体1位で突破しました

 で学んだ Cloud Trace, Cloud Profiler をまず設定する。New Relic はプロファイルが取れれば不要と思ったんで、入れない事とする。リソース監視は top を更新間隔1秒で目視確認して行う事にした。

いずれ問題になってくると思ったんで、nginx.conf でのボット対策を依頼した。

15:00

検索機能がクソ重い事分かったんで、ソート用にいくつかインデックスを追加 (EXPLAIN 確認してない)
MySQL サーバーのスレーブ追加を依頼

16:00

なぞって検索のN+1クエリについて、1段目のクエリのWHERE条件に、後段の条件を追加する感じで修正して対応した。
SELECT *
FROM estate
WHERE
  latitude <= ? AND latitude >= ? AND longitude <= ? AND longitude >= ?
  AND ST_Contains(ST_PolygonFromText(%s), ST_GeomFromText(CONCAT('POINT(', latitude, ' ', longitude, ')')))
ORDER BY popularity DESC, id ASC
latitude, longitude から POINT を作る方法について、いま冷静に見ると ST_GeomFromText は使わずとも、直接 POINT(latitude, longitude) で大丈夫と思います。

16:30

searchRecommendedEstateWithChair の条件式が直そうとしてバグらせた。
いつバグったか最初は不明だったためコミットごとにベンチ実行し、切り分けの後当該コミットを Revert して復旧した。

17:00

椅子購入時のロックが無駄なので UPDATE ~ WHERE ~ で、Affected Rows を見る感じに修正した。
SELECT * を画面上に使うカラムのみに減らしてみたが、FAIL しちゃうので元に戻す (レギュレーション良く読んでない)、あまり減らせそうにないので、放置する事とする。

18:00

MySQL スレーブが出来たので、物件検索を別のDBに向けるように修正した。
やる事が無くなったので、なぞって検索の空間インデックス対応に着手する。

19:00

空間インデックス対応 (estate に POINT 型のカラム location を追加) が完成して、なぞって検索のクエリを修正 (EXPLAIN 確認した)
SELECT *
FROM estate
WHERE ST_Contains(ST_PolygonFromText(%s), location)
ORDER BY popularity DESC, id ASC
この辺でスコア2500くらい獲得

20:00

20時半くらいから謎に FAIL し始めて、initialize 時のスリープとか試したが特に変化せず、再起動したりして何とか最終スコア 2210 獲得して終了。

感想

とても素晴らしい運営と問題作成をありがとうございました。
本選でもよろしくお願いします。

反省点

popularity DESC, id ASC の複合インデックスは、ソート時に使われていると思っていたけれど、使われておらず、その事に最後まで気づきませんでした。同時にデプロイした rent ASC, id ASC のインデックスが多少効いていたことで満足していました。MySQL 5.7 ドキュメント: ORDER BY Optimization も今更ながら読んでます。そもそも複合インデックスの末尾に PRIMARY KEY のカラム入れるのはおかしかったですね😅
なぞって検索のクエリに LIMIT を入れられるはずが入れられていなかった。影響度合いは不明ですが、せっかくクエリで多角形内包条件込みの最終結果を取り出せるように直したのに、無駄に取得してしまっていました。
Echo Framework のデバッグモードがオンで、ログも出したままでした。デバッグモードは影響をあまり認識していなかったのですが、JSON エンコード時に無駄にインデントを追加してくれたりするので、検索結果の巨大なレスポンスの時、多少は効いてきたかもしれないです。
Cloud Profiler は、プロファイル取得にいちいち手を取られずに、パフォーマンス改善で刻々と変化するボトルネックを分析するのに非常に役に立ちました。



2020-08-16

Google Trust Services 用の CAA レコードを追加しました

当ブログで使っている独自ドメイン hidekiy.com では、学習用で無駄に CAA レコード を設定して証明書発行が出来る認証局を制限しているのですが、Google Trust Services (GTS) についてのレコードを追加した事についての記事です。
2018年に設定した当初は、Blogger の独自ドメイン用証明書には Let's Encrypt が使われていたので、以下のような CAA レコードを設定していました。
0 issue "letsencrypt.org"
0 issuewild "letsencrypt.org"
その後、巷の Blogger のブログでは GTS へ変更されているのに、何故か自分のブログだけ GTS に切り替わらないのが気になって調査した結果、GTS の証明書発行が出来るような CAA レコードを設定する必要がある事が分かり、Google Trust Services, Certificate Policy などを参考に、
0 issue "pki.goog"
0 issuewild "pki.goog"
を追加したところ、無事 GTS 発行の証明書に置き換わりました。 
Blogger 側の挙動としては、GTS、Let's Encrypt の順で発行可能な証明書が発行されているような雰囲気があります。

関連記事

2019-02-03

Intel Dual Band Wireless-AC 7260 付属の Bluetooth がデバイス記述子要求の失敗となる

Windows 10 の PC にて、インテル® ドライバー & サポート・アシスタント というツールを使って、Intel 製のドライバを色々更新していたら、使用していた Intel Dual Band Wireless-AC 7260 付属の Bluetooth 部分が正常に認識されなくなり、デバイス記述子要求の失敗 コード43 というエラーがデバイスマネージャー上で出るようになりました。

再起動、シャットダウン、シフトキーを押しながらシャットダウン、ドライバを削除と色々試したのですが、特に変化なく、途方に暮れていたところ、こちらの記事
圏外恐怖症: デバイス記述子要求の失敗 コード43 なんじゃこれ!!
を参考にして、PC の電源をコンセントより抜いて、しばらく放置してから起動したところ、正常に認識され動作するようになりました。

こちらの方法は試していないのですが、同様なエラーを別の方法で解決されているようでした。
超絶はらへ('A`) - USB機器がエラーコード43を返してきた場合の対処方法

詳しく調査していないのですが、必要な何らかのリセット処理が正常に行われておらず、デバイス側とホスト側が矛盾した状態になり、復旧出来なくなる不具合があるのではと想像しています。

2018-05-06

ASUS TPM-L R2.0 のファームウェアを 5.63.3144 に更新しました

Windows 10 Version 1803 に更新したところ、Windows Defender セキュリティセンターにて、TPM チップのファームウェアの更新が必要という警告が出るようになったので、さっそく更新してみました。作業内容についてメモしておきます。

更新手順
1. 更新元バージョンを調べて USB ストレージを準備
2. ASUS のマニュアルの指示の通り、以下を実行
2.1. UEFI の設定で、Security Device Support と Launch CSM を Disable
2.2. USB ストレージから起動して、EFI シェルで更新手続きを実行
2.3. UEFI の設定を元に戻して再起動
3. Microsoft の指示の通り TPMのクリアを実行

補足
更新手順はマニュアルの通りで上手くいきましたが、更新元のバージョンに合わせたファイルをダウンロードして使用することが必要でした。
更新元のバージョンによっては、ASUS のダウンロードページで Show all を押すと出てくるもう一つの方を使う必要がある場合があります。

TPM チップのバージョンを確認するには、
Windows Defender セキュリティセンター > デバイスセキュリティ > セキュリティプロセッサ > セキュリティプロセッサの詳細
を見ると良いようです。

EFI シェルに入る方法は、配布されているファイルを、X:\EFI\Boot\BOOTX64.EFI というパスになるように USB ストレージに展開して、起動すれば良いようでした。

UEFI の設定変更や、TPM のクリアを行う際は、BitLocker の保護の中断を行ってから作業をすると回復キーを何度も入れなくて済むので便利です。

リンク
セキュリティ プロセッサ (TPM) ファームウェアを更新する - Windows Help
TPM-L R2.0 Driver & Tools | Motherboard Accessory | ASUS Global - 2018年5月現在、更新元バージョンの異なる2種類のファイルがダウンロード出来るようになっています。
TPM-L R2.0 Manual | Motherboard Accessory | ASUS Global - ファームウェアの更新の仕方がコマンドと共に載っているので必読です。