それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

dm-cache(lvm-cache)を作って使う、設定方法

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

で一旦キャッシュを取り外すことができます。

さて、速いのか

多分速くないです。キャッシュなので、ベンチマークを使ってもあまりうまく取れない. だってキャッシュなので一回はファイルを読まないといけない。

というわけで、適当な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に取りに行ってそれを待つからでしょうか?

f:id:takuya_1st:20180806021737p:plain

キャッシュは、キャッシュヒット率とかも考慮しないといけないわけですし、その一方でメモリは潤沢に搭載できるわけですし。メモリがあるところへの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.

関連資料

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/