読者です 読者をやめる 読者になる 読者になる

Vagrantプロバイダの共有フォルダ性能比較

Vagrant を使って仮想環境で開発するさい、共有フォルダ (Vagrantfile の synced_folder 設定) が仮想マシンの通常のフォルダに比べてものすごく遅いという問題があります。そこで、現実的な PHP のアプリケーション (実際に運用しているWebサイト) を使って、実際に共有フォルダの影響がどのくらいあるかという調査をしてみました。

編集したソースコードの同期を簡単にするには、やはり共有フォルダを使うのが一般的でしょう。変更するたびに手動でファイル転送する方法だと、面倒なうえ同期ズレが心配です。ですが、PHP はリクエストのたびにソースファイルをスキャンします。つまり、十分に速いファイルシステムにソースが置かれていないと、毎回その I/O のペナルティを受けることになります。

(他の言語ラインタイムだと、いちどメモリ上にコードが乗ってしまうと、以後プログラムをロードするためにファイルシステムにアクセスする必要はほとんどありません。この話はあくまで PHP でとくに影響が強いという話です)

自分は、とくに意識しなくても共有フォルダが速い Parallels プロバイダを使っていたのですが、Parallels は 11 以降、年間サブスクリプションで購入する Pro バージョン以上でないと、Vagrant を使えない仕様になってしまいました。他の人にも買ってもらえば済むという簡単な話では済まなくなったので、仮想化環境を再検討しようと思い、VirtualBoxVMware を、NFS を併用した場合も含めて比較してみました。

構成

  • CPU x2
  • メモリ 1.5GB
  • ランタイム = PHP 7.0
  • Web = Nginx 1.10 + php-fpm
  • DB = MySQL 5.6
  • キャッシュ = Redis 3.2

Web フレームワークは Yii 2.0 です。本来どのあたりの性能かというのはこちらを参考に: GitHub - kenjis/php-framework-benchmark: PHP Framework Benchmark

MySQL との I/O が重くなるビューは、HTMLの部分レンダリング結果を Redis にキャッシュしています。とはいえ、MySQL にはそこそこ (8 〜 20 クエリ/ページ) アクセスがあります。MySQL のストレージは VM の中にあります。他に、水平分散したとき Web サーバー間で共有すべきデータは Redis にあります。が、ログ等の挙動に影響しないデータのは一部共有フォルダに書き込んでいます。

結果

f:id:tanakahisateru:20170313135727p:plain

  • Front Page = おすすめコンテンツ系のリンクありのトップ
  • Nginx Single File = どのページでも参照しているCSS
  • Privacy Policy / Contact (SSL) = あまり I/O のないページ、SSLの有無で比較するため
  • Contents List = 主だったコンテンツの一覧、Pagination でスクロール
  • Contents Detail = とても複雑なコンテンツ詳細、キャッシュががんばってる

f:id:tanakahisateru:20170313142738p:plain

f:id:tanakahisateru:20170313142809p:plain

wrk で計測。単位は秒間レスポンス数です。静的ファイル配信だけは桁が違うので別のグラフにしました。

完全に予想外だったのが VMware のデフォルト共有フォルダです。基本性能 Parallels と遜色ない商用VMと思いきや、素の共有フォルダの性能は VirtualBox より遅くなりました。Nginx に CSS を要求して秒間30しか出ません。とんでもない遅さですね。

この結果、共有フォルダを NFS にしているかどうかが支配的だということがわかりました。ParallelsNFS を使うかどうかに関係なく同程度の性能が出ているので、はじめから Mac OSAPI を使わずに、NFS 相当のことをしているのだというふうに推測できます。

NFS を使ったパターンの中で比べると、やはり VirtualBox はやや劣ります。が、誰でも無償で使えるものという汎用性で考えると、十分な性能になっていると思います。あまり CPU を使わない Nginx の静的ファイル配信では大きく差を空けられていますが、HTMLページのレスポンスを考えれば、秒間1000もいらないですしね。

結論

というわけで、Mac の PHPer が求めていたのは有料製品ならではの VM チューニング、ではなく、単に共有フォルダの NFS 化だったというお話でした。

NFS - Synced Folders - Vagrant by HashiCorp

Vagrantのshare folderが遅い時はNFSを使うといいです - Qiita

とはいえ、MS 系ブラウザでもフロントエンドのテストをすることは多々あるでしょうし、MacWindows をストレスなく動かせるものは準備しておくのが良いでしょう。やりたい人は、それと同じ製品でサーバーの仮想化までやってしまってもいいかもしれませんが、それはオプションと考えておくのが無難です。

Mac で開発する PHPer のパターン、こんな感じに落ち着くでしょうか。

まあ、PHP 以外の、秒間1000レスポンスの世界であれば、商用VMの性能影響が大きくなるので、また違った指針になるかもしれませんが。