Hatena::ブログ(Diary)

Dマイナー志向 このページをアンテナに追加 RSSフィード

2016-10-30

ISUCON6本選で名誉運営としてお手伝いしてきました

この話を頂いた時は正直「名誉運営とは」と思ったのですが、本選に進むつもりで予定も開けてたしと二つ返事で引き受けることにしました。

本選運営のお手伝いとしてやったことは以下のとおり。

  • Azure関連
  • CIの構築
  • Python実装
  • 自分の知見に基づくアドバイスなど

Azure関連

Azureの特性を踏まえた上での構成検討やワンクリックデプロイのためのテンプレート作成などを行いました。

予選ではデプロイの仕組みにcustomData使われていましたが、customDataは実行スクリプトをbase64に変換する必要があり、変更のたびに手間がかかるので、カスタムスクリプト拡張機能を用いてデプロイすることにしました。

customDataはUbuntuなど一部のLinuxでしか動作しないため、カスタムスクリプト拡張を利用するのがオススメです。

また、せっかくだからAzureのサービスを有効活用しようとの流れから、AzureのLog Analyticsを用いて競技者の各サーバにメトリックス情報を収集する拡張機能もインストールするようにしました。

そうそれそれ。でも実は私のミスでOMS側がうまく動かなかったんですけどね…。

CIの構築

本選の準備はGitHubのプライベートリポジトリで進めていたのですが、Azureのワンクリックデプロイを実現するためには公開領域にテンプレートを置く必要があることと、デプロイ用のファイル一式を固めたファイルを生成する必要があったため、CI環境を作成しました。

CIサービスはプライベートリポジトリでも無料で使えるWerckerを採用しました。

また、今回の本選はDocker環境だったのですが、Dockerのビルドおよび動作テストを行うために別途Jenkinsサーバも用意しました。DockerのテストにWerckerを使用しなかったのは、現状Dockerのビルド環境としてWerckerは使えないためです*1

Python実装

本選のPython実装は私が担当させていただきました。

私が本職プログラマーだった頃は主にPerl/PHPを生業としており、インフラエンジニアな今はちょっとしたツール作成にPythonを書くことが多いもののPythonでWebアプリケーションを実装した経験はほぼゼロ。とても不安でしたがなんとか実装することができました。

当初はTwistedベースの実装を依頼されたのですが、着手してみたところ自分の力量では無理だと判断し、Flaskで実装しなおしています。

また、Python3+Gunicorn(sync)だとServer Side Eventsの実装でyield周りがうまく動かず、ギリギリになって急遽Python2+Gunicornに置き換えたりしました。

残念ながらPythonで予選を通過したチームはいなかったようなので誰からも試されていない可能性があります。もし良かったらPython実装で問題を解いてみてくださいね。

自分の知見に基づくアドバイス

その他、自分の知見に基づいたアドバイスをいくつかさせていただきました。

途中からの運営参加で色々と口を挟むと快く思わない人もいるかもしれないと思い、あまり出しゃばらないように心がけてました。

でも結果として出しゃばってましたね。ごめんなさいごめんなさい。

いやぁ運営ってこんなに大変だったんですね

f:id:tmatsuu:20161030223528j:image:medium:right

私はただのお手伝い要員でしたが、それでも結構大変でした。ISUCON運営ってこんなに大変だったんですね。

ただのお手伝いでこれだけ大変なのに、メインの運営の皆様がどれだけ大変かは想像もつきません。

皆さん運営の方々に感謝しましょう。ありがとうありがとう。🙏

*1:できなくはない。QiitaにWerckerでDockerビルドをやる記事あります

2016-09-18

ISUCON6予選で敗退しましたがAzureに詳しくなれました

AppArmor Goとして @netmarkjp, @ishikawa84g, @matsuu で参戦しましたが残念ながら去年に続き予選敗退(推定)となりました。最終スコアは24000ぐらいです。

序盤

  • デプロイが終わって何も変更していない状態(デフォルトのperl実装)でベンチマーク回す
    • →スコア0
  • Go言語に切り替えてベンチマーク回す
    • →スコア0
  • MySQLに適切なインデックス追加、htmlifyの正規表現生成を切り出してentryの追加/削除があるまで正規表現をキャッシュして使いまわす
    • →スコア0

えーこれでもダメかーと思いつつ昼食で気分転換。

中盤

昼食で思いつきました。

  • 初期状態でentryごとにマッチするキーワードを予め抽出してキャッシュし、entryの追加/削除があるごとにentryごとのキーワードキャッシュをいい感じに調整することで正規表現生成のコストを下げようとする
    • →キーワード一覧を生成したものの、Goでregexp.Regexpの生成があまりに遅く事前キャッシュが全然終わらない
  • Goのregexp.Regexpの利用を諦めてPCRE実装を試みようとする
    • →実現可能性を疑ってしまいあまり手が進まない
  • このあたりから右往左往

ヤバイヤバイとこのあたりで少し焦り始める。

終盤

この時点で16:30、未だスコア0のまま。

  • Goを一旦諦めPerlに切り替え、htmlifyの正規表現生成をキャッシュするところまで実装
    • →スコア10000ちょいを記録。まじかよF***。Goつらい。
  • ようやくスタートラインだ、Perlでボトルネックを調べて潰していこう
    • 久々のPerlですっかりDevel::NYTProfの使い方を忘れてしまっており、ボトルネックをきちんと把握できないままの悪戦苦闘

最後にスコア24000ぐらいを記録してフィニッシュでした。つらい。

反省会

Goで正規表現のCompileが遅いのは事前に把握していたのですが、それをどうにかする方法が思いつかず惨敗でした。またGoを諦める判断も遅かったしGo以外も勉強しておけばよかった。複数の言語に対応できるようにしておくことは大事ですね。

あとで聞いた話によるとgolangであればstrings.Replacer が使えるらしいです。なるほどー。しかし自分の知識とググラビリティではその情報にたどり着くことはできなかったでしょう。南無。

まとめ

予習のおかげでAzureに随分詳しくなれました。今後の仕事に大いに役立ちそうな気がします。

ISUCONでは負けましたが、大きな戦果を得ることができました。ありがとう運営さんありがとうISUCON!

ISUCON6予選の過去問Vagrantも作り始めてます。乞うご期待。

2016-09-09

ISUCONの練習に使える環境を各種ご用意しております

前回の記事もISUCONネタだったmatsuuです。ISUCONのことしか書いてないがな。

ISUCONで良いスコアを叩き出すためには過去問を解くことが大事と1年前にも書かせて頂きましたが、今回も様々な環境で過去問にチャレンジできるようにしました。どうぞご査収ください。

Microsoft Azure

今回のISUCON6はMicrosoft Azure上で行われるということで、Azure用テンプレートを用意しました。クリックするだけでAzure環境にデプロイが可能です。

https://github.com/matsuu/azure-isucon-templates

ISUCON5予選とPixivさんの社内ISUCONをデプロイするテンプレートを用意しております。

内部的には真っさらなOS上でAnsibleによるプロビジョニングを行っているため構築に1時間弱かかりますのでご了承下さい。

今回初めてテンプレートを作ったので抜け漏れがあるかもしれません。問題があれば随時ご指摘ください。

Vagrant

前回のVagrant環境も更新しました。

https://github.com/matsuu/vagrant-isucon

https://github.com/matsuu/vagrant-pixiv-isucon2016

vagrant upを実行すればAnsibleによるプロビジョニングが始まります。boxの配布までは行っておりません。ごめんなさい。

Ansible

同様にAnsible環境も更新しています。

https://github.com/matsuu/ansible-isucon

Pixivさんの社内ISUCONは公式リポジトリのAnsibleをご利用ください。

Terraform

過去問の本家AMIなどを起動するためのTerraformも用意しています。

https://github.com/matsuu/terraform-isucon

https://github.com/matsuu/terraform-pixiv-isucon2016

移植版も含まれてます。移植版はプロビジョニングにAnsibleが使われるので構築に時間がかかります。ご注意ください。

Docker

今回テスト的にDocker環境も用意してみました。

https://github.com/matsuu/docker-isucon

とりあえず作りやすそうなISUCON4予選で作ってみましたが、AnsibleからDockerfileへの書き換えでかなり疲弊したためもう作りたくありません。

Docker HubでAUTOBUILDを回しているのでdockerコマンドでダウンロード可能です。各言語ごとのdocker-compose.ymlも用意しています。

まとめ

環境構築ばかりやっていて過去問を解く時間がないです。何やってんだ。

みなさんのお役に立てば幸いです。

2015-09-27

ISUCON5で予選敗退しましたがアクセスログ解析ツールkataribeは充実しました

「チームSELinuxはEnforcing」としてishikawa84g、matsuu、netmarkjpの3人でISUCON5に参加したものの、スコアが伸びず予選敗退となりました。

最終スコアは3886。構成はVarnish+Python+MySQLでした。

ちなみにUbuntuだったためSELinuxはインストールしておらずEnforcingにしてません。すみません。でもAppArmorは有効にしたままだよ!

当初はGo言語で実装する予定だったものの、運営からGo言語の実装にはバグがあるとの事前通知があったため、バグ解消に時間をとられるのを嫌ってPythonを選択しました。しかしPythonの知見が乏しくツラい感じでした。選択ミスった…。

やったことはMySQLのチューニング、nginx→Varnishの差し替え、SQLのチューニングなどです。

VarnishにしたのはESIで部分キャッシュを実装するためでしたが、結局部分キャッシュを実装するところまで至りませんでした。

そのあたりもあって焦りが先に来てしまいなかなかスコアを伸ばせず撃沈となりました。

アクセスログ解析ツールkataribeについて

ISUCON5の事前準備として、前回のISUCON4参加時で作ったアクセスログ解析ツールkataribeを充実させました。

元々はgoのソースコードを直接書き換えて都度go buildする仕様でしたが、TOML形式の設定ファイルでカスタマイズできるようにしました。いくつかのチームは実際にISUCON5予選で使って頂いたようで、私として嬉しい限りです。俺の屍を越えてゆけ的な。

kataribeの特徴は、正規表現で複数のリクエストを束ねられることです。

例えばISUCON5予選では、以下のように設定しました。

(一部省略)
[bundles]
  [bundles.get_profile]
  name = "GET /profile/*"
  regexp = '^GET /profile/.*'
  [bundles.post_profile]
  name = "POST /profile/*"
  regexp = '^POST /profile/.*'
  [bundles.diary_entries]
  name = "GET /diary/entries/*"
  regexp = '^GET /diary/entries/.*'
  [bundles.diary_entry]
  name = "GET /diary/entry/*"
  regexp = '^GET /diary/entry/.*'
  [bundles.post_diary_comment]
  name = "POST /diary/comment/*"
  regexp = '^POST /diary/comment/.*'
  [bundles.post_friends]
  name = "POST /friends/*"
  regexp = '^POST /friends/.*'
  [bundles.css]
  name = "GET /css/*"
  regexp = '^GET /css/.*'
  [bundles.fonts]
  name = "GET /fonts/*"
  regexp = '^GET /fonts/.*'
  [bundles.js]
  name = "GET /js/*"
  regexp = '^GET /js/.*'

すると以下のような出力が得られます。

便利!

まだまだ至らない部分もあるツールですが、今後も徐々に改善していこうと思います。まる。

2015-08-30

ISUCON過去問で予選通過のスコアを再現できるようにした

今年のISUCONは「チームSELinuxはEnforcing」で参加するmatsuuです。

前回のエントリーでISUCON過去問を再現できるようにしましたが、予選時と異なるスペックでどこまでスコアを上げればいいのかわからないという問題がありました。

そこで、ほぼ予選通過のスコアを再現できるVagrantとAnsibleを用意しました。

現在はISUCON4予選のみ用意してます。ISUCON3予選は…まぁそのうち。

使い方

vagrant-isucon-passからVagrantfileをダウンロードしてvagrant upでokです。

既にvagrant-isucon(ansible-isucon)で構築したサーバがある場合は、サーバ内で以下の手順を踏むことでも構築できます。

git clone https://github.com/matsuu/ansible-isucon-pass.git
cd ansible-isucon-pass/isucon4-qualifier
ansible-playbook -i local playbook.yml

ベンチマーク

これを使って手元の環境でスコアを測ってみました。

環境初期スコアチューニング後備考
AWS m3.xlarge(vCPU 4個、メモリー15GB)124738862予選時のスペック
Macbook12inch+VirtualBox(メモリー2GB)63214850

ちなみにISUCON4の予選通過スコアは37808、私のチームのスコアは45742でした。当日のスコア一覧はこちら

まとめ

CPUスペックやメモリ容量が異なり、ボトルネックになる箇所が本来と異なる可能性があるため*1、このスコアもあくまで参考程度にしかなりませんが、ひとつの目安として使えるのではないかと思います。

何をチューニングしてるかはansible-isucon-passを覗けばわかりますが、まずは中身を見ずに自力でこのスコアを目指してみるのがいいと思います。Let's enjoy!

*1:一応できるだけメモリを節約しながらスコアを上げてみました