2019-09-07 (Sat) [長年日記]
_ ISUCON9予選参加
社内Slackで原君が「ISUCON9の登録が8/25までなんですが興味ある人います?」と言っていたので手を上げたらISUCON初参加することになった。当初は原君、橋本君と三人で出る予定だったが、橋本君が出られなくなってしまったので代りに佐田君に参加してもらった。
チーム名: yarunee
リポジトリ: https://github.com/shugo/isucon9
以下、だいたい時系列にメモ。
- 10:10くらいに会社に着いたものの、誰もいないので帰ろうかなと思ったが、会議室にいた(集合場所はちゃんと決めましょう)。
- とりあえずコーヒーを多めに淹れてポットに用意。
- /home/isucon/isucari/webappをGitHubに上げようとしたが、画像ファイルが多いのでrubyの部分だけGitHubに上げた。
- 何か自分だけ会議室の無線LANの速度が出ないので、LANケーブルを探してきて有線LANに変更。
- 佐田君がインデックスを作成。
- 原君がproductionモードへの変更やログの設定。
- 過去のISUCON情報をぐぐって alp というツールで
alp -r --sum --aggregates='/users/[0-9]+\.json,/items/[0-9]+\.json,/transactions/[0-9a-f]+\.png,/upload/[0-9a-f]+\.jpg' -f /var/log/nginx/access.log
とかして/users/transactions.jsonの実行時間合計が長いことを特定。 - かつふじのチキンカツ定食・親子丼をおごった。
- MySQLのスロークエリをログに出すようにしたが、0.5秒以上のクエリは3つほどしか出ず/users/transactions.jsonとは関係なさげ。
- items.created_atのインデックスを追加。
- /users/transactions.jsonのsellerをJOINするようにしたがあまりスコアは上がらず。
- categoriesが40件くらいしかない&get_category_by_idが再帰的にSELECTしていて遅そうだったので、JOINするのではなくメモリにキャッシュするよう修正。
- 冷蔵庫にあったアイス(お中元だったらしい)を振る舞った。
- buyerもJOINするよう修正。
buyey
というRuby版のtypoを運営に報告。ベンチマーク通ってたのでこの部分削っても動くんだろうけど、コンテストの趣旨に反する気がするのでtypo修正。- STDERR.putsでプロセスID、スレッドID、処理開始からの経過秒数をsyslogに出力して、外部API呼び出しがボトルネックと特定。
- 外部API呼び出しの結果をレスポンスに含めているので、非同期化してスループットを上げるのはかなり構成変えないと難しそうで悩む。
- api_client.shipment_statusがdoneを返すケースが多そうなことをログで確認。
- transaction_evidences.statusがdoneの場合はAPI呼び出しを省略してdoneを返せばいいのではないかという仮説を立て、原君にドキュメントで状態遷移を確認してもらった上で実装。ベンチマークも通った。
- 佐田君がMySQLの何かのパラメータをチューニング。
- この時点でまだアプリケーションサーバのスケールアウトに成功しておらず、諦めてDBサーバだけ別インスタンスにするよう方針変更。
- 例外が握りつぶされてdb errorとだけ表示されていたりしたので、例外の内容やバックトレースをログに出すように原君に修正してもらった。
- しかし、17:45くらいになってもまだ上手く行かないので諦めムードの中、原君がnginxの設定ミス(スケールアウトの設定が残っていた)に気付いて修正。
- 一応ロードバランサーも別インスタンスにして(効果はなかった)、pumaのプロセス数を調整(IO待ちが多そうなのでスレッド数も調整すればよかったと後で気付いたが、そもそもちゃんとスレッドセーフになってたのか?)。
- 終了時刻が16:10に変更されてロスタイムがあることに気付いたのでインスタンス再起動を試すも、ベンチマークは間に合わず。
構成変更は原君と佐田君ががんばってくれていたが、ファイルアップロードとかもあったので特定URLはスケールアウト対象から除外するようにしたのに商品数の不一致でベンチマークが最後まで通らなかったのは謎。このあたり自分はあまり把握してないので原君が書いてくれるはず。
結局たいしたことはできなかった気がしたが、ぎりぎり予選通過することができた。 なぜか本戦は上位3チームだけだと勘違いしていたので予選通過できると思っていなかったけど、東京まで行かないといけないらしい。どうしよう。
2019-09-26 (Thu) [長年日記]
_ オイル交換
出社前にFUNTIMEに寄ってオイル交換してもらった。店に着いたら店長が納車から帰ったばかりのようだったので、もう少し早かったら危なかった。
スクーターやアメリカンはお断りなはずなのに預かり車両で置いてあるのはスクーター・アメリカンばかり……。
Side BではZZ-02を入れてもらったと話したら、同じ粘度・金額でもっといいオイルを使ったブレンドがあるという怪しい言葉(FUNTIMEもNUTECなので大丈夫なはず)に乗ってみた。
オイル換えて調子もいいのでどこか遠くに行きたい。
走行距離: 15282km
2019-09-28 (Sat) [長年日記]
_ iTerm2でCommandをメタキーとして使う
諸事情で最近中古のMacBook Proを入手したが、ターミナルのメタキーがOptionキーになっていて、TextbrinerなどでEmacsキーバインドが使いづらいのでiTerm2とKarabiner-Elementsの設定をした。
iTerm2の設定
- [Preferneces]->[Profiles]->[Keys]でLeft OptionをEsc+にする。
- [Preferences]->[Keys]->[Remap Modifiers]でLeft OptionをLeft Commandに、Left CommandをLeft Optionに変更する。
これでCommandをメタキーとして使えるが、このままだとiTerm2の時だけOption-TABで切り替えしないといけなくてつらい。
Karabiner-Elements2の設定
- 以下のファイルを~/.config/karabiner/assets/complex_modifications/iterm2.jsonに保存する。
{
"title": "iTerm2 rules",
"rules": [
{
"description": "Command-TAB to Option-TAB on iTerm2",
"manipulators": [
{
"type": "basic",
"from": {
"key_code": "tab",
"modifiers": {
"mandatory": ["left_command"]
}
},
"to": [
{
"key_code": "tab",
"modifiers": ["left_option"]
}
],
"conditions": [
{
"type": "frontmost_application_if",
"bundle_identifiers": [
"^com\\.googlecode\\.iterm2"
]
}
]
}
]
},
{
"description": "Command-SPC to Option-SPC on iTerm2",
"manipulators": [
{
"type": "basic",
"from": {
"key_code": "spacebar",
"modifiers": {
"mandatory": ["left_command"]
}
},
"to": [
{
"key_code": "spacebar",
"modifiers": ["left_option"]
}
],
"conditions": [
{
"type": "frontmost_application_if",
"bundle_identifiers": [
"^com\\.googlecode\\.iterm2"
]
}
]
}
]
}
]
}
- [Complex modifications]->[Add rule]で[Command-TAB to Option-TAB on iTerm2]を追加する(自分はCommand-SPCを入力ソースの切り替えに割り当てているので、Command-SPCの方も追加しているがお好みで)。
2019/9/30追記
以下の記事を参考にしたらKarabiner-Elementsを使わなくてもiTerm2の設定だけでできた。
_ shugo [今思えば、単一リクエストの処理中に外部API呼び出しを複数回やってるのをThreadで雑に並列化するだけでもスコア上..]