テストステ論

高テス協会会長が, テストステロンに関する情報をお届けします.

dm-lcの紹介 (10) lcコマンドセット

目次

dm-lcは, ユーザランドとの界面に, dmsetupコマンド(create, remove, reload, message etc.)とsysfsを使っています. しかし, ユーザがこれらのコマンドを自由に叩くことが危険な場合もあります.
例を挙げます. dm-lcは, キャッシュデバイスなしで動作するモードを許します. マルチコア環境において, この状態に対してキャッシュデバイスを追加してキャッシュありモードに安全に遷移させるためには, ロックをとる必要があります. モードが遷移して実行パスが切り替わるため, 新しいI/Oを拒否するのが実装として簡単かつ確実です. dm-lcでは, これらのロックはカーネル内に実装せず, ユーザランドでのdmsetup suspend|resumeで実現しています. 他にも, dm-lcの複雑なキャッシュ階層の中に残留しているI/Oのことなど, 考慮すべきことが様々あります. dm-lcはライトバックキャッシュなので, 操作を誤るとデータが吹っ飛びます. そのため, 細心の注意が必要なのです.

lcコマンドセット

この問題に対して, dm-lcは, ユーザランドのスクリプトを用意することによって, 安全な操作を実現しています. そのスクリプトは, #python setup.py installすることによって自動的にインストールされます. 以下に, その説明を載せます.

コマンド 説明
lc-create $volName $deviceID $path $pathで指定されたデバイス-backedな, キャッシュがない仮想デバイスを作ります. dm-lcでは作成した仮想デバイスのことをlcデバイスと読んでいます. キャッシュなしモードで動作するlcデバイスは概念的には, offset=0のlinearデバイスと同じです.
lc-format-cache $path キャッシュとして使うデバイスをフォーマットします. フォーマットとは, メタデータのデフォルト値を書き込むことです. この状態ではキャッシュは利用可能ではありません. メモリ上のデータ構造がないからです. 続いて, resumeをする必要があります.
lc-resume-cache $cacheID $path フォーマットしたキャッシュデバイスをresumeします. resumeとは, メタデータをスキャン*1して, メモリ上のメタデータを復元することです. dm-lcでは, フォーマットしたばかりのキャッシュも, サーバがクラッシュしたあとのキャッシュも同格のものとして扱っています.
lc-attach $deviceID $cacheID lcデバイスに対して, キャッシュをattachします. これによって, lcデバイスはキャッシュありモードで動作します.
lc-detach $deviceID $deviceIDで指定されるlcデバイスにattachされているキャッシュデバイスをdetachします. キャッシュデバイス上に, $deviceIDについてダーティなキャッシュが残っているにも関わらず強制的にdetachすることは整合性の観点から危険です. そのため, すべてのダーティがmigrateされない限りはdetach出来ないようにしています.
lc-remove $deviceID lcデバイスを削除します. キャッシュがdetachされていることが条件です.
lc-deamon start/restart/stop サーバ内にデーモンを常駐させます. デーモンは, migrationの自動制御などを自動的に行います. sysfsから設定他, デバイス-キャッシュの構成なども取得します.

使ってみよう(お試し)

どういう効果があるか分からないストレージカーネルモジュールをサーバに入れることは推奨しません. そのため, dm-lcは, 簡単にお試しするためのスクリプトを用意しています. 自分の手で実行し, 自分の目で動作確認してください.
以下では, ユーザ権限でコンパイルしてから, ルート権限でインストールをしてdm-lcの操作を行うという流れを想定して話をします. dm-lcをセットアップして, 様々なI/Oを与えてみて, sysstatなどで動作を確認すると良いでしょう.

まず, dm-lcをダウンロードしましょう.

$cd
$git clone https://github.com/akiradeveloper/dm-lc.git

これで, /home/akira/dm-lcにコードがダウンロードされます. 設定するファイルは, configファイルだけです. configファイルは以下のようになっています. 自分の環境に合うように修正してください. 以下のファイルでそうなっているように, 使うデバイスは, LVMを使って作成した仮想デバイスでも構いません. キャッシュデバイスは小さい方が, migrationの様子が分かる点では良いです. 例えば以下では, 3MBとしています. SSDに対して圧倒的な速度で書き込まれていく様子が見たい場合は, 30GB程度の大きさにすると良いでしょう.

cd /home/akira/dm-lc
$vi config
#! /bin/sh

export LC_ROOT=`pwd`

BACKING=/dev/vg1/backing // 修正する
export BACKING

CACHE=/dev/vg1/cache3m // 修正する
export CACHE

続いてコンパイルです.

$source build

を行なってください. これによって, dm-lcがコンパイルされます. それではルート権限に移って, セットアップをしましょう. 以下のコマンドを打てば, dm-lcが自動的にインストールされ, キャッシュありモードの仮想デバイス(名前はperflv)が生成されます. ここまで来るとすでに, ddなどを打って楽しむことが出来ます. prepareスクリプトの中では, lcコマンドセットのインストールも自動的に行なっています.

$cd - 
#cd /home/akira/dm-lc
#source prepare

dm-lcでは, もっとも初歩的なテストとして, rubyのbuild and make testを用意しています.

#source ruby_compile

を行うと, xfsでフォーマットされたlcデバイスが/mnt/perflvにマウントされ, 同梱されたruby tarballがその下に展開され, コンパイルが始まります. 私のMBPに入ってる糞仮想マシンであれば10分以上かかりますが, i7-3770とメモリ32Gを積んだ開発用マシンであれば, 数十秒で終わります. xfsを選択した理由は, write barrierを発行してくれるからです. dm-lcの工夫である, write barrierの遅延処理のおかげで, I/Oはスムースに流れます. その工夫なしのナイーブな実装の場合, 性能は著しく低下します.

動作確認の方法は何でも構いませんが, sysstatやblktraceが適切だと思います. sysstatについては, 例えば, sar -druv 1と打ってみてください.

以上です. 私はdm-lcを世に出したいと思っています. 最近は, dm-lcのユーザランド部分に関する記事を書いています. これは重要なことです. みなさんがdm-lcを試し, その有用性を知ることで, 徐々に普及していく未来に対して一歩一歩向かっていると思います.

*1:formatとresumeにとても時間がかかることが, dm-lcの課題です