lvm cache を作ってみよう
ssd 買ったけど容量持て余しました。大きい容量はNAS/HDDに突っ込んでるし。バックアップはGoogle Drive(Gsuite 無限)にあるし、普段遣いのファイルはNextCloud に置いていて20GB程度だし。SSDがだいぶ余った。
lvm-cache でSSDをキャッシュ化する。
dm-cache と呼ばれるやつですね。
似た機能にbache などがありますが、今回設定していくのは lvm のみで完結するSSDキャッシュです。
前提条件
SSDとHDDが同じVGに入っていること。
もし違うVG間でVGの境界を超えてキャッシュを作ろうとすると
lvconvert cache not same vg
とエラーになる。
インストールは不要です。lvm は殆どの場合最初から用意されています。
HDDとSSDを同じVGに入れる。
HDDとSSDを同じVGに突っ込んで単純なスパニングの容量拡張をする。
sudo pvcreate /dev/hdd #HDD sudo pvcreate /dev/ssd # SSD ## vg にする sudo vgextend data /dev/hdd sudo vgextend data /dev/ssd
もし、SSDを単独でVGにしてしていたら、LVをPVに再帰的に指定すればいい。
sudo lvcreate -n from_ssd_for_hyrid -L 50GB my_ssd_vg sudo pvcreate /dev/my_ssd_vg/from_ssd_for_hyrid sudo vgextend data /dev/my_ssd_vg/from_ssd_for_hyrid
LV を再帰的にLVMのPVに指定できる柔軟性ってすごい便利だよね。
VG からキャッシュ用のLVを切り出す
VGからLVに切り出す。このときに、どのPVから作るのかを指定する
lvcreate -n lv_cache -L 20G data /dev/ssd
VG からキャッシュ・メタデータ用のLVを切り出す。
同じようにメタデータ用のLVを作る
lvcreate -n lv_cache_meta -L 1G data /dev/ssd
LVM ってVGでまとめておいて、そこからLV切り出すときにPVを透過的に指定できるのでホント便利。
CachePool を作る
作ったキャッシュ用LV( lv_cache ) と キャッシュメタデータ用LV ( lv_cache_meta ) を1つに結合して、キャッシュプールを作る
lvconvert --type cache-pool --poolmetadata data/lv_cache_meta data/lv_cache
これが成功すると lvs -a
で lv_cache_meta が []
の中に消える。
キャッシュLVを作る
ここまでで作ったキャッシュ・プールを元データのLVに乗っけて統合する
lvconvert --type cache --cachepool data/lv_cache data/my_server_data
出来上がりを確認する。
lvs では 見れないので -a
を付けて確認する。lvは大量になるのでVGで絞り込んでいます。
絞り込みは lvs $VG_NAME
である。併せて lvs -a $VG_NAME
です、
takuya$ sudo lvs -a data LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert [lv_cache] data Cwi---C--- 30.00g 89.87 0.19 0.00 [lv_cache_cdata] data Cwi-ao---- 30.00g [lv_cache_cmeta] data ewi-ao---- 2.00g [lvol0_pmspare] data ewi------- 2.00g server_data data Cwi-aoC--- 10.01t [lv_cache] [server_data_corig] 89.87 0.19 0.00 [server_data_corig] data owi-aoC--- 10.01t
後片付け
不要になったら、次のコマンドです。取り外します。
lvconvert --splitcache data/my_server_data
で一旦キャッシュを取り外すことができます。
再度取り付けるときは、さっきのコマンドをもう一度
lvconvert --type cache --cachepool data/lv_cache data/my_server_data
このとき
Do you want wipe existing metadata of cache pool volume data/lv_cache? [y/n]: y
この様に、今のキャッシュのデータはワイプして消すけど問題ない?って聞かれる。
これで、取り外して(デタッチ)と取り付け(アタッチ)が出きるようになるので、速度を調べたり容量を変化させたり自由にできますね。
さて、速いのか
多分速くないです。キャッシュなので、ベンチマークを使ってもあまりうまく取れない. だってキャッシュなので一回はファイルを読まないといけない。
というわけで、適当な1GBくらいのファイルを連続して2回読み込んでみましょう
takuya$ dd if=./sample.dd of=/dev/null bs=1k 1411902+1 レコード入力 1411902+1 レコード出力 1445787812 bytes (1.4 GB, 1.3 GiB) copied, 15.7419 s, 91.8 MB/s takuya@$ dd if=./sample.dd of=/dev/null bs=1k 1411902+1 レコード入力 1411902+1 レコード出力 1445787812 bytes (1.4 GB, 1.3 GiB) copied, 2.04984 s, 705 MB/s
ぉ、割と速い。。。?SSDの限界値超えて速すぎる?うちの安物SSDは500MB/s以上でないと思う、きっとこれはメモリキャッシュが効いてる
うーん、メモリキャッシュには敵わないので、アクセスするファイルが多いときに有効に働きそうですね。
10GBで試してみる。
takuya@:video$ dd if=10GB.dd of=/dev/null 19521704+1 レコード入力 19521704+1 レコード出力 9995112872 bytes (10 GB, 9.3 GiB) copied, 126.673 s, 78.9 MB/s takuya@:video$ dd if=10GB.dd of=/dev/null 19521704+1 レコード入力 19521704+1 レコード出力 9995112872 bytes (10 GB, 9.3 GiB) copied, 124.038 s, 80.6 MB/s
うーんあまり効いてる気がしない。
キャッシュなので、HDDのベンチをとってもあまり意味のない数字が出ていました。 徐々に転送速度が下がるのはキャッシュがなくなってHDDに取りに行ってそれを待つからでしょうか?
キャッシュは、キャッシュヒット率とかも考慮しないといけないわけですし、その一方でメモリは潤沢に搭載できるわけですし。メモリがあるところへの2次キャッシュと考えると、SSDを1TB買ってキャッシュに使うなら、DDRメモリを32GBまで積んだほうがいいわけですし。やっぱり答えはいつも同じ。メモリは限界まで積め。できる限りメモリ詰め込め。なるほど、流行らないわけだわ。
WriteBackでHDDの書き込み待ちをせず、Write Troughにしたら書き込み速度はSSDと同等になるはずだろうが、WriteThroughは停電でデータ消えるし用途が限られる.
NFSやSMBををLVMキャッシュしたらいいのかと思ったけどそれってLVMでやることだろうか。
うーん。キャッシュヒット率・・・
ちなみに我が家のSSDの速度を測ったところ READで 450MB/s でした。
takuya@:~$ dd if=/data/ssd10G.dd of=/dev/null 20971520+0 レコード入力 20971520+0 レコード出力 10737418240 bytes (11 GB, 10 GiB) copied, 23.7774 s, 452 MB/s
これも連続して読み出すとメモリキャッシュだ。
takuya@:~$ dd if=10G.dd of=/dev/null 10240+0 レコード入力 10240+0 レコード出力 10737418240 bytes (11 GB, 10 GiB) copied, 1.21843 s, 8.8 GB/s
メモリマジはやい。。。
2018-08-06 追記
dm-cacheはwrite through のときでも、シーケンシャルIO(Write)はキャッシュしないって書いてある。
バッファリングはシステムに任せてメモリでやってくれってことね。
Re: [linux-lvm] Testing the new LVM cache feature
By default dm-cache (as is currently upstream) is not going to cache sequential IO, and it also isn't going to cache IO that is first written. It waits for hit counts to elevate to the promote threshold. So dm-cache effectively acts as a hot-spot cache by default.
2018-11-13 追記
キャッシュのメタ情報を扱いだすと。再起動時にlvmetadで時間がかかる
WARNING: Failed to connect to lvmetad. Falling back to internal scanning.
- https://unix.stackexchange.com/questions/199164/error-run-lvm-lvmetad-socket-connect-failed-no-such-file-or-directory-but
- https://askubuntu.com/questions/745218/ubuntu-wont-boot-because-of-lvmetad
起動の時間が3分くらいかかるようになったので調べてたらどうもLVMのキャッシュらしい。 やっぱキャッシュいらないかもしれない。
2018-11-30 追記
LVMのキャッシュをSSDにするとやっぱり速い.。停電でデータ消えるとか思ってたけど、よく考えるとSSDにデータ残る。RAMDiskやってたときの思考が残ってた。
関連資料
http://takuya-1st.hatenablog.jp/entry/2017/03/06/192708
参考資料
man lvmcache(7)
https://rwmj.wordpress.com/2014/05/22/using-lvms-new-cache-feature/