Masteries

技術的なことや仕事に関することを書いていきます.

Test::mysqldが立ち上げるMySQLのデータをメモリ上に配置して高速化した話

会社で新しく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の遅さが気になっている方は是非試してみてはいかがでしょうか.