ISUCON練習 private-isu[1] Windows上構築~ベンチ成功(0点)
private-isuをやっていく。
環境
- Windows 10
- Docker Desktop
- 言語はGo
ログ
アプリ起動
- Docker Desktopは起動しておく
してないとerror during connect: this error may indicate that the docker daemon is not running:
docker compose build app
- 画面確認
ベンチ
- 実行してみる
$ docker run --network host -i private-isu-benchmarker /opt/go/bin/benchmarker -t http://host.docker.internal -u /opt/go/userdata exec /opt/go/run.sh: no such file or directory
Windows で Docker 環境構築時のエラー対処法【no such file or directory】
この問題か・・・git config --global core.autocrlf inputしてやり直し
- 再実行
$ docker run --network host -i private-isu-benchmarker /opt/go/bin/benchmarker -t http://host.docker.internal -u /opt/go/userdata /opt/go/run.sh: line 3: /opt/go/C:/Program Files/Git/opt/go/bin/benchmarker: No such file or directory
WindowsのGit Bashでパス変換が予期せぬ動作をする場合の対処法 - Qiita
今度はこれ。MSYS_NO_PATHCONV=1 で対処
- 再々実行
$ MSYS_NO_PATHCONV=1 docker run --network host -i private-isu-benchmarker /opt/go/bin/benchmarker -t http://host.docker.internal -u /opt/go/userdata {"pass":false,"score":25,"success":68,"fail":6,"messages":["静的ファイルが正しくありません (GET /css/style.css)","静的ファイルが正しくありません (GET /js/main.js)","静的ファイルが正しくありません (GET /js/timeago.min.js)"]}
webappの方の資材再作成忘れてた
- 再々々実行
$ MSYS_NO_PATHCONV=1 docker run --network host -i private-isu-benchmarker /opt/go/bin/benchmarker -t http://host.docker.internal -u /opt/go/userdata {"pass":true,"score":0,"success":209,"fail":64,"messages":["リクエストがタイムアウトしました (GET /)","リクエストがタイムアウトしました (GET /@angelina)","リクエストがタイムアウトしました (GET /@clarissa)","リクエストがタイムアウトしました (GET /@colleen)","リクエストがタイムアウトしました (GET /@dina)","リクエストがタイムアウトしました (GET /@ilene)","リクエストがタイムアウトしました (GET /@kristina)","リク エストがタイムアウトしました (GET /@olivia)","リクエストがタイムアウトしました (GET /@rowena)","リクエストがタイムアウトしました (GET /@shana)","リクエストがタイムアウトしました (POST /login)","リクエストが タイムアウトしました (POST /register)"]}
スコア0だけどようやくpass!
makeインストール
ローカルでもmakeできるように。
- PATH通し
C:\Program Files (x86)\GnuWin32\bin
- VSCode再起動
where make
ISUCON練習 ISUCON12予選環境構築(自己署名証明書利用)
久しぶりに構築。色々あったのでやり方メモ。
資材
aws-isucon/isucon12-qualify at main · matsuu/aws-isucon · GitHub
構築
インスタンス起動
インスタンスタイプ選択
https://ap-northeast-1.console.aws.amazon.com/ec2/home?region=ap-northeast-1#SpotInstances:
足りるか分からないが一旦安いt3.microにする→apt updateで無応答になってしまったのでt3a.mediumに変更。
インターネットからの HTTPS トラフィックを許可 をチェック。
ssh接続に成功。
ssh -i "2021-06-14-isucon-renshu.pem" ubuntu@ec2-hoge.ap-northeast-1.compute.amazonaws.com
ベンチ正常終了に成功。
h$ ./bench -target-addr 127.0.0.1:443 [ADMIN] 19:50:46.609523 TargetURL: https://t.isucon.dev, TargetAddr: 127.0.0.1:443, RequestTimeout: 30s, InitializeRequestTimeout: 30s, StrictPrepare: true, ReproduceMode: false [ADMIN] 19:50:52.497786 POST /initialize 200 初期化 19:50:52.497895 初期化リクエストに成功しました 実装言語:go 19:50:52.497912 整合性チェックを開始します [ADMIN] 19:50:52.528032 POST /api/admin/tenants/add 200 新規テナント作成 [ADMIN] 19:50:52.550243 GET /index.html 200 /index.htmlを確認 [ADMIN] 19:50:52.556737 GET /js/app.3a4ec98c.js 200 /js/app.3a4ec98c.jsを確認 ... 19:52:19.417110 Error 1 (Critical:0) 19:52:19.417121 PASSED: true 19:52:19.417132 SCORE: 1880 (+1898 -18(1%))
クライアント証明書
おいてあるファイルのままだとChromeにインポートできなかったので変換。
cd /etc/nginx/tls openssl pkcs12 -export -in fullchain.pem -inkey key.pem -out fullchain.p12
isucon12-qualify/nginx/tls at main · isucon/isucon12-qualify · GitHub
設定してみたがERR_CONNECTION_TIMED_OUT
期限切れてた。
$ openssl x509 -in fullchain.pem -text -noout Certificate: Data: Version: 3 (0x2) Serial Number: 03:b0:ab:d5:14:2d:81:74:e8:26:1a:d4:f8:21:ae:20:62:87 Signature Algorithm: sha256WithRSAEncryption Issuer: C = US, O = Let's Encrypt, CN = R3 Validity Not Before: Jun 17 04:40:52 2022 GMT Not After : Sep 15 04:40:51 2022 GMT
openssl genpkey -algorithm RSA -out key.pem -pkeyopt rsa_keygen_bits:2048 openssl req -new -key key.pem -out request.csr openssl x509 -req -days 365 -in request.csr -signkey key.pem -out fullchain.pem openssl dhparam -out dhparam.pem 2048 sudo cp /tmp/mycert2/myserver.crt fullchain.pem sudo cp /tmp/mycert2/myserver.key key.pem sudo service nginx restart sudo service nginx status
これだとブラウザアクセスが上手く行かない。
Unable to communicate securely with peer: requested domain name does not match the server’s certificate. HTTP Strict Transport Security: true HTTP 公開鍵ピンニング: false
Google Chrome から HTTPS でアクセスすると警告が表示される - Customer Support
Subject Alternative Name (SAN) の設定がないのがダメなのかも。
san.conf
[req] distinguished_name = req_distinguished_name x509_extensions = v3_req prompt = no [req_distinguished_name] CN = *.t.isucon.dev [v3_req] keyUsage = keyEncipherment, dataEncipherment extendedKeyUsage = serverAuth subjectAltName = @alt_names [alt_names] DNS.1 = *.t.isucon.dev DNS.2 = isucon.t.isucon.dev
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout myserver.key -out myserver.crt -config san.cnf openssl pkcs12 -export -out myserver.pfx -inkey myserver.key -in myserver.crt ファイル入れ替えてnginx再起動
それでもERR_SSL_KEY_USAGE_INCOMPATIBLEになった。 Key Usage属性がダメっぽい。
openssl genrsa -out myserver.key 2048 openssl req -new -key myserver.key -out myserver.csr -subj "/CN=*.t.isucon.dev" echo basicConstraints = CA:FALSE > extfile.cnf echo subjectAltName = DNS:*.t.isucon.dev >> extfile.cnf echo keyUsage = digitalSignature, nonRepudiation, keyEncipherment >> extfile.cnf openssl x509 -req -days 365 -in myserver.csr -signkey myserver.key -out myserver.crt -extfile extfile.cnf openssl pkcs12 -export -out myserver.pfx -inkey myserver.key -in myserver.crt openssl x509 -in myserver.crt -text -noout ファイル入れ替えてnginx再起動
ここまでやってもNET::ERR_CERT_AUTHORITY_INVALID。
そのあと↓とchrome再起動をやったらできた。どれが最低限必要だったのか整理できてないが、一旦ブラウザ表示はできた。
アドレスバーに chrome://net-internals/#hsts を入力します。 "Delete domain security policies" のセクションに移動します。 "Delete domain" のフィールドにドメイン名(例:isucon.t.isucon.dev)を入力し、"Delete" ボタンをクリックします。
Terraform Associateに合格した
Terraform Associateに合格した。体験記を書いておく。(勿論規約上書ける範囲で)
費用
項目 | 費用(円) |
---|---|
試験 | 9,366 |
Udemy | 2,400 |
AWS | 236 |
合計 | 12,002 |
教材
- Associate Tutorial List | Terraform - HashiCorp Learn を全部実施
- HashiCorp Certified: Terraform Associate Practice Exam 2022 | Udemy を4個目まで解いた
事前知識:仕事で何度か簡単なtf修正、plan/applyを経験したことがあるくらいの状態だった。
学習方法
公式Associate Tutorial List
用意した環境
- クライアント(Windows 10)
- Git Bash
- Visual Studio Code (+Terraform拡張)
- Terraform
- Docker Desktop
- AWSアカウント
- Terraform Cloud
Windowsだと環境エラーに引っかかるかもと思っていたが、特に問題はなかった。 AWS費用は全チュートリアルをやって2ドル弱だった。
チュートリアル実施の流れ
ドキュメントを読んだ上で、
- AWSでアクセスキー発行
- Visual Studio CodeでTerraform拡張で補完を効かせつつ写経
- terraformコマンドで実行
- AWSコンソールでできたものを見る
のような感じで実施した。
Udemy
- 問題を解くとき:本番が英語なので、英文読む練習を兼ねて基本そのままで解く
- 解説を見るとき:Chromeの翻訳機能で日本語にして読む
Udemyは問題文以外のペインの表示が大きくて見づらいが、サポートに聞いたところ畳む方法はないとのこと。
結果
Status: Pass
Overall Score: 91%
結果は試験ツールでも見られるが、終わってすぐにメールでも届いていた。
困ったこと
試験前
試験中
- 最初に試験ツールが他アプリ終了を要求するが、Dropboxが終了させてもタスクマネージャからキルしても復活してチェックを通せなかった。仕方ないのでDropboxをアンインストールして対処した。
- たまにアプリが自動起動するのか、OutlookやPhone(何のアプリか不明)が試験ツールにブロックされたという表示が出た。OKを押すだけで消えたが、試験に影響しないか不安だった。結局特に問題はなかった。
感想
公式のチュートリアルが実践的で良かった。
机からディスプレイはどけたが、電源ケーブルと映像ケーブルは流石に大変でそのままにしていたが、特に何も言われなかった。
参考にした記事
LeetCode Weekly Contest 282 復習
Rank 4615 / 22307 4問目DPが解けなかった
問題
- . Minimum Time to Finish the Race https://leetcode.com/contest/weekly-contest-282/problems/minimum-time-to-finish-the-race/
解説
この解説が分かりやすかった https://leetcode.com/problems/minimum-time-to-finish-the-race/discuss/1802444/C%2B%2B-Linear-time-DP-with-explanation
ポイント
- 問題文からdp[n+1]がdp[n]から導けそうなことに気づく
- 問題文から漸近式を導く
- タイヤを交換するしない
- さかのぼって交換する場合もタイヤの連続使用回数の上界で縛れること
- オーダを落とすための制約(タイヤの連続使用回数の上界がchangeTimeとfi * ri(x-1)から導かれる)
実装
- int32超え(2e9)の扱い
ISUCON11予選記録 Fratty 164位
チームFratty、ISUCON11予選は参考スコア27426 164位でした。悔しい・・・。
振り返りのためのメモ。
時系列
大きくスコアが伸びたポイント
時刻 | スコア | メモ |
---|---|---|
10:06 | 1631 | 初回 |
11:38 | 16614 | インデックス追加1回目 |
15:55 | 31803 | N+1 trend, getIsuList / DB分散 |
スコアグラフ
スコア表 後半は点数記入する余裕がなかったが、結局31803が最高点だった。
やったこと
- mockの停止:効果不明瞭
- インデックス追加(1):明らかに向上
- インデックス追加(2):効果不明瞭
- N+1解消 /api/trend:効果不明瞭(スコアがさがったが対象APIは高速化していた)
- N+1 getIsuList / DBを別サーバに分散:明らかに向上(一緒にやってしまったので混在)
- nginx処理の別サーバへの分散:効果不明瞭、ただしサーバ1号機のサチりは解消できていた
- drop値チューニング:結局、タイムアウトを減らせなかったので初期の0.9が一番スコアが出てそうだった
良かったこと
できなかったこと
- タイムアウトがなぜ起きるのかを突き止める必要があると思っていたが、それを調べる方法がわからなかった
- nginxの499ログのidからなにかできたかも
トラブル
Goのパス周りが壊れる(解決)
- ビルドが一時できなくなる。.bashrcの読み直しにより解消。
-
- これの影響でIDE機能が使えず、Goの記述速度がかなり低下した
- ローカルや別サーバでやろうとしたが、could not import...のエラーで動かせず断念。
モニタ枚数が足りなくて写したい情報が写せず、操作にスイッチングコストがかかっていた(長時間なので、馬鹿にならない疲労になる)
CloudFormationで別スタックを立てて並列開発できると思っていたが、IP数制限に引っかかった
CloudFormationでAMIを差し替えて切り戻しや複製ができると思っていたが、内部IPのような固定パラメータがupdateを阻害してできなかった
ダッシュボードでパーセンタイルデータを出してなかったので解析精度が落ちた
今後やりたいこと
ISUCON10本選 練習環境構築 ベンチマーカーを動作させる
ISUCON10本選に挑戦してみたくてまずは環境構築したメモ。
とりあえずベンチ実行してスコアが出てアプリが見えるところまでやった。
ISUCON10 本選当日マニュアルは以下。
isucon10-final/manual.md at master · isucon/isucon10-final · GitHub
インスタンス起動、SSH接続
「ISUCONの過去問にチャレンジするためのシンプルな環境構築」を使う(ISUCON9予選) - kavo’s diary と同様にami-0f7362c1bbc7e30ecを使ってインスタンスを立ち上げ、SSH接続。
isuconユーザに切り替え。
$ sudo -i -u isucon
サービス起動
立ち上げた直後は起動していないので、起動する。 参考実装の切り替え方法
sudo systemctl enable --now xsuportal-web-golang.service sudo systemctl enable --now xsuportal-api-golang.service
仮想ポータルアクセス
どこから仮想ポータルを見られるのかは当日マニュアルとアプリケーションマニュアルをざっと見ただけだと分からなかった。が、xsuportal-api-golang.serviceのログで9292で受けてるっぽいことに気づく。
$ sudo systemctl status xsuportal-api-golang.service ... http server started on [::]:9292
curlしてみると弾かれる。ポート開けてなかった。
$ curl localhost:9292
AWSコンソールで9292を開けたらcurlでhtmlが返ってきた。
$ curl localhost:9292 <!doctype html><html lang="ja" class="has-background-grey-lighter"><head><title>XSUCON Portal</title><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="xsu:api-base-url" content="/"/><link href="/packs/vendor.css" rel="stylesheet"></head><body><div id="app"></div><script src="/packs/vendor.js"></script><script src="/packs/audience.js"></script></body></html>i
ブラウザでhttp://x.x.x.x:9292/ を開くとタイトルだけ出て中身はカラのページが見えた。
ベンチマーク実行
ポータルの中身はカラに見えるのは以下の理由のよう。
なお、初期状態ではアプリケーションの動作に必要なデータが不足しているため、アプリケーションをブラウザから動作確認するためには、一度負荷走行を実行してください (後述)。
Running a benchmarker locallyのコマンドを参考に実行してみる。そのままだと下記エラーになる。3000番ポートで待ってなさそうだし、本番と同じ構成になってなさそう。
dial tcp [::1]:3000: connect: connection refused
$ sudo lsof -i:3000 $
試しにtargetのポートをapiが受けてる9292に変更し実行してみる。
$ ./bin/benchmarker -exit-status -target app.t.isucon.dev:9292 -host-advertise local.t.isucon.dev -tls-cert ../secrets/cert.pem -tls-key ../secrets/key.pem 16:56:17.000277 ISUCON10 benchmarker e858b2588a199f9c7407baacf48b53126b8aeed6+dirty 16:56:17.001955 ===> PREPARE 16:56:26.754919 Language: go 16:56:26.754936 HTTP: http://app.t.isucon.dev:9292/(tls=false) 16:56:26.754942 gRPC: localhost:50051 16:56:26.755009 ===> LOAD 16:56:26.755049 LOAD INFO Registration Open at: 2021-06-16 16:56:27 +0000 UTC Contest Start at: 2021-06-16 16:56:37 +0000 UTC Contest Freeze at: 2021-06-16 16:57:17 +0000 UTC Contest Ends at: 2021-06-16 16:57:27 +0000 UTC 16:57:36.762065 ===> VALIDATION 16:57:47.793989 ERR: validation: critical: http: Get "http://app.t.isucon.dev:9292/api/contestant/dashboard": context canceled 16:57:47.794491 ERR: validation: timeout: critical: timeout: http: timeout: Get "http://app.t.isucon.dev:9292/api/contestant/dashboard": context deadline exceeded 16:57:47.794515 ERR: validation: timeout: critical: timeout: http: timeout: Get "http://app.t.isucon.dev:9292/api/contestant/dashboard": context deadline exceeded 16:57:47.794636 ERR: validation: critical: http: Post "http://app.t.isucon.dev:9292/api/login": context canceled 16:57:47.794724 ERR: validation: critical: http: Get "http://app.t.isucon.dev:9292/api/contestant/dashboard": context canceled 16:57:47.794820 ERR: validation: critical: http: Get "http://app.t.isucon.dev:9292/api/contestant/dashboard": context canceled 16:57:47.794877 ERR: validation: critical: http: Get "http://app.t.isucon.dev:9292/api/contestant/dashboard": context canceled 16:57:47.794933 ERR: validation: critical: http: Get "http://app.t.isucon.dev:9292/api/contestant/dashboard": context canceled 16:57:47.794989 ERR: validation: critical: http: Get "http://app.t.isucon.dev:9292/api/contestant/dashboard": context canceled 16:57:47.795089 ERR: validation: critical: http: Get "http://app.t.isucon.dev:9292/api/contestant/dashboard": context canceled 16:57:47.805110 ===> SCORE Count: admin-answer-clarification: 8 admin-get-clarification: 8 admin-get-clarifications: 73 audience-get-dashboard: 370 create-team: 10 enqueue-benchmark: 118 finish-benchmark: 109 get-clarification: 8 get-dashboard: 60 join-member: 20 list-notifications: 1491 post-clarification: 8 resolve-clarification: 8 (1290 * 1.0) + 37 - 400(err: 0, timeout: 405) Pass: false / score: 927 (1327 - 400) Fail reason: Critical error
Pass: falseとあるが、一応スコアは出ている。
ポータルサイトもタイムラインチャートやリーダーボードが見えるようになった。
ユーザとしてログインして管理者・競技者のページも見えた。
XSUCON Admin
XSUCON Contestant
最低限ベンチ動作とアプリが見えるようになった。
「ISUCONの過去問にチャレンジするためのシンプルな環境構築」を使う(ISUCON9予選)
公式で用意されているお手軽構築を使ったメモ https://isucon.net/archives/54946542.html
今回はISUCON9予選をやってみる。
キーペア作成
EC2>インスタンスを起動
AMI検索
https://github.com/matsuu/aws-isucon のAMI IDで検索。今回は「ami-03b1b78bb1da5122f」で検索し、コミュニティ AMI (1)を選択。
インスタンスタイプ選択
今回はt3.smallにしてみる。 https://aws.amazon.com/jp/ec2/pricing/on-demand/
安くしたいのでスポットインスタンスを使う。
セキュリティグループ
SSH接続と、アプリをブラウザから見たいので22と80を開けておく。(IP縛った方が安全。)
起動>キーペア選択
さっき作ったのを選ぶ。
起動後にSSH接続しようとするとConnection timed out。
ネットワーク設定修正
こちらのチェックリストに助けられた。 https://qiita.com/yokoto/items/338bd80262d9eefb152e
インターネットゲートウェイがdetachedになっていたのでVPCにアタッチ。
また、ルートテーブルにIPv4のルートがなかったので追加。
SSH接続
ローカルPCのgit bashからつないでみる。接続成功。
$ ssh -i "2021-06-14-isucon-renshu.pem" ubuntu@18.x.x.x Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 5.4.0-1045-aws x86_64) ...
アプリ画面を見る
https://18.x.x.x/ にブラウザでアクセスする。警告が出るが、続行するとアプリ画面が見えた。
めっちゃお手軽でありがたみがすごい。