第748回の
さまざまなRAIDレベルたち
RAIDにはいくつかのレベルとそれを組み合わせたものが存在します[1]。そのうちUbuntuがインストーラーとしてサポートしているのは、RAID 0、1、5、6、10の5種類です。もちろんインストーラーはUbuntuのルートファイルシステムを構築するための仕組みなので、純粋なデータ領域をRAIDとして構築するのであれば、mdadm
コマンドを用いてさらに複雑な構成が可能になります。
まずは第748回の手順に従って、RAID 1、5、6、10について紹介しましょう。やっていることは第748回をベースにしています。環境の構築方法は第748回の
RAID 5:速度と冗長性と利用効率のバランス重視=虻蜂取らず
UbuntuのインストーラーはRAID 2、3および4には対応していません。使用効率が悪い、計算量が多い、I/
これらの欠点をある程度解消したのがRAID 5です。RAID 0のようにデータを複数のストレージに分散して記録しつつ、データのパリティを計算し、これも分散して記録する方式です。最低3台のストレージが必要ではあるものの、1台分の容量のみをパリティとして使うだけで、ストレージの利用効率にも優れています。RAID 0の速度とRAID 1の冗長性を兼ね備えた良いとこ取りという触れ書きですが、1台壊れるだけで速度も信頼性も大きく低下します。よってソフトウェアRAIDにおいてRAID 5を使うのは限定的なケースと思っておけば良いでしょう。
RAID 5は最低3台なので3台構成で構築してみましょう。インスタンス名はraid5
」、カスタムストレージボリュームはraid5b
」raid5c
」
$ lxc init raid5 --empty --vm -c limits.cpu=2 -c limits.memory=8GiB --storage raid $ lxc config device set raid5 root size=40GiB $ lxc config device add raid5 iso disk boot.priority=1 source=$HOME/ダウンロード/ubuntu-22.04.1-live-server-amd64.iso $ lxc storage volume create raid raid5b --type=block size=40GiB $ lxc storage volume create raid raid5c --type=block size=40GiB $ lxc storage volume attach raid raid5b raid5 $ lxc storage volume attach raid raid5c raid5 $ lxc start raid5 --console=vga
ストレージの設定は次のようになります。最低ひとつのESP
インストール後再起動して、状態を確認すると次のような結果になります。
$ cat /proc/mdstat Personalities : [raid6] [raid5] [raid4] [linear] [multipath] [raid0] [raid1] [raid10] md0 : active raid5 sdc2[1] sdb2[0] sda2[3] 81612800 blocks super 1.2 level 5, 512k chunk, algorithm 2 [3/3] [UUU] unused devices: <none> $ sudo mdadm --detail /dev/md0 /dev/md0: Version : 1.2 Creation Time : Sun Jan 29 11:59:59 2023 Raid Level : raid5 Array Size : 81612800 (77.83 GiB 83.57 GB) Used Dev Size : 40806400 (38.92 GiB 41.79 GB) Raid Devices : 3 Total Devices : 3 Persistence : Superblock is persistent Update Time : Sun Jan 29 13:00:55 2023 State : clean Active Devices : 3 Working Devices : 3 Failed Devices : 0 Spare Devices : 0 Layout : left-symmetric Chunk Size : 512K Consistency Policy : resync Name : ubuntu-server:0 UUID : d7b8174e:a3f77ba5:4b85fb03:8f1d951f Events : 252 Number Major Minor RaidDevice State 0 8 18 0 active sync /dev/sdb2 1 8 34 1 active sync /dev/sdc2 3 8 2 2 active sync /dev/sda2
RAID 1のときと比べると、台数やサイズ等の違いに加えて、次のようなフィールドが追加されています。
Layout : left-symmetric Chunk Size : 512K
「Layout
」Chunk Size
」
RAID 5の場合、パリティ用の領域は1台分となります。そのため台数が増えるほど、ストレージの利用効率はあがります。たとえばnTBが3台なら2nTB
さらに最近の大きな容量のHDDだと、再構築時の読み込みエラー数も無視できません。結果的にRAID 5は、RAIDとして扱いづらい位置づけになりました。
RAID 6:2台壊れてもなんとかなる堅牢性
RAID 6はRAID 5をベースに、パリティを複数のストレージに書き込む方式です。このため最低台数は4台からとなりますが、2台壊れてもなんとかなる
RAID 6もとりあえず最低必要台数の4台で構築してみます。インスタンス名はraid6
」、カスタムストレージボリュームはraid6b
」raid6c
」raid6d
」
$ lxc init raid6 --empty --vm -c limits.cpu=2 -c limits.memory=8GiB --storage raid $ lxc config device set raid6 root size=40GiB $ lxc config device add raid6 iso disk boot.priority=1 source=$HOME/ダウンロード/ubuntu-22.04.1-live-server-amd64.iso $ lxc storage volume create raid raid6b --type=block size=40GiB $ lxc storage volume create raid raid6c --type=block size=40GiB $ lxc storage volume create raid raid6d --type=block size=40GiB $ lxc storage volume attach raid raid6b raid6 $ lxc storage volume attach raid raid6c raid6 $ lxc storage volume attach raid raid6d raid6 $ lxc start raid6 --console=vga
インストール手順も同じなので、最終的な構成結果だけ残しておきます。
$ cat /proc/mdstat Personalities : [raid6] [raid5] [raid4] [linear] [multipath] [raid0] [raid1] [raid10] md0 : active raid6 sdc2[1] sdb2[0] sda2[3] sdd2[2] 81612800 blocks super 1.2 level 6, 512k chunk, algorithm 2 [4/4] [UUUU] unused devices: <none> $ sudo mdadm --detail /dev/md0 /dev/md0: Version : 1.2 Creation Time : Sun Jan 29 14:54:09 2023 Raid Level : raid6 Array Size : 81612800 (77.83 GiB 83.57 GB) Used Dev Size : 40806400 (38.92 GiB 41.79 GB) Raid Devices : 4 Total Devices : 4 Persistence : Superblock is persistent Update Time : Sun Jan 29 15:02:01 2023 State : clean Active Devices : 4 Working Devices : 4 Failed Devices : 0 Spare Devices : 0 Layout : left-symmetric Chunk Size : 512K Consistency Policy : resync Name : ubuntu-server:0 UUID : 73ab874d:5cd3dd66:9e3aa7c6:235a4ca1 Events : 187 Number Major Minor RaidDevice State 0 8 18 0 active sync /dev/sdb2 1 8 34 1 active sync /dev/sdc2 2 8 50 2 active sync /dev/sdd2 3 8 2 3 active sync /dev/sda2
RAID 6は台数を増やして容量を稼ぎたい場合の選択肢になってくるでしょう。ただし、再構築時に故障が起きやすい弱点についてはRAID 5と同じです。2台壊れるよりも3台壊れることのほうが少ないだろうという期待を込めて
RAID 10:RAID 0と1のいいとこどりでCPUに優しい構成
ここまで紹介したRAIDはいずれも単体のRAIDレベルで構成されていました。それに対して
たとえば
一般的にNested RAIDはその分だけ必要なストレージの台数が増えます。RAID 6+6になると最低16台のストレージが必要ですし、RAID 1+0でも4台必要です。構成も複雑になりがちですが、その分それぞれのレベルの利点を組み合わせやすくなります。
さて、Ubuntuのインストーラーは
RAID 10で使用できる具体的なデータレイアウトについては、md(4)のmanページのRAID 10の項目や英語版のWikipediaの項目、Il sistemistaの説明などが参考になります。かんたんに説明すると、あるデータブロック
- near:複製chunkを元のchunkを書き込んだストレージから、複製先のストレージ上のできるだけ近い位置に書き込む
- far:複製chunkを元のchunkを書き込んだストレージから、複製先のストレージ上の十分に遠い位置に書き込む
- offset:複製chunkを元のchunkを書き込んだストレージに対して、距離を指定した値の分だけずらしたストレージに書き込む
nearレイアウトで、複製を1個作成する
farレイアウトは個々のストレージをオリジナルのデータを記録する領域と、複製chunkを記録する領域に分割した上で、同じストレージにオリジナルと複製データの両方が書き込まれてしまわないように調整しています。オリジナルのデータが個々のストレージデバイスの近い領域にまとまっていることで、理論上はシーケンシャル読み込みの性能が向上しますが、書き込み性能は落ちます。実際のところは、ワークロードによってnear/
RAID 10は複製を1個作成するのであれば、1台までの故障であれば復旧可能です。また、連続しない2台の故障でも復旧できる可能性があります。よってRAID 6よりは耐障害性が若干低くなるのですが、パリティ計算をしなくて良い分、CPUに優しい構成となります。ただしパリティの代わりにデータを複製する以上、利用可能な容量はRAID 1と同様に半分以下となってしまいます。
さらにRAID 10の特徴としてレプリカ数を指定できる点にあります。当然のことながらそのぶんストレージの利用効率は落ちるわけですが、その分耐障害性があがります。また異なるレイアウトを組み合わせて使うことも可能です。
説明が長くなってしまいましたが、4台構成でRAID 10を構築してみしょう。インスタンス名はraid10
」、カスタムストレージボリュームはraid10b
」raid10c
」raid10d
」
$ lxc init raid10 --empty --vm -c limits.cpu=2 -c limits.memory=8GiB --storage raid $ lxc config device set raid10 root size=40GiB $ lxc config device add raid10 iso disk boot.priority=1 source=$HOME/ダウンロード/ubuntu-22.04.1-live-server-amd64.iso $ lxc storage volume create raid raid10b --type=block size=40GiB $ lxc storage volume create raid raid10c --type=block size=40GiB $ lxc storage volume create raid raid10d --type=block size=40GiB $ lxc storage volume attach raid raid10b raid10 $ lxc storage volume attach raid raid10c raid10 $ lxc storage volume attach raid raid10d raid10 $ lxc start raid10 --console=vga
インストール手順も同じなので、最終的な構成結果だけ残しておきます。
$ cat /proc/mdstat Personalities : [raid10] [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] md0 : active raid10 sdc2[1] sdb2[0] sdd2[2] sda2[3] 81612800 blocks super 1.2 512K chunks 2 near-copies [4/4] [UUUU] unused devices: <none> $ sudo mdadm --detail /dev/md0 /dev/md0: Version : 1.2 Creation Time : Sat Feb 4 10:33:34 2023 Raid Level : raid10 Array Size : 81612800 (77.83 GiB 83.57 GB) Used Dev Size : 40806400 (38.92 GiB 41.79 GB) Raid Devices : 4 Total Devices : 4 Persistence : Superblock is persistent Update Time : Sat Feb 4 10:48:36 2023 State : active Active Devices : 4 Working Devices : 4 Failed Devices : 0 Spare Devices : 0 Layout : near=2 Chunk Size : 512K Consistency Policy : resync Name : ubuntu-server:0 UUID : ce802cc9:9563225b:8afe8fca:f22cf8d3 Events : 302 Number Major Minor RaidDevice State 0 8 18 0 active sync set-A /dev/sdb2 1 8 34 1 active sync set-B /dev/sdc2 2 8 50 2 active sync set-A /dev/sdd2 3 8 2 3 active sync set-B /dev/sda2
上記の
Layout : near=2
残念ながらUbuntuのインストーラーでは、near2以外のRAID10は選択できません。
性能テスト
UbuntuがサポートしているRAIDレベルを一通りセットアップできたところで、それぞれの速度を確認してみましょう。ちなみUbuntuをインストールした状態のRAID 1
$ lxc storage info raid info: description: "" driver: btrfs name: raid space used: 115.06GiB total space: 372.53GiB
では、それぞれ速度にどれくらいの違いがでるのか、簡易的に確認してみましょう。Ubuntuにおけるストレージの速度計測だと、fioが定番です。パッケージから簡単にインストールできるのでインストールしてしまいましょう。今回はJSONで出力したものをパースしたいので、jqも合わせてインストールしておきます。
$ sudo apt install fio jq
fioはあまりにも設定パラメーターが多く、実際に計測する際にどれをどう選べば良いか判断が難しいところです。言い方をかえると、このあたりのパラメーターをきちんと理解できる人でないと正しい計測はできないということでもあるのですが、そこはそれ。精度や想定しているワークロードとかは置いておいてともかくカジュアルに測りたい場合には不便です。というわけで、それっぽいパラメーターをでっちあげてみました。これを設定ファイルとして流用することにしましょう。
$ cat <<EOF > cdm.fio [global] ioengine=libaio iodepth=1 size=1g direct=1 loops=5 runtime=30 filename=cdm directory=/tmp/ stonewall [SEQ1MQ8T1-Read] bs=1m iodepth=8 numjobs=1 rw=read [SEQ1MQ8T1-Write] bs=1m iodepth=8 numjobs=1 rw=write [SEQ128KQ32T1-Read] bs=128k iodepth=32 group_reporting numjobs=1 rw=read [SEQ128KQ32T1-Write] bs=128k iodepth=32 numjobs=1 rw=write [RND4KQ32T16-Read] bs=4k iodepth=32 numjobs=16 group_reporting rw=randread [RND4KQ32T16-Write] bs=4k iodepth=32 numjobs=16 group_reporting rw=randwrite [RND4KQ1T11-Read] bs=4k iodepth=1 numjobs=1 rw=randread [RND4KQ1T1-Write] bs=4k iodepth=1 numjobs=1 rw=randwrite EOF
個々の設定項目の詳細についてはfioのドキュメントを参照してください。
これを実機で動かすためには次のように実行します。
$ fio -f cdm.fio --output-format=json --output=results.json
これでresults.
」
$ jq -r '.jobs[] | [.jobname, if .read.bw > 0 then .read.bw/1000, .read.iops | round else .write.bw/1000, .write.iops | round end] | @tsv' \ results.json | column -t --table-columns JOB,MB/s,IOPS --table-right MB/s,IOPS JOB MB/s IOPS SEQ1MQ8T1-Read 3093 3021 SEQ1MQ8T1-Write 2497 2438 SEQ128KQ32T1-Read 3216 25129 SEQ128KQ32T1-Write 2436 19033 RND4KQ32T16-Read 1705 426291 RND4KQ32T16-Write 679 169671 RND4KQ1T11-Read 37 9336 RND4KQ1T1-Write 247 61768
ちなみにデータは/tmp/
に作られます。必要に応じて次のように削除しておきましょう。
$ rm /tmp/cdm
これを元に、それぞれのRAIDレベルの結果を調べてみます。ちなみに実際に実行した環境は次のようなマシンです。
機能 | メーカー | 型番 | 備考 |
---|---|---|---|
CPU | Intel | Core i9-12900 | 16C/ |
CPUクーラー | Noctua | NH-L9i-17xx | 空冷 |
メモリー | Crucial | CT2K32G4DFD832A | DDR4-3200 32GBx2 |
M/ |
ASRock | B660-ITX | ITX |
ストレージ | Crucial | P5 Plus 1TB | PCIe 4. |
GPU | Intel | UHD Graphics 770 | iGPU |
ちなみにこのマザーボードはPCIe 4.
RAIDなし
比較対象のために、ストレージが1台で単なるext4を使っているインスタンスも用意しておきましょう。
JOB MB/s IOPS SEQ1MQ8T1-Read 20888 20398 SEQ1MQ8T1-Write 5871 5733 SEQ128KQ32T1-Read 23617 184505 SEQ128KQ32T1-Write 6497 50756 RND4KQ32T16-Read 1249 312312 RND4KQ32T16-Write 583 145832 RND4KQ1T11-Read 158 39405 RND4KQ1T1-Write 124 31083
RAID 1
RAID 1は一般的に読み込みは2台並列に行えるので理論上ははやくなるのですが、実際のところは1台からしか読まないことも多く、そこまで良くはならないようです。それに対して書き込みは、両方に書かなければならない都合上、同程度か遅くなってしまいます。
書き込み結果も少し遅くなってしまうようです。
JOB MB/s IOPS SEQ1MQ8T1-Read 22599 22069 SEQ1MQ8T1-Write 4923 4808 SEQ128KQ32T1-Read 19065 148945 SEQ128KQ32T1-Write 4524 35341 RND4KQ32T16-Read 1164 290932 RND4KQ32T16-Write 345 86349 RND4KQ1T11-Read 153 38184 RND4KQ1T1-Write 116 28916
RAID 5
RAID 5は接続する台数分並列に読み書きできるので、理論的には台数が増えるほど高速になります。しかしながら今回は1個のストレージを仮想的に複数に見せているだけなので、その恩恵にはあずかれません。逆にパリティ計算が必要になった分だけソフトウェアRAIDの場合は遅くなるようです。
JOB MB/s IOPS SEQ1MQ8T1-Read 21313 20813 SEQ1MQ8T1-Write 2986 2916 SEQ128KQ32T1-Read 15697 122635 SEQ128KQ32T1-Write 3185 24885 RND4KQ32T16-Read 1201 300211 RND4KQ32T16-Write 214 53501 RND4KQ1T11-Read 154 38455 RND4KQ1T1-Write 59 14625
RAID 6
RAID 6もRAID 5と同様に理論的には台数が増えるほど高速になります。ただしソフトウェアRAIDな上に、今回の構成だとその高速化にはあずかれない点も同様です。むしろパリティの書き込みが増えている分、書き込みはRAID 5よりもさらに遅くなります。
JOB MB/s IOPS SEQ1MQ8T1-Read 21141 20645 SEQ1MQ8T1-Write 2544 2484 SEQ128KQ32T1-Read 13725 107225 SEQ128KQ32T1-Write 2114 16516 RND4KQ32T16-Read 1072 267993 RND4KQ32T16-Write 171 42741 RND4KQ1T11-Read 151 37803 RND4KQ1T1-Write 57 14242
RAID 10 (near2)
RAID 10のnear2については、読み込み程度はRAID 1と同程度、書き込みは台数が増えるほど高速になるもののRAID 0の半分程度というのが理論値です。
RAID 5や6に比べるとパリティ計算がない分だけ、書き込みの性能が向上しています。
JOB MB/s IOPS SEQ1MQ8T1-Read 19065 18618 SEQ1MQ8T1-Write 7468 7293 SEQ128KQ32T1-Read 16435 128401 SEQ128KQ32T1-Write 5607 43807 RND4KQ32T16-Read 1121 280154 RND4KQ32T16-Write 362 90621 RND4KQ1T11-Read 153 38202 RND4KQ1T1-Write 118 29425
まとめ
当然の結果ではありますが、単一のデバイスを仮想的に分割している以上、RAIDの高速化の恩恵は受けられません。RAID使わないほうがはやいという悲しい結果になりました。
とは言え、高速化は今回の目的ではありません。あくまで、RAID系の操作の習熟が目的です。まずはRAIDを使ったからといって極端に遅くなっているわけではないということだけわかれば十分でしょう。
次回はようやく、RAIDの鬼門であるリビルドにチャレンジしてみます。