ISUCON練習準備メモ
ISUCONの練習準備
チーム内部向けに、久しぶりにISUCON練習やるとき、諸々の操作を思い出すためのメモ。とりあえず上から順にやっていけば感覚が蘇る・・・はず。
クラウドコンソール
- インスタンス起動
ツール
- RLoginでログイン
- VSCodeでRemote Development接続
- Slack
よく使うaliasを思い出す
0 #ベンチ一式実行 br #vi bash profile so #source bash profile sli #サービスリスト sre #アプリ再起動
アプリ・ベンチ・ログ
- ブラウザでアプリにアクセス
- ベンチマークを実行、slackで結果確認
- ログ出てるか確認
- ログ分析結果が出てるか確認
メモ
スコアを追っていけるダッシュボード的なのが欲しい
ISUCONのススメの商業版・同人版の違い
サークルFrattyが技術書典9で頒布した「Webサービスチューニングコンテスト ISUCONのススメ」ですが、商業版の出版が決まりました。同人版から内容が増強されており、いくつか違いがあるため本記事にてまとめます。
同人版・商業版の差異は次の表の通りです。
同人版 | 商業版 | |
---|---|---|
販売プラットフォーム | 技術書典オンラインマーケット | 各種プラットフォーム |
媒体 | 電子版のみ | 電子版/印刷版 |
価格 | 500円(税込) | 電子版1,600円(税別) 印刷版 2,000円(税別) ※1 |
発売日 | 2020/09/12 | 2021/02/05 |
内容 | 詳細はこちら | 左記にリソースモニタリング、N+1問題・処理並列化・サーバ間リソース分散のトピックを追加 |
- ※1 それぞれのプラットフォームのセール等により価格が変化する場合があります。
(参考)目次の差分
技術書典9で技術同人誌を出した記録(時間推移、やったこと、ツール選定等)
2020/09/12-22に開催された技術書典9で、チームFrattyとしてWebサービスチューニングコンテスト ISUCONのススメ:Frattyという本を出した。 そのときの時間推移とやったこと、使ったツールや選定理由の記録。
大体3人で1ヵ月で79ページの本を作成・出版した。
技術書典終了後に記念に作った物理本:
タイムライン
- 6/27 チームのLINEグループで技術書典でISUCONの本出してみない?と言ってみる
- 7/3 打ち合わせ1 本のネタ出し
- 7/10 技術書典9の日程(9/12-22)発表、改めてチーム3人で本を出そうと決める
- 7/18 打ち合わせ2 本のネタ出し
- 7/25 リポジトリ作成
- 8/1 技術書典9参加フォーム公開
- 8/2 打ち合わせ3 チーム名検討、アイコン検討、参加申し込み
- 8/8 打ち合わせ4 ゆるい目次書き出し
- 8/10 18:20 技術書典9参加申込審査結果[参加]メール通知
- 8/11執筆本格開始~
- 8/21 チームアイコン決定
- 8/22 打ち合わせ5 目次リファクタ
- 8/30 打ち合わせ6 タイトル決定
- 9/4-11 追い込みレビュー
- 9/8 夜 暫定版入稿
- 9/9 23:36 暫定版 販売審査[承認]メール通知
- 9/11 夜 完成版入稿
- 9/12 0:18 完成版 販売審査[承認]メール通知
- 9/12 10:00 技術書典9販売開始
- 9/22 技術書典9終了
データ
- 執筆期間:8/11~9/11の約1ヵ月
- 本
- A5 表紙込79ページ
- 電子版のみ
- 表紙は表表紙のみ(電子版なので)
- Gitリポジトリ
- 消化issue:116
- コミット数: 257
- ビルド数: 270
- PR数: 40
コミットグラフ:
進め方
- discord打ち合わせでissueを棚卸しする
- 執筆はPRであげてレビューしてもらう(ただ、実際にはPR上でレビューするというより、先にマージしてから読むことが多かった)
苦労した点
- 正解がないもの
- 本タイトル、チーム名、アイコン、表紙デザインなど、なかなか決まらなかった
- 権利関係
- 重要だが調べるのが大変
- 環境整備・インストール
- ビルド環境、校正ツールあたりでかなりエラー対処に時間食ったが、あまり頑張らず素直に動いてくれるものだけで良かった気がする
- ハマったこと
- .gitignoreのpdf除外設定の無効化をミスっていてpdfがpushできていなかった
- VSCode上でID: constimage1 にマッチする画像が見つかりませんでした。とかエラーメッセージが出てるけどビルドしたら表示されてた
使ったツール・サービス、選択理由など
全体
技術検証
- Google Cloud Platform
- バウチャーがあったのと、使い慣れていたので。
文章執筆
- Re:VIEW Template TechBooster
- VSCode
- .reのリアルタイムプレビューができる
- prhでlintしてくれる
- GitHub プライベートリポジトリ
- 今は複数人で使ってもタダ。太っ腹。
- GitHub Actions
- Google docs音声入力
- 最初のドラフトとか、とりあえず喋って原文を作るのに良かった。口に出すことで整理される効用もある。
校正
prh、redpen、JustRightProなどlintツールを色々試したが、インストールの苦労のわりにそこまで効果があった感じはなかった。後半の方になるとそんな些末なことより・・・という感じになっていく。とりあえずVSCodeにprh extention for VSCodeはさっと入るのでそれくらい入れておけばいい気がする。
- prh extention for VSCode
表紙作成
Google spreadsheetはフォント追加ができないので、Powerpointで全部やった。PDF出力も可能。画像がはみ出てても削ってくれる。
図作成
ベクタ画像が欲しくて結構苦労した。 最終的なやり方としては、作成途中では仮のpngをおいてしまい、最終工程で一気にepsを作る。画像編集の段階では編集/共有のしやすさからgoogle slideで作り、pptxでエクスポート後、パワポで該当の図形だけを選択→図として保存(png/emf)→Metafile to EPS Converterでeps作成。
- Google slide
- Powerpoint
- Metafile to EPS Converter
今回は使わなかったがvscode拡張で編集できるdraw.io統合もある。
内容議論
- Google docs
- Discord
広報
- Twitter
- チーム用アカウントを作って本の宣伝をした
アンケートフォーム
- Google forms
アイコン
- hatchful
感想
- 技術書典運営様のサポートが凄い。新規サークル向けにYouTubeで解説動画を連載したり、チャットサポートがあったり。チャットサポートレスが爆速かつ親身。ありがとうございます。
- ISUCON運営様が快く許諾を下さったので本が出せました。ありがとうございます。
ISUCON10予選問題の疑似環境をGCP上に作る(初期スコア400前後)
概要
ISUCON10予選をなるべく当時と同じように解きたいので、疑似環境を作るためのメモ。
初期スコアが456だったので、近い値が出るようにしたい。
結論
N1の1vCPU/2GBメモリ、ゾーン永続ディスク20GBで作ったインスタンスでは(ベンチマーカー内包で測って)初期スコア400前後になる。 cloudshellですぐ起動したい場合以下のスクリプトでインスタンス作成可能。
gcloud beta compute instances create isucon10q --zone=asia-northeast1-b --machine-type=custom-1-2048 --subnet=default --network-tier=PREMIUM --maintenance-policy=MIGRATE --scopes=https://www.googleapis.com/auth/devstorage.read_only,https://www.googleapis.com/auth/logging.write,https://www.googleapis.com/auth/monitoring.write,https://www.googleapis.com/auth/servicecontrol,https://www.googleapis.com/auth/service.management.readonly,https://www.googleapis.com/auth/trace.append --tags=http-server --image=ubuntu-1804-bionic-v20200923 --image-project=ubuntu-os-cloud --boot-disk-size=20GB --boot-disk-type=pd-standard --boot-disk-device-name=isucon10q --no-shielded-secure-boot --shielded-vtpm --shielded-integrity-monitoring --reservation-affinity=any
サーバスペック
GitHub - isucon/isucon10-qualify: ISUCON10予選より基本スペックは以下の通り。
OSはUbuntu 18.04.5 LTSだった。
$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 18.04.5 LTS Release: 18.04 Codename: bionic
GCPで再現する
スペック選定
CPU/Memory/Interface
GCPのマシンタイプ | Compute Engine ドキュメント | Google Cloudから似ているスペックの構成を探すと、 共有ではないコアで1vCPUが選べるのが汎用(N1)だけのようである。 汎用(N1)のカスタムで1vCPU2GBにできる。 カスタム時のネットワーク下り(外向き)帯域幅(Gbps)は書いてない気がするが、近いn1-standard-1の帯域幅は2Gbps。
#インスタンス自体が1コアでなくても、maxcpus=1を指定する方法もあるらしい。
#「vCPU」と「Core」の対応関係が調べてもいまいちよくわからない
IO throughput/IOPS
Storage options | Compute Engine Documentation | Google Cloudによると、ゾーン永続ディスクの最大持続 IOPS、最大持続スループット(MB/秒)は
ゾーンバランス永続ディスクの最大持続 IOPS、最大持続スループット(MB/秒)は
らしい。とはいっても、この最大持続 IOPS、最大持続スループットが本番インスタンスのIO throughput/IOPS制限と近い意味の数値なのかは不明。
IOPS(Input/Output Per Second)とは - IT用語辞典 e-Words
装置の特性により、読み込み(リード)か書き込み(ライト)か、シーケンシャルアクセス(連続した領域にアクセス)かランダムアクセス(飛び飛びに様々な領域にアクセス)か、転送するデータの量がどれくらいかによって1回の動作に要する時間が異なる。
このため、実用上は「4KBランダムライトIOPS」のように計測条件を明示することが多い。この例では、4キロバイトのデータを装置内の不連続な箇所に飛び飛びに書き込む動作を行った際のIOPSを表している。
例1:ゾーン永続ディスク20GB
カタログ上以下のはず。
fioを使ってストレージの性能を計測してみた - Qiitaを参考にfioというツールで測ってみる。fioのドキュメントは1. fio - Flexible I/O tester rev. 3.23 — fio 3.23-28-g7064-dirty documentation
IOPS/スループット測定目的×シーケンシャル/ランダム×R/Wの8パターン。
sudo apt update sudo apt-get install -y fio head -c 10G /dev/urandom > /tmp/test2g ls -l /tmp/test2g fio -filename=/tmp/test2g -direct=1 -rw=read -bs=4k -size=2G -numjobs=64 -runtime=10 -group_reporting -name=file1 > 1--4k-seq--r.log fio -filename=/tmp/test2g -direct=1 -rw=write -bs=4k -size=2G -numjobs=64 -runtime=10 -group_reporting -name=file1 > 2--4k-seq--w.log fio -filename=/tmp/test2g -direct=1 -rw=randread -bs=4k -size=2G -numjobs=64 -runtime=10 -group_reporting -name=file1 > 3--4k-rand-r.log fio -filename=/tmp/test2g -direct=1 -rw=randwrite -bs=4k -size=2G -numjobs=64 -runtime=10 -group_reporting -name=file1 > 4--4k-rand-w.log fio -filename=/tmp/test2g -direct=1 -rw=read -bs=32m -size=2G -numjobs=16 -runtime=10 -group_reporting -name=file1 > 5-32m-seq--r.log fio -filename=/tmp/test2g -direct=1 -rw=write -bs=32m -size=2G -numjobs=16 -runtime=10 -group_reporting -name=file1 > 6-32m-seq--w.log fio -filename=/tmp/test2g -direct=1 -rw=randread -bs=32m -size=2G -numjobs=16 -runtime=10 -group_reporting -name=file1 > 7-32m-rand-r.log fio -filename=/tmp/test2g -direct=1 -rw=randwrite -bs=32m -size=2G -numjobs=16 -runtime=10 -group_reporting -name=file1 > 8-32m-rand-w.log $ grep IOPS * 1--4k-seq--r.log: read: IOPS=15.0k, BW=58.7MiB/s (61.5MB/s)(3521MiB/60018msec) 2--4k-seq--w.log: write: IOPS=15.1k, BW=59.1MiB/s (61.9MB/s)(3546MiB/60017msec) 3--4k-rand-r.log: read: IOPS=145, BW=600KiB/s (614kB/s)(36.2MiB/61714msec) 4--4k-rand-w.log: write: IOPS=296, BW=1201KiB/s (1230kB/s)(71.4MiB/60849msec) 5-32m-seq--r.log: read: IOPS=3, BW=111MiB/s (116MB/s)(6688MiB/60238msec) 6-32m-seq--w.log: write: IOPS=2, BW=71.9MiB/s (75.4MB/s)(4320MiB/60096msec) 7-32m-rand-r.log: read: IOPS=2, BW=79.9MiB/s (83.8MB/s)(4960MiB/62094msec) 8-32m-rand-w.log: write: IOPS=0, BW=11.9MiB/s (12.4MB/s)(736MiB/62051msec)
値が多いが、おそらくカタログのIOPSと比べる対象は4KBランダムリードライトの3,4だと思う。R/Wで145/296とカタログから想定した値の10倍くらいになっている。 スループットは32Mのシーケンシャルなのかランダムなのかわからないけどシーケンシャルだとすれば、R/Wで111/71.9MiB/sとカタログから想定した値の30~40倍くらいか。
例2:ゾーンバランス永続ディスク30GB
カタログ上以下のはず。
同様に計測する。
$ grep IOPS * 1--4k-seq--r.log: read: IOPS=445, BW=1797KiB/s (1840kB/s)(107MiB/60851msec) 2--4k-seq--w.log: write: IOPS=294, BW=1196KiB/s (1224kB/s)(71.1MiB/60853msec) 3--4k-rand-r.log: read: IOPS=295, BW=1197KiB/s (1226kB/s)(71.2MiB/60852msec) 4--4k-rand-w.log: write: IOPS=294, BW=1196KiB/s (1224kB/s)(71.0MiB/60853msec) 5-32m-seq--r.log: read: IOPS=0, BW=16.9MiB/s (17.7MB/s)(1024MiB/60527msec) 6-32m-seq--w.log: write: IOPS=0, BW=15.6MiB/s (16.4MB/s)(960MiB/61391msec) 7-32m-rand-r.log: read: IOPS=0, BW=16.9MiB/s (17.7MB/s)(1024MiB/60515msec) 8-32m-rand-w.log: write: IOPS=0, BW=15.6MiB/s (16.4MB/s)(960MiB/61404msec)
4KBランダムリードライトの3,4をみるとR/Wで295/294とカタログから想定した値の1.5倍くらいになっている。 32Mランダムリードライトのスループットは、R/Wで16.9/15.6MiB/sとカタログから想定した値の2倍くらい。 RWで揃うのは想定どおりだけど、普通の永続ディスクよりもスループットが下回ったのが想定外だった。単にfio実行パラメータが適切ではないからな気もする。
まあ結局よくわからないのでゾーン永続ディスク20GBで試してスコアを見ることにする。
構築
公式のansibleを使ってみる。普通にaptインストールすると古い2.5.1が入ってしまうので以下のようにする。
$ sudo apt update $ sudo apt install software-properties-common $ sudo apt-add-repository --yes --update ppa:ansible/ansible $ sudo apt install -y ansible $ ansible --version ansible 2.9.13 config file = /etc/ansible/ansible.cfg configured module search path = [u'/home/hogehoge/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules'] ansible python module location = /usr/lib/python2.7/dist-packages/ansible executable location = /usr/bin/ansible python version = 2.7.17 (default, Jul 20 2020, 15:37:01) [GCC 7.5.0]
Ansible のインストール — Ansible Documentationより
127.0.0.1宛で1回試してみるが、ssh鍵設定していなかったので怒られる。
git clone https://github.com/isucon/isucon10-qualify.git cd isucon10-qualify/provisioning/ansible vi inventory/hosts (127.0.0.1記載) ansible-playbook allinone.yaml -i inventory/hosts fatal: [127.0.0.1]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: Warning: Permanently added '127.0.0.1' (ECDSA) to the list of known hosts.\r\nno such identity: /home/hogehoge/.ssh/id_rsa: No such file or directory\r\nhogehoge@127.0.0.1: Permission denied (publickey).", "unreachable": true}
鍵追加
touch .ssh/authorized_keys cat isucon10.pub >> .ssh/authorized_keys cat .ssh/authorized_keys chmod 600 .ssh/authorized_keys ls -l .ssh/authorized_keys cp isu10 .ssh/id_rsa chmod 600 .ssh/id_rsa ls .ssh/id_rsa -l #疎通 ssh 34.84.152.xx -i .ssh/id_rsa -l hogehoge
再実行してfailなく完了。 やった後に気づいたけどphpとかrubyのインストールが時間食うので使わないやつは外したほうがよい。
$ ansible-playbook allinone.yaml -i inventory/hosts ... PLAY RECAP ******************************************************************************************************** 127.0.0.1 : ok=76 changed=72 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 Saturday 26 September 2020 22:33:40 +0000 (0:00:05.664) 1:05:45.373 **** =============================================================================== web-rust : Build Web Application Rust ------------------------------------------------------------------- 1215.58s langs : Install PHP -------------------------------------------------------------------------------------- 986.44s langs : Install Ruby v2.7.1 ------------------------------------------------------------------------------ 452.84s langs : Install perl v5.32.0 ----------------------------------------------------------------------------- 399.46s langs : Install python v3.8.5 ---------------------------------------------------------------------------- 256.83s web-perl : Install isuumo.perl Pacakges ------------------------------------------------------------------ 141.91s common : Install Package(Build) --------------------------------------------------------------------------- 74.59s web-bootstrap : Build frontend application ---------------------------------------------------------------- 51.67s web-ruby : Build Web Application ruby --------------------------------------------------------------------- 38.82s web-bootstrap : Install Package(MYSQL) -------------------------------------------------------------------- 34.19s web-bootstrap : Make initial data ------------------------------------------------------------------------- 31.82s web-bootstrap : Install frontend packages ----------------------------------------------------------------- 29.90s bench : Snapshot isucon10 --------------------------------------------------------------------------------- 25.66s web-php : Install isuumo.php Pacakges --------------------------------------------------------------------- 20.89s web-bootstrap : Export frontend application --------------------------------------------------------------- 20.45s langs : Install Rust -------------------------------------------------------------------------------------- 18.64s web-deno : Build Web Application deno --------------------------------------------------------------------- 18.59s web-go : Build Web Application Go ------------------------------------------------------------------------- 14.70s langs : Install Go 1.14.7 --------------------------------------------------------------------------------- 10.38s web-python : Install isuumo.python Pacakges ---------------------------------------------------------------- 9.95s
動作確認
インスタンスの外部IPをブラウザで開いてアプリの動作を確認(本番のような転送は不要)。
isuconユーザに切り替えてベンチ実行。
su isucon #passはisucon cd isuumo/bench $ ./bench --target-url http://localhost 2020/09/26 23:13:24 bench.go:86: === initialize === 2020/09/26 23:13:27 bench.go:98: === verify === 2020/09/26 23:13:28 bench.go:108: === validation === 2020/09/26 23:14:12 load.go:181: 負荷レベルが上昇しました。 2020/09/26 23:14:26 fails.go:105: [client.(*Client).SearchEstatesNazotte] /home/isucon/isuumo/bench/client/webapp.go:367 message("POST /api/estate/nazotte: リクエストに失敗しました") [client.(*Client).Do] /home/isucon/isuumo/bench/client/client.go:136 code(error timeout) *url.Error("Post \"http://localhost/api/estate/nazotte\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)") *http.httpError("context deadline exceeded (Client.Timeout exceeded while awaiting headers)") [CallStack] [client.(*Client).Do] /home/isucon/isuumo/bench/client/client.go:136 [client.(*Client).SearchEstatesNazotte] /home/isucon/isuumo/bench/client/webapp.go:361 [scenario.estateNazotteSearchScenario] /home/isucon/isuumo/bench/scenario/estateNazotteSearchScenario.go:214 [scenario.runEstateNazotteSearchWorker] /home/isucon/isuumo/bench/scenario/load.go:100 [runtime.goexit] /home/isucon/local/go/src/runtime/asm_amd64.s:1373 2020/09/26 23:14:28 bench.go:110: 最終的な負荷レベル: 1 {"pass":true,"score":406,"messages":[{"text":"POST /api/estate/nazotte: リクエストに失敗しました (タイムアウトしました)","count":1}],"reason":"OK","language":"go"}
成功。もう少しベンチを実行してブレを確認。
2020/09/26 23:17:05 bench.go:110: 最終的な負荷レベル: 1 {"pass":true,"score":389,"messages":[{"text":"POST /api/estate/nazotte: リクエストに失敗しました (タイムアウトしました)","count":5}],"reason":"OK","language":"go"} {"pass":true,"score":398,"messages":[{"text":"POST /api/estate/nazotte: リクエストに失敗しました (タイムアウトしました)","count":6}],"reason":"OK","language":"go"} {"pass":true,"score":389,"messages":[{"text":"POST /api/estate/nazotte: リクエストに失敗しました (タイムアウトしました)","count":3}],"reason":"OK","language":"go"}
大体400前後になった。本番の初回実行が456だったので少し低いが、WSL2上に構築して初期で1310になったときよりはまあ近い感じになったかも。 ベンチとアプリを一緒のサーバに入れてしまってる分は性能が落ちていると思われる。ネットワーク的にも影響あるかもしれない。
ISUCON10予選問題をUbuntu18.04@WSL2(Windows 10 Home)で動かすまでのメモ、トラブルシュート集
ISUCON10予選問題をUbuntu18@WSL2(Windows 10 Home)で動かしたときのメモ。末尾にトラブルシュートもまとめた。
環境
大体は2020/09/19の最新バージョン。
- ホストOS側(Windows)
- Windows 10 Home 2004 19041.508
- WSL2
- Docker desktop 2.3.0.5 (48029)
- ゲストOS側(Ubuntu)
- Ubuntu 18.04.5 LTS
- Docker-compose 1.27.3
- Go 1.15.2
ソース
ゴール
WSL2のUbuntu上でdocker-composeでアプリを立ち上げ、ブラウザでWebアプリ画面を確認し、ベンチマーカーでスコアを出す。
手順
基本的にGitHub - isucon/isucon10-qualify: ISUCON10予選の「問題の起動方法」を中心に色々設定を挟む形になっている。
WSL2インストール
WSL2はWindows 10 バージョン2004に含まれる。 Windows 10 バージョン2004の更新配布は段階的に行われているらしく、私のPCではまだ来ていなかった。 ただ、手動インストールは可能で、少し不安はあったがやってみた(結果問題なく動作した)。 大体以下を参考にすればOK。Ubuntuは本番と同じ18.04を選ぶ。
WSL2導入|WinアップデートからWSL2を既定にするまでのスクショ - Qiita
Install Docker Desktop
Windows 10 Home で WSL 2 + Docker を使う - Qiita
docker-composeをインストール
Install Docker Compose | Docker Documentationを参考にインストール。
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.27.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose $ sudo chmod +x /usr/local/bin/docker-compose
再起動しないとパスが通らなかった。PowerShellからシャットダウン(自動再起動する)。
PS> wsl -t Ubuntu-18.04
またコンソールを開く。
$ docker-compose --version docker-compose version 1.27.3, build 4092ae5d
クローン、諸々インストール、パス設定
$ git clone https://github.com/isucon/isucon10-qualify.git $ sudo apt install -y gcc make python3-pip $ pip3 install -r requirements.txt
golangはaptでは入れない。aptだと1.10が入ってしまうが、使用するライブラリwaytが1.13以上を必要とするため、最新版を手動で入れる。
$ wget https://golang.org/dl/go1.15.2.linux-amd64.tar.gz $ sudo tar -xvf go1.15.2.linux-amd64.tar.gz $ sudo mv go /usr/local
wgetが進まない場合、後述の # ホストNWとゲストNWのMTU値が一致していないとダウンロードがタイムアウトすることがある 参照。
Goの環境変数を設定する。.profileにexportを追加する。
$ vi ~/.profile
export GOROOT=/usr/local/go export GOPATH=~ export PATH=$GOROOT/bin:/usr/local/go/bin:$GOPATH/go/bin:$PATH
$ source ~/.profile $ go version go version go1.15.2 linux/amd64
ライブラリインストール。
$ go get github.com/orisano/wayt $ wayt wayt: subcommand is required: Available SubCommands: ...
sudoでgo,waytが実行できるようにsudoパスを設定(makeで必要)
$ sudo visudo
Defaults secure_pathにパスを書き足す。 /home/koのところは自分の設定に合わせる。
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/home/ko/bin:/usr/local/go/bin"
動作確認
$ sudo go version $ sudo wayt wayt: subcommand is required: Available SubCommands: ...
docker-composeのためにPATHに docker-credential-desktop.exeのあるディレクトリを追加し、~/.docker/config.jsonを一度削除しておく(これをしないと認識してくれないことがある)。
echo 'export PATH="$PATH:/mnt/c/Program Files/Docker/Docker/resources/bin:/mnt/c/ProgramData/DockerDesktop/version-bin"' >> ~/.profile tail ~/.profile source ~/.profile rm ~/.docker/config.json
初期データの生成
$ cd isucon10-qualify/initial-data $ sudo make
エラーなく終わればOK。
- Windows側でdocker desktopがrunningになっていること。タスクトレイアイコンから状態が分かる。
- Ubuntu側で3306ポートを使っていないこと。既存のmysqlがあったりする場合停止する。
- ERROR: error pulling image configuration: unexpected EOFが出て止まった場合、とりあえずもう何回か試すとよい。
問題サーバーを立ち上げ
$ cd isucon10-qualify/webapp/ make isuumo/go (そのままログtail状態へ)
アプリをブラウザで確認
Microsoft Storeから起動してもう1つ窓を開く。
IPを確認する。
$ ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1454 inet xxx.xxx.xxx.xxx netmask 255.255.240.0 broadcast 172.yyy.yyy.yyy ...
PowerShellで先程確認したxxx.xxx.xxx.xxxへポートフォワーディング を行う。Connection resetと出ることがあるがその後も転送は続いている。この手順は ISUCON10 予選マニュアル · GitHubによる。
PS C:\WINDOWS\system32> ssh localhost -L localhost:8080:xxx.xxx.xxx.xxx:80 -N kex_exchange_identification: read: Connection reset PS C:\WINDOWS\system32>
ブラウザで http://localhost:8080/ にアクセスし、ISUUMOの画面が見えればOK。
ベンチマークを実行
ビルドして実行し、スコアが出れば完了。
$ cd ~/isucon10-qualify/bench $ sudo make $ ./bench ... 2020/09/20 02:32:04 bench.go:110: 最終的な負荷レベル: 8 {"pass":true,"score":1310,"messages":[{"text":"POST /api/estate/nazotte: リクエストに失敗しました (タイムアウトしました)","count":40}],"reason":"OK","language":"go"}
トラブルシュート
docker desktopが起動していないとdocker-composeがFileNotFoundErrorで終了する
docker desktopを起動してもう一度やってみる。docker desktopはタスクトレイアイコンから状態が分かる。
$ sudo make ... docker-compose -f ../webapp/docker-compose/go.yaml down -v Traceback (most recent call last): File "urllib3/connectionpool.py", line 677, in urlopen File "urllib3/connectionpool.py", line 392, in _make_request File "http/client.py", line 1252, in request File "http/client.py", line 1298, in _send_request File "http/client.py", line 1247, in endheaders File "http/client.py", line 1026, in _send_output File "http/client.py", line 966, in send File "docker/transport/unixconn.py", line 43, in connect FileNotFoundError: [Errno 2] No such file or directory ...
参考: During startup check that docker is running · Issue #774 · jupyterhub/repo2docker · GitHub
docker-composeがdocker.credentials.errors.InitializationErrorで終了する
PATHに docker-credential-desktop.exeのあるディレクトリを追加し、また、それでも上手く行かない場合は~/.docker/config.jsonを一度削除する。
$ sudo make ... Traceback (most recent call last): File "bin/docker-compose", line 3, in <module> File "compose/cli/main.py", line 67, in main File "compose/cli/main.py", line 126, in perform_command File "compose/cli/main.py", line 1070, in up File "compose/cli/main.py", line 1066, in up File "compose/project.py", line 615, in up File "compose/service.py", line 356, in ensure_image_exists File "compose/service.py", line 1267, in pull File "compose/progress_stream.py", line 99, in get_digest_from_pull File "compose/service.py", line 1234, in _do_pull File "docker/api/image.py", line 396, in pull File "docker/auth.py", line 48, in get_config_header File "docker/auth.py", line 324, in resolve_authconfig File "docker/auth.py", line 235, in resolve_authconfig File "docker/auth.py", line 262, in _resolve_authconfig_credstore File "docker/auth.py", line 287, in _get_store_instance File "docker/credentials/store.py", line 25, in __init__ docker.credentials.errors.InitializationError: docker-credential-desktop.exe not installed or not available in PATH [7239] Failed to execute script docker-compose Makefile:22: recipe for target 'verification_data' failed make: *** [verification_data] Error 255
参考: WSL2上のdocker-composeで認証エラー - roy-n-roy メモ `docker-compose up` fails in WSL 2 environment · Issue #7495 · docker/compose · GitHub
ホストNWとゲストNWのMTU値が一致していないとダウンロードがタイムアウトすることがある
ホスト側でPowerShellでMTUを確認。この場合1454。
PS C:\WINDOWS\system32> netsh interface ipv4 show subinterface MTU MediaSenseState 受信バイト 送信バイト インターフェイス ------ --------------- ----------- ---------- ----------------- ... 1454 1 159585932 7359736 ブロードバンド接続 ...
ゲスト側でMTUを確認。元がいくつだったか取りそこねた。ゲスト側も1454に合わせて、何かwgetしてみる。ダウンロードが成功すればOK.
$ ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1xxx ... $ sudo ip link set eth0 mtu 1454 $ ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1454 ... $ wget https://golang.org/dl/go1.15.2.linux-amd64.tar.gz
参考: WSL2 fails to make HTTPS connection if Windows is using VPN · Issue #4698 · microsoft/WSL · GitHub
waytのコマンドが通らない
バイナリが存在するか、PATHにそのフォルダが入っているか、.profileに書いたパスは正確か、.profileを読み込んだか、sudo実行時はsudoにPATH等が継承されているかを確認する。
$ find / -name wayt 2>/dev/null /home/ko/src/github.com/orisano/wayt /home/ko/go/src/github.com/orisano/wayt /home/ko/bin/wayt $ env|grep GO $ cat ~/.profile $ source ~/.profile $ sudo visudo $ wayt $ sudo wayt
go get github.com/orisano/waytが上手く行かない
-u -vをつけてログを出してみる。TLS handshake timeoutしてるようなら上記のMTUのトラブルシュートを試す。
$ go get -u -v github.com/orisano/wayt ... package google.golang.org/grpc: unrecognized import path "google.golang.org/grpc": https fetch: Get "https://google.golang.org/grpc?go-get=1": net/http: TLS handshake timeout ...
../../go/src/github.com/orisano/wayt/http.go:45:14: undefined: http.NewRequestWithContextが出てるようなら使っているgoのバージョンが古いので上げる。
技術書典9でISUCONの初心者向け性能改善プロセス解説本を出しました
技術書典9にて、サークルFratty(@team_fratty)として「Webサービスチューニングコンテスト ISUCONのススメ ~初心者向けに環境構築から 計測・改善まで解説する本~」を出しました。技術書典のページは文字数・画像枚数に制限があるため、本記事で+αの内容を紹介します。以下は本書の表紙です。
基本情報
- タイトル:Webサービスチューニングコンテスト ISUCONのススメ ~初心者向けに環境構築から 計測・改善まで解説する本~
- 出版:Fratty(@team_fratty)
- 媒体:電子書籍(PDF)
- 価格:500円
- 販売場所:技術書典オンラインマーケットより購入可能
- 初出:2020/09/12(技術書典9)
概要
性能改善ができるエンジニアになりたい人へ ISUCONに参加しよう!
ISUCONとは、LINE株式会社が運営窓口となって毎年開催している「お題となるWebサービスを決められたレギュレーションの中で限界まで高速化を図るチューニングバトル」です。数百チームの参加者が一斉に、朝から晩まで、同じWebサービスのチューニングに取り組み、性能の高さを競います。6年間毎年参加し続け、同人誌を書いてしまうくらい楽しいコンテストです!参加者がもっと増えたらと思い、これまであまり見かけなかった、ボトルネックを発見・修正するまでの観察や思考の流れを解説する本を書きました。本書がISUCONをより楽しむきっかけになったり、ISUCONや性能改善がうまくなりたいと思う方の役に立つことを期待しています。
【内容】
本書ではISUCON9予選問題(2019年)を題材にしています。 練習用の環境構築からWebサービスの性能計測、修正とその結果評価までを具体的な手順とともに解説します。 本書を読むことで性能改善のプロセスが身に付き、ISUCONでの動き方が分かります。 コマンドやスニペットはコピペできるようにGitHubで公開しています。
https://github.com/team-fratty/rec4isucon
【想定読者】
- 「Webサービスの性能改善ができるようになりたい」
- 「ISUCONに参加してみたいが、どのように勉強すればよいか分からない」
- 「ISUCONに参加したが、何をすればよいか分からなかった」
という方を想定読者としています。 また、Linux OSの基本的な操作を前提知識としています。
【環境等】
本書の作業手順は次の環境で書かれています。
目次
本文紹介
本書のメインである環境構築、性能改善:計測・修正を抜粋して紹介します。
第3章 環境構築
第3章ではISUCON9予選問題を題材に、GCP上で練習用サーバを構築する方法を解説しています。
第4章 性能改善:計測
第4章:計測の節では、リクエスト単位・処理ブロック単位・SQL単位での計測と、ボトルネックを特定する流れを解説します。
第4章 性能改善:修正
第4章:修正の節では、計測結果からWebサービスの修正内容を導出し、修正→再計測→効果測定を行う性能改善のプロセスを解説します。
以上、ISUCONのススメの紹介でした。
ISUCON10予選参加記録
ISUCON10参加してきました。 結果287位で敗退でした・・・。めっちゃ悔しい。どう考えれば解けていたのか分析して来年リベンジしたい。
ISUCON10 オンライン予選 全てのチームのスコア(参考値) : ISUCON公式Blog
607 Fratty
タイムライン
- 12:20 開始
- プロキシの書き方が上手く行かず、SSH接続に時間を取られる
- とりあえずVSCodeでつなぐことに成功、計測用設定を仕込み始める
- 13:48 練習用に作っていたUbuntuからsshでRLoginでアクセス成功
ssh -L localhost:8080:10.xxx.x.xxx:80 isucon-server3
- 14:11 alpでリクエスト単位の結果初回取得
- 14:19 処理単位、スロークエリ集計初回取得
- とりあえずインデックスを貼る→そんなに変わらず
- 15:32 なぞってのN+1解消を考える→諦める
- ishihrがなぞってのN+1解消に取り掛かるが、レスポンス不正で通らず
- サーバ負荷分散に取り掛かり始める。1,2号機で分散してみるが、ほぼ変わらず→アプリ以外の所ネックか
- DBでリソースサチってるんじゃないかと推測し(NG)、1,2,3号機で3号機をDBのみにし、1,2で分散して3号機に繋がせた。ほぼ変わらず。
- BOTの排除をnginxのルーティングでやる
- レスポンス不正が最後まで治らず、切り戻して最終計測
反省
とりあえずそもそもの力不足は棚に上げると、いくらでもあるが、、、
- アプリ修正にもっとリソースを割くべきだった気がする
- VSCodeのGo拡張機能が動かなかった→練習の時点で発生していたので原因解明しておけばよかった
- アプリ書き換えの準備不足 リクエスト・レスポンスの常時出力とかしておくべきだった
- リソースモニタリングしてない。サーバ負荷分散して効かなかったとき、そこを見るべきだった(推測するな計測せよ)
絶対ISUCON11やってほしい、、、