📘

M1 Maxで爆速のdocker環境を手に入れる

2021/12/12に公開

はじめに

普段はRailsをメインに開発をしていて、これまではMacbook Air 2018 + VirtualBox を使用していました。
Macbook Pro 2021(M1 Max)を購入し、先人たちの記事を参考にdocker環境を構築してみた所、
思ったよりも速くなかったので、試行錯誤した結果爆速の環境を手に入れました。

環境

Macbook Pro 2021 (M1 Max)

  • CPU: M1 Max(10 core)
  • メモリ: 32GB

Macbook Air 2018 (Intel)

  • CPU: Intel Core i7 1.3GHz クアドコア
  • メモリ: 16GB
  • VirtualBox(vagrantで構築)

検証

solidus

1. lima (M1)

M1 Pro + Lima + Dockerが速い (Rails/RSpec検証)

こちらの記事と同じ環境を構築し、solidusの同じテストを実行した結果、4 minutes 30 seconds とほぼ変わらない(誤差程度)の結果となりました。
シングル性能は同じで、メモリ帯域とストレージの速度はMaxの方が上なのに結果は変わりませんでした。

2. VirtualBox (Intel)

1と同じsolidusを、Macbook AirのVirtualBoxに構築したdockerで実行した結果は
10 minutes 10 secondsでした。

3. multipass

sshfsではストレージのアクセスがボトルネックになるため、VirtualBox環境と同様に
Linux環境に閉じ籠もる作戦に変更することにしました。
Limaはホームディレクトリに .linux が付くのが特殊で、neovimの設定ファイルのパスに問題があるので、multipassを使うことにしました。
rspecの実行時間は3 minutes 34.9 secondsでした。
limaもQEMUを使っているのでlimaのままLinuxに閉じ籠もってもパフォーマンスは変わらないと思います。

検証結果

マシン アーキテクチャ 仮想環境 CPUコア メモリ rspec実行時間
Macbook Pro 2021 M1 Max Intel Lima 4 core 8GB 4 minutes 30 seconds
Macbook Air 2018 Intel VirtualBox 4 core 8GB 10 minutes 10 seconds
Macbook Pro 2021 M1 Max Intel multipass 4 core 8GB 3 minutes 34.9 seconds

自前のrailsプロジェクト

limaをarch: x86_64での稼働も試してみましたが、docker buildやgemのnative extensionのビルドが異常に遅く、実用的ではなかったため構築中に断念しました。
Dockerfile変更し、M1環境に対応させました。
手元にあるsolidusと似た構成のRailsプロジェクトをいくつかM1対応を試みましたが、
結果的にM1に完全対応できたのは現時点では1プロジェクトのみです。
M1に移植する際のポイントについては、別の機会にまとめようと思います。

マシン アーキテクチャ 仮想環境 CPUコア メモリ rspec実行時間
Macbook Air 2018 Intel VirtualBox 4 core 8GB 2 minutes 36.9 seconds
Macbook Pro 2021 M1 Max M1 Max multipass 4 core 8GB 1 minute 2.87 seconds

記録は残っていませんが、Macbook AirのDocker Desktop for MacからVirtualBoxに移行した際、3倍ほど速くなっています。
実用的ではありますが、multipass + Docker が思ったよも速くならなかったので、ここから更にがんばります。

CPU / メモリの割当を増やす

現時点ではmultipassでlaunch後にCPU / メモリの割当を増やす公式な方法はなさそうです。

$ sudo nvim /var/root/Library/Application\ Support/multipassd/qemu/multipassd-vm-instances.json

-smp, -m がそれぞれCPU, メモリに対応しているので8 core, 8192MB(8GB)に変更しました。
その結果、solidus, 自前のrailsプロジェクトともにrspecの実行にかかる時間はほとんど変わりませんでした。

rspecを並列化する

CPUコアの割当を増やしても速くならなかったため、CPUがうまく使われていないと考え、
rspecを並列化することにしました。

Gemfile
+  gem 'parallel_tests'
config/database.yml
--- a/config/database.yml
+++ b/config/database.yml
@@ -26,7 +26,7 @@ development:
 # Do not set this db to the same as development or production.
 test:
   <<: *default
-  database: app_test
+  database: app_test<%= ENV['TEST_ENV_NUMBER'] %>
 
 # As with config/credentials.yml, you never want to store sensitive information,
 # like your database password, in your source code. If your source code is
$ rails parallel:setup
$ rails parallel:spec 

検証結果

rspecを並列化したため、VirtualBox環境でも速くなったため、そちらの結果も合わせて

マシン アーキテクチャ 仮想環境 CPUコア メモリ rspec実行時間
Macbook Air 2018 Intel VirtualBox 4 core 8GB 2 minutes 24 seconds
Macbook Pro 2021 M1 Max M1 Max multipass 8 core 8GB 21.84 seconds

まとめ

multipassどdockerで当初のMacbook Airと比較し、7倍以上速い環境が手に入りました。
メモリの割当や帯域は結果に影響なかったので、
CPUコア数では同スペックのM1 Proでも上記の検証結果とは変わらないパフォーマンスが出ると思います。

Discussion