ayumin.log

読みにくかったら脳内sedで整形してね

サーバチューニングコンテストインフラ担当のAnsible設計書

去年の9月のisucon10予選、今年の2月のN-PTCなどに参加して、ツールの使い方や初動をまとめたくなったので記事を書いていたが、書きながらこの辺をうまいことやるplaybookを書いて、Ansibleで3サーバ同時に叩き込んだ方が良いのでは?と思った。

どういう構成にするか考えながら、大まかな設定を忘れないうちに書いておく。

あとでplaybook書いたら公開する(予定は未定)

サーバの配分について

3人チームなら勿論1人1台。

最近の傾向を見ると、isuconなどでは1チームに3台のサーバが割り振られる。ただし、ベンチを向けられるサーバは1台しかないこともある。

この場合、ベンチサーバは作業が終わってもインフラが持った方がよさそう。(nginxなどのチューニングのため)

前準備

何より先にGit管理。複数人だとGit使えないとコードに触ることもできないので、急いでセットアップする必要がある。

セットアップで必要になるスクリプトの流し込みとkataribeなどのインストールはAnsibleで行い、インストールまでできるようにしておくと楽そう。

まずSSHしてディレクトリ構成を把握、playbookをwebapp/などのディレクトリを対象にできるよう微調整する。 .gitごとwebアプリケーションのディレクトリに全部Ansibleで叩き込む。

このAnsibleのplaybookに入れておくべき処理は以下

  • webapp以下に入れるベンチ前setupスクリプト/ベンチ後summarizeスクリプト
    • どこに入れるかは変数(git_dir)にしておき、当日サーバにSSHしてから変数にパスを入れる
    • setup/summarizeについては自作する
  • Nginx/Apacheの設定ファイルをwebapp以下に持ってくる
    • ↑↑の変数のディレクトリ(git対象リポジトリ)にコピーしてくる
      • 普通にコピーするとsu権限になるので、その辺もAnsibleでちゃんとやる
      • 必要な変数はgit対象リポジトリ↑↑↑(git_dir)と設定ファイルのあるディレクトリ(original_conf_dir)
  • kataribe, pprofなどのインストール
    • 主にgo get -u が必要になるもの
  • (mysql8などのインストール)
    • これは状況によるが、以前mysql8へのアップデートが効くことがあったので、一応入れておくと良いかも

nginx,Apacheの設定ファイルの場所は決め打ちしない方が良い(ミスるとgit管理が面倒になるため)

Nginxなら

$ sudo ls /etc/nginx

Apacheなら

$ sudo ls /etc/apache 
$ sudo ls /etc/apache2

あたりにあるので要チェック。このファイルを基準にAnsibleでgit対象ディレクトリに持ってきて、ベンチ前に使用するsetupスクリプトapacheなどの設定ファイルをコピーする処理を入れたい。

3台にとりあえず最低限必要ファイルを叩き込めたら、メインとなるサーバで作業する。

git監視対象の設定

ここからはサーバにSSHして直接ファイルに触る。

まずはgitの設定。
このタイミングで大きなファイル等がgitに入ると時間がかかって面倒なので、gitで共有するファイルは

  • apache/nginxの設定ファイル
  • 初期設置スクリプト
  • アプリケーションのコード部分のみ

に絞った方が良い。後から必要なファイルがでてきたら、適宜.gitignoreから除外する。
下手に広範囲にgitの監視対象にすると、ミスったときに大変になる。

ここで.gitignoreを作ったらすぐpush -fして、チームの人に他2台にpullしてもらう。

kataribe

Apache, NginxなどのWebアプリケーションサーバのログをいい感じに整形してくれるツール。

github.com

過去2回とも使用している。
ほぼ必須レベルのツールで、これがあればWeb APIエンドポイントの呼び出し時間、回数などの情報が可視化できる。

使い方は以下であるが、セットアップまではAnsibleで行えそう。

$ go get -u github.com/matsuu/kataribe
$ ${GOPATH}/bin/kataribe -generate 
#GOPATHは普通は/home/${username}/go にある。go env GOPATHで表示可
$ cat <logFile> | ${GOPATH}/bin/kataribe 
# 整形されて呼び出し回数やかかった時間などでランキング形式になった結果が出てくる

kataribeの注意点としてkataribe -generateで出来たkataribe.tomlの中にLogFormatの例がある。

それをApacheやNginxなど、それぞれ使用するアプリケーションサーバのログフォーマットにする必要があるため、この時点でapacheなどのconfigファイルはgit管理しておきたい。

他にはkataribe側の設定を必要とすることはあまりない。

ここで得た結果を見て、○○のAPIが重そうだ→何が原因なんだろう?という流れで検証する。

kataribeのメリットは基本的にどの言語、競技にも対応できること。

NginxとApacheは大体どっちか使われるし、実装言語に依存しないツールなので、ここまでは完全なルーチンワークにして良い。

自分はここで吐き出されたログファイルを、Goで作った自家製ツールでDiscordに飛ばすことが多い。 そのためにsummarizeスクリプトが必要になる。

pprof

Goのプロファイリングツール。Go以外の実装には使えない。
このツールの便利さは、コードの何行目にどの程度かかってるかまで可視化できるところにある。

kataribeは「このエンドポイントが遅い」までしか分からないが、pprofは「○○行が遅い」あたりまで出力してくれる。

じゃあpprofだけでいいじゃんと思うかもしれないが、画像配信などが原因になっていることもあるので、切り分けのためにkataribeは必要。

使い方はここで書くより参考になる資料があるので、リンクをおいておく。

インストールに

$ go get -u github.com/google/pprof

が必要だが、Ansibleにまとめられる。

使い方は以下が参考になる。

medium.com

pprofは使うのにmain関数に一文追加する必要があるので、ブランチを切って行いたい。

またここで絶対ベンチが必要になる。(計測のため)

pprofを動かしてベンチを取っている最中に、pprofを適用したブランチからのプルリクを送り即マージ。他の人にpullしてもらう。

pt-query-digest

スロークエリの集計。aptリポジトリを追加してapt installでインストールできる。

これもAnsibleでインストールまでは行きたいが、aptリポジトリの追加がAnsibleでできるかが未確認なので、手打ちが必要になる可能性がある。

www.percona.com

に乗っているので、後で読む(実はまだちゃんと使ったことがない)

その他

この辺でDBスキーマを把握しておきたい。

initとかの初期化ファイル関係にパスワードが入ってるか、コードの中に埋め込まれていることが多い。

おそらくテーブルはそんなに多くない(2-8程度)なので、全部

show full columns from <table名>;

とかで取得して、スクショなどで共有する。

アプリ担当にこの辺りまで任せられると少し楽かも。

top, dstat, iotopとかでioやcpuの挙動も見ながら、適宜どこを修正すべきかを伝えていくことがインフラの仕事な気がする。

まとめ

ここまでのツールがあればgit管理、エンドポイントの処理時間、プログラムの重そうな部分の把握、SQLのスロークエリの分析ができる。

ここまで行えば、パフォーマンスチューニングに必要な計測は全て行えるので、アプリ側に集中できる。

できれば開始1時間で計測関係のセットアップは片付けたい。