2014年6月14日

BTRFS の RAID 機能

BTRFSはRAID機能を内蔵している。

LinuxのRAIDはmdの使用が一般的だが、今回は以前報告した「BTRFSのFIEMAP/filefragは嘘をつく」と併せてこの内部RAID機能を検証する。

検証に使った 3.0.101カーネルは以下のRAIDレベルをサポートする。
  • JBOD - リニアな複数ディスクの結合。冗長性なし
  • RAID0 - ストライピングによるアクセス性能向上。冗長性なし
  • RAID1 - ミラーリング。100%冗長
  • RAID10 - RAID0 を RAID1上で動作。ストライピングによるアクセス性能向上と100%の冗長性
上記より新しいカーネルではRAID5(水平パリティ)とRAID6(二重水平パリティ)も実現されているが、BTRFSのWikiにはまだ開発中でバグが多いので使用するな、と警告がある。

まず、実験のためにloopデバイスを二つ作り、JBODをマウントする。

root@h-rn312:~# truncate -s 100M /data/img/loop-img.0 /data/img/loop-img.1
root@h-rn312:~# losetup /dev/loop0 /data/img/loop-img.0
root@h-rn312:~# losetup /dev/loop1 /data/img/loop-img.1
root@h-rn312:~# mkfs.btrfs -f /dev/loop0 /dev/loop1 
SMALL VOLUME: forcing mixed metadata/data groups
WARNING! - Btrfs v3.14.1 IS EXPERIMENTAL

WARNING! - see http://btrfs.wiki.kernel.org before using

Performing full device TRIM (100.00MiB) ...

Turning ON incompat feature 'mixed-bg': mixed data and metadata block groups
Created a data/metadata chunk of size 8388608
Performing full device TRIM (100.00MiB) ...
adding device /dev/loop1 id 2
fs created label (null) on /dev/loop0
    nodesize 4096 leafsize 4096 sectorsize 4096 size 200.00MiB
Btrfs v3.14.1
root@h-rn312:~# mount -o rw /dev/loop0 /mnt
mount: block device /dev/loop0 is write-protected, mounting read-only
root@h-rn312:~# mount -o remount,rw /dev/loop0 /mnt


mkfs時に二つのディスクデバイスを組み合わせる(デフォルトはJBOD)ことを宣言しているので、マウントはどちらのデバイス名でもよい。後から「btrfs device add /dev/loop2 /mnt」のように追加もできる。一回目のマウントが読み出しオンリーになってしまったが理由は不明。

複数ディスクを使ってBTRFSのRAIDを構築・構成する方法の詳細はBTRFSのWikiを参照してください。

これに50MBのダミーのファイルを作る。

root@h-rn312:~# dd if=/dev/urandom of=/mnt/jbod bs=1M count=50

このファイルをfilefragでエクステントの状況を見る。使ったのは最新のe2fsprogs-1.42.10からビルドしたfilefrag。以前のバージョンより冗長な出力を見せる。

root@h-rn312:~# filefrag -v /mnt/jbod
Filesystem type is: 9123683e
File size of /mnt/jbod is 52428800 (12800 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..    3199:       3072..      6271:   3200:          
   1:     3200..    7999:       8192..     12991:   4800:       6272:
   2:     8000..   12799:      13312..     18111:   4800:      12992: eof
/mnt/jbod: 3 extents found

しかし、ここで表示されるFIEMAPioctl出力の「物理オフセット」は「BTRFSのFIEMAP/filefragは嘘をつく」で報告したようにBTRFSが内部で使う「論理オフセット」(filefragのファイル「論理オフセット」と混同しないこと)で、実際の物理ディスクのオフセット(位置)とは関係ない。

そこで特別にパッチを当てたカーネルとfilefragを使って本当の物理ディスクオフセットを見てみる。
root@h-rn312:~# filefrag -v -P /mnt/jbod
Filesystem type is: 9123683e
File size of /mnt/jbod is 52428800 (12800 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length: device: flags:
   0:        0..    3199:        256..      3455:   3200:   7:1
   1:     3200..    7999:       3072..      7871:   4800:   7:0
   2:     8000..   12799:       5376..     10175:   4800:   7:1   eof
/mnt/jbod: 3 extents found

device」フィールドは実際に使用されている物理ディスク(この場合はloopデバイス)のメジャー:マイナー・デバイス番号。これを見ると、ファイルはloop0デバイスとloop1デバイスにストライプ的に分散されており、普通「JBOD」でイメージする単純なリニア結合とは違い、むしろ複数ディスクからなるストレージプールにパフォーマンスを考慮した分散と解釈するのが適当のようだ。

続いて、同じようにして3台のディスクからなるRAID0(ストライピング)を試してみる(ここではloopデバイスでなく/dev/sdb*を使ったのでデバイス番号がJBODの例と違うが、うまく脳内変換してください)。

root@h-rn312:~# filefrag -v /mnt3/raid0
Filesystem type is: 9123683e
File size of /mnt3/raid0 is 52428800 (12800 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..   12799:       7158..     19957:  12800:             eof
/mnt3/raid0: 1 extent found
root@h-rn312:~# filefrag -v -P /mnt3/raid0
Filesystem type is: 9123683e
File size of /mnt3/raid0 is 52428800 (12800 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length: device: flags:
   0:        0..   12799:       1622..      5887:   4266:   8:21  eof
   0:        0..   12799:       1616..      5887:   4272:   8:20  eof
   0:        0..   12799:       4432..      8693:   4262:   8:19  eof
/mnt3/raid0: 1 extent found
root@h-rn312:~# filefrag -v -P -X /mnt3/raid0
Filesystem type is: 9123683e
File size of /mnt3/raid0 is 52428800 (12800 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length: device: flags:
   0:        0..    31ff:        656..      16ff:   10aa:   8:21  eof
   0:        0..    31ff:        650..      16ff:   10b0:   8:20  eof
   0:        0..    31ff:       1150..      21f5:   10a6:   8:19  eof
/mnt3/raid0: 1 extent found

物理エクステントの出力を見ると、/mnt/raid0ファイルの1論理エクステント(0~12799)に3物理エクステントが/dev/sdb[1-3](8:19~8:21)に分散して対応しており、filefragの出力からは分からないが各ストライプの長さは64KB(16ページブロック)。物理エクステントは連続してファイル内容を保持してはおらず、ストライプの続きは次のディスクのストライプに連続して、ディスクの使用は論理エクステントの終端まで循環する。

eof」のフラグは filefragが単に最終論理エクステントに表示するだけなのであまり意味はない

-Xオプションをつけた16進表示も見ると、物理エクステントの開始オフセットは3台のディスクで揃っていないどころか、ストライプの境界にも揃っておらず、さらには長さもバラバラなことが分かり、mdのディスク・アドレス空間で一様なストライピングとは様相が違うことが分かる。

次は2台のディスクを使ったRAID1(ミラーリング)。

root@h-rn312:~# filefrag -v /mnt2/raid1
Filesystem type is: 9123683e
File size of /mnt2/raid1 is 52428800 (12800 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..    6399:       5129..     11528:   6400:          
   1:     6400..    9599:      11529..     14728:   3200:          
   2:     9600..   12799:      21504..     24703:   3200:      14729: eof
/mnt2/raid1: 2 extents found
root@h-rn312:~# filefrag -v -P /mnt2/raid1
Filesystem type is: 9123683e
File size of /mnt2/raid1 is 52428800 (12800 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length: device: flags:
   0:        0..    6399:       2313..      8712:   6400:   8:18
   0:        0..    6399:       5129..     11528:   6400:   8:17
   1:     6400..    9599:       8713..     11912:   3200:   8:18
   1:     6400..    9599:      11529..     14728:   3200:   8:17
   2:     9600..   12799:      18688..     21887:   3200:   8:18  eof
   2:     9600..   12799:      21504..     24703:   3200:   8:17  eof
/mnt2/raid1: 3 extents found

三つの論理エクステントのそれぞれが 2台のディスクの同じサイズの物理エクステントで構成されているのはよいとしても、ペアになる物理エクステントの開始オフセットは揃っていない。どうもmdのような完全ディスクレベルのミラーリングとは違い、ファイルエクステント単位のRAIDを実現していることがますますはっきりしてきた。

最後はRAID10。最低4台のディスクが必要(mdでは3台でもRAID10を実現できる)。

root@h-rn312:~# filefrag -v /mnt4/raid10
Filesystem type is: 9123683e
File size of /mnt4/raid10 is 52428800 (12800 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..   12799:       7174..     19973:  12800:             eof
/mnt4/raid10: 1 extent found
root@h-rn312:~# filefrag -v -P /mnt4/raid10
Filesystem type is: 9123683e
File size of /mnt4/raid10 is 52428800 (12800 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length: device: flags:
   0:        0..   12799:       2310..      8709:   6400:   8:25  eof
   0:        0..   12799:       2310..      8709:   6400:   8:24  eof
   0:        0..   12799:       2304..      8703:   6400:   8:23  eof
   0:        0..   12799:       5120..     11519:   6400:   8:22  eof
/mnt4/raid10: 1 extent found

RAID1と同様、物理オフセットは揃っていない。

さらに動作を検証すると、RAID機能はリアルタイムではなく、一旦普通のシングルディスクファイルで展開されたエクステントをバックグラウンドでRAIDに再構築しているようだ。

下は、RAID0にファイルを作成した直後と10秒ほど経ってからの物理エクステントの様子。最初は/dev/sdb1だけで作られたファイルが/dev/sdb[1-3]に分散される様子が見える。

root@h-rn312:~# ./filefrag -v -P /mnt3/raid0
Filesystem type is: 9123683e
File size of /mnt3/raid0 is 52428800 (12800 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length: device: flags:
   0:        0..    1023:          0..      1023:   1024:   8:19
   1:     1024..    2047:          0..      1023:   1024:   8:19
   2:     2048..    3071:          0..      1023:   1024:   8:19
   3:     3072..    4095:          0..      1023:   1024:   8:19
   4:     4096..    5119:          0..      1023:   1024:   8:19
   5:     5120..    6143:          0..      1023:   1024:   8:19
   6:     6144..    7167:          0..      1023:   1024:   8:19
   7:     7168..    8191:          0..      1023:   1024:   8:19
   8:     8192..    9215:          0..      1023:   1024:   8:19
   9:     9216..   10239:          0..      1023:   1024:   8:19
  10:    10240..   11263:          0..      1023:   1024:   8:19
  11:    11264..   12287:          0..      1023:   1024:   8:19
  12:    12288..   12799:          0..       511:    512:   8:19  eof
/mnt3/raid0: 13 extents found
root@h-rn312:~# ./filefrag -v -P /mnt3/raid0
Filesystem type is: 9123683e
File size of /mnt3/raid0 is 52428800 (12800 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length: device: flags:
   0:        0..   12799:       1622..      5887:   4266:   8:21  eof
   0:        0..   12799:       1616..      5887:   4272:   8:20  eof
   0:        0..   12799:       4432..      8693:   4262:   8:19  eof
/mnt3/raid0: 1 extent found

と言うことで、BTRFSのRAID機能は、その実現方法がファイルシステムに依存しているらしいことが分かった(当然か)。LVMなしでJBODが簡単に実現できることはメリットがあるが、「本物の」RAID機能はBTRFS内部で一体化しておりレイヤの切り分けができないので、システムの拡張とか事故が起きたときの 対応はどうだろうかという疑問が残る。得てしてこう言う「一体型」ソリューションは、そのシステムが想定しているモデルから少しでも外れると途端に使いにくくなるもの、と言う経験則からは躊躇する。

0 件のコメント:

コメントを投稿