LinuxのRAIDはmdの使用が一般的だが、今回は以前報告した「BTRFSのFIEMAP/filefragは嘘をつく」と併せてこの内部RAID機能を検証する。
検証に使った 3.0.101カーネルは以下のRAIDレベルをサポートする。
- JBOD - リニアな複数ディスクの結合。冗長性なし
- RAID0 - ストライピングによるアクセス性能向上。冗長性なし
- RAID1 - ミラーリング。100%冗長
- RAID10 - RAID0 を RAID1上で動作。ストライピングによるアクセス性能向上と100%の冗長性
まず、実験のために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 |
しかし、ここで表示されるFIEMAPのioctl出力の「物理オフセット」は「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 件のコメント:
コメントを投稿