会社で新しくMac miniを支給してもらったのですが, ストレージがHDDだったので, ディスクの読み書きを繰り返す処理, 例えばTest::mysqldを使ったWebアプリのテストが非常に遅くなってしまいました. この原因は, HDDに対するデータの読み書きが遅いという所なので, データを読み書きする先をHDDからメモリに変えることで, 高速化が期待できます.
というわけで, Mac OS X上でメモリから仮想ディスクを作ってマウントし, Test::mysqldで立ち上げるMySQLのデータをメモリ上に配置するようにした上で, テストを回すというところまでを試してみたので, その方法をまとめておきます.
参考ページ
この記事を書くにあたっては, 以下のページを参考にさせて頂きました. ありがとうございました.
メモリのマウント
Linuxでは, tmpfs
というファイルシステムがあり, これを使えば簡単にメモリをファイルシステムとしてマウントすることが出来ますが, Macにはありません.
参考ページによると, hdid
というコマンドを使えば, 同等のことが実現出来るようです.
$ hdid -nomount ram://128000
/dev/disk2
$ newfs_hfs /dev/disk2
Initialized /dev/rdisk2 as a 63 MB HFS Plus volume
$ mkdir /tmp/mem
$ mount -t hfs /dev/disk2 /tmp/mem
まず最初に, hdid
コマンドでメモリの一部領域を使って仮想的なディスクを作ります.
128000
というのは仮想ディスクに割り当てるセクタ数で, 1セクタ512バイトなのでこの場合約63MBになります.
割り当てるセクタ数が少なすぎると, Test::mysqldでMySQLを立ち上げた時に容量不足でテストが動かなかったりしますので, この辺りの数字は必要に応じて変えると良いでしょう.
次にnewfs_hfs
コマンドで作成した仮想ディスクをHFSで初期化し, 最後にmount
コマンドで/tmp/mem
にマウントしています.
マウントの解除
$ hdiutil detach /dev/disk2
"disk2" unmounted.
"disk2" ejected.
hdiutil
コマンドで, メモリ上に作成した仮想ディスクを破棄すればOKです.
Test::mysqldで建てたMySQLのデータをメモリ上に配置する
Test::mysqldは, MySQLを立ち上げる際にそのデータを格納しているディレクトリをFile::Tempを使って作成しています.
なので, File::Tempが生成するテンポラリディレクトリを, 先ほど作成した/tmp/mem
に生成するようにすれば, Test::mysqldが立ち上げるMySQLのデータはメモリ上に展開されることになります.
File::Tempは, TMPDIR
という環境変数でテンポラリディレクトリの生成先を指定出来るので, 例えばApp::Prove::Plugin::MySQLPoolを使っている場合,
TMPDIR=/tmp/mem prove t
のようにテストを実行すれば, App::Prove::Plugin::MySQLPoolがTest::mysqldを使って立ち上げるMySQLは, ハードディスクではなくメモリ上にデータを配置するようになります.
まとめ
ストレージがSSDではなくHDDのマシンの場合, このようにしてテスト用のMySQLのデータをメモリ上に配置することにより, データの読み書きの時間を大幅に短縮することができます. また, Mac Book AirのようなSSDマシンの場合, テスト実行時にSSDを使わないようになるので, SSDの寿命を削らずに済む, という利点があります.
ストレージにHDDを使っていて, Test::mysqldやApp::Prove::Plugin::MySQLPoolの遅さが気になっている方は是非試してみてはいかがでしょうか.