過去の検証で、インライン重複排除ができるストレージの作成までは手段が確立している。
そして「おうち HCI」を目指すうえでどうしても必要となってくるのが、「All Flash でインライン重複排除ができるストレージサーバ」である。
普通に仮想イメージ上に作るだけなら楽だが、Hyper-V 上で Raw Device Mapping して作る場合、ちょっとだけ面倒だったので、本記事はそのメモとなる。
また、RAID Level の検証も合わせて実施したので、その備忘録である。
■まえがき
今まで書いてきた記事をもとに、仮想マシンのディスクイメージ置き場を作る手順である。
ただし、今までと違うのは、ストレージ用仮想マシンに SSD を Raw Device Mapping して RAID 設定を行うところである。
SSD で RAID を組む場合の要件などは理解しているつもりだが、パフォーマンス試験などを残していなかったため、それをメインに記録を残している。
また、実際の構築にあたっては、以下の記事の継ぎ接ぎとなっている。
【過去記事】Enterprise Linux で重複排除を使ってみる
【過去記事】おうち VMware ESXi 7.0 は HCI の夢を見るか
なお、エンタープライズ向けストレージほど素晴らしい物ではないのは当然である。
■本記事そのものの構成
・Hyper-V 上の設定
・SSD on mdraid の検証
・実際の構築
■構成
・Host Server
- Windows Server 2019
- Hyper-V 有効化済み
・Storage Server VM
- CPU 8Cores
- Memory 16GB
- OS-Disk 20GB
- Storage-SSD 480GB x4
■■■ Hyper-V 上の設定 ■■■
■ストレージサーバ用 VM へ物理ディスクの接続
仮想マシンに対して物理 SSD を接続する Raw Device Mapping を行う場合、ホスト OS から論理的に切り離す必要がある。
切り離しを実施することで、仮想マシンの設定からディスクを接続できるようになる。
・ホスト OS からの切り離し
・仮想マシン設定にて物理ディスクの接続
■■■ SSD on mdraid の検証■■■
■各 RAID レベルの比較
Linux Kernel の mdraid では、主に RAID0/1/4/5/6/10 がサポートされている。
今回は SSD が 4 本なので、利用可能な RAID レベルとしては RAID0/1/4/5/6/10 である。
また、オーバープロビジョニングを考慮し、480GB の SSD 1 つあたり 400GB の使用とする。
RAID Level | Capacity | Fault tolerance |
---|---|---|
RAID 4 | 1.2TB | 1 |
RAID 5 | 1.2TB | 1 |
RAID 6 | 800GB | 2 |
RAID 10 | 800GB | At least 1-drive failure |
■Block Discard の重要度
SSD を使ったストレージの場合、Trim/UNMAP を行って Block Discard を実施しないとパフォーマンスが劣化していく。
パフォーマンスの劣化を防ぐためにも、Block Discard は重要である。
Windows や Intel Rapid Storage Technology 等による一般的な RAID 構築手法だと RAID0 でのみ Trim がサポートされている。
Linux の場合は、Kernel 3.6 にて RAID1 環境での Trim サポート、Kernel 3.7 にて RAID4/5/6 環境での Trim サポートが付いたらしい。
この辺の調査は、過去の記事参照。
Linux Server に SSD を Software RAID (mdraid) で入れるときの確認ポイント
そのため、RAID 構築した状態で本当に Block Discard がされているのかを確認しておく。
■Trim/UNMAP など Block Discard 処理の確認方法
Block Discard 処理を可視化する方法として、Linux では SystemTap を用いることで可視化することができる。
[SH2の日記] SSDに対するBlock Discard/TRIMをSystemTapで可視化する
Linux Kernel にて blkdev_issue_discard が呼び出されたとき、何がどのブロックに対して Discard したのかをモニタリングすることで、可視化できるようだ。
今回はこちらの方法を使って確認する。
■SystemTap による Block Discard 処理の可視化をする準備
SystemTap を利用するには、kernel-debuginfo と kernel-debuginfo-common が必要になる。
参考:[Red Hat] 第2章 SystemTap の使用
CentOS の場合、http://debuginfo.centos.org/ に存在するため、こちらから持ってくる。
なお、本来は yum/dnf コマンドにてインストール可能なのだが、最新 Kernel の repodata が作成されていないためエラーとなる。
# yum install --enablerepo=base-debuginfo kernel-debuginfo-`uname -r`
CentOS-8 - Debuginfo 13 MB/s | 17 MB 00:01
Last metadata expiration check: 0:00:04 ago on Sun 04 Oct 2020 06:57:03 PM JST.
No match for argument: kernel-debuginfo-4.18.0-193.19.1.el8_2.x86_64
Error: Unable to find a match: kernel-debuginfo-4.18.0-193.19.1.el8_2.x86_64
そのため、手動でファイルをダウンロードしてインストールを行う。
# cd # mkdir ./systemtap # cd ./systemtap # wget -N http://debuginfo.centos.org/8/x86_64/Packages/kernel-debuginfo-`uname -r`.rpm http://debuginfo.centos.org/8/x86_64/Packages/kernel-debuginfo-common-x86_64-`uname -r`.rpm # yum install ./kernel-debuginfo-`uname -r`.rpm ./kernel-debuginfo-common-x86_64-`uname -r`.rpm Last metadata expiration check: 0:00:51 ago on Sun 04 Oct 2020 07:00:23 PM JST. Dependencies resolved. ========================================================================================== Package Arch Version Repository Size ========================================================================================== Installing: kernel-debuginfo x86_64 4.18.0-193.19.1.el8_2 @commandline 497 M kernel-debuginfo-common-x86_64 x86_64 4.18.0-193.19.1.el8_2 @commandline 57 M Transaction Summary ========================================================================================== Install 2 Packages Total size: 554 M Installed size: 2.9 G Is this ok [y/N]: y Downloading Packages: Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Running transaction Preparing : 1/1 Installing : kernel-debuginfo-common-x86_64-4.18.0-193.19.1.el8_2.x86_64 1/2 Installing : kernel-debuginfo-4.18.0-193.19.1.el8_2.x86_64 2/2 Running scriptlet: kernel-debuginfo-4.18.0-193.19.1.el8_2.x86_64 2/2 Verifying : kernel-debuginfo-4.18.0-193.19.1.el8_2.x86_64 1/2 Verifying : kernel-debuginfo-common-x86_64-4.18.0-193.19.1.el8_2.x86_64 2/2 Installed products updated. Installed: kernel-debuginfo-4.18.0-193.19.1.el8_2.x86_64 kernel-debuginfo-common-x86_64-4.18.0-193.19.1.el8_2.x86_64 Complete!
インストールが完了した後 SystemTap スクリプトを作成し、動作確認を行う。
# vi discard.stp
probe kernel.function("blkdev_issue_discard").return { printf("%s, sector=%d, nr_sects=%d, return=%d (%d - %d KiB)\n", execname(), $sector, $nr_sects, $return, $sector / 2, ($sector + $nr_sects) / 2 - 1); }
# stap discard.stp
SystemTap がエラーで終了しないことを確認した後に、別ターミナルにて「使っていないディスク」に向かって blkdiscard あたりしてみる。
# blkdiscard /dev/sdb
次のように出力されれば、問題なく Block Discard の可視化ができている。
blkdiscard, sector=0, nr_sects=937703088, return=0 (0 - 468851543 KiB)
■試験用 Software RAID の作成
試験として、RAID4/5/6/10 全ての種類を作成し、その後 Block Discard ができるか試す。
まずは、ディスク状況の確認から。
# fdisk -l
Disk /dev/sda: 20 GiB, 21474836480 bytes, 41943040 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x5a0fe596
Device Boot Start End Sectors Size Id Type
/dev/sda1 * 2048 4196351 4194304 2G 83 Linux
/dev/sda2 4196352 12584959 8388608 4G 82 Linux swap / Solaris
/dev/sda3 12584960 41943039 29358080 14G 83 Linux
Disk /dev/sdb: 447.1 GiB, 480103981056 bytes, 937703088 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/sdc: 447.1 GiB, 480103981056 bytes, 937703088 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/sdd: 447.1 GiB, 480103981056 bytes, 937703088 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/sde: 447.1 GiB, 480103981056 bytes, 937703088 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
sdb, sdc, sdd, sde が空ディスクのため、こちらを使って Software RAID の構築を行う。
Software RAID を作成する前に、Flash Translation Layer (FTL) が最適化されることを願ってディスクの全領域を Block Discard する。
# blkdiscard /dev/sdb # blkdiscard /dev/sdc # blkdiscard /dev/sdd # blkdiscard /dev/sde
SystemTap にて以下の出力があったため、各 SSD に無事 Block Discard が発行された模様。
blkdiscard, sector=0, nr_sects=937703088, return=0 (0 - 468851543 KiB) blkdiscard, sector=0, nr_sects=937703088, return=0 (0 - 468851543 KiB) blkdiscard, sector=0, nr_sects=937703088, return=0 (0 - 468851543 KiB) blkdiscard, sector=0, nr_sects=937703088, return=0 (0 - 468851543 KiB)
次に、Software RAID を作るためにパーティションの切り出しを行う。
# fdisk /dev/sdb Welcome to fdisk (util-linux 2.32.1). Changes will remain in memory only, until you decide to write them. Be careful before using the write command. Device does not contain a recognized partition table. Created a new DOS disklabel with disk identifier 0x2caf8b68. Command (m for help): n Partition type p primary (0 primary, 0 extended, 4 free) e extended (container for logical partitions) Select (default p): p Partition number (1-4, default 1): First sector (2048-937703087, default 2048): Last sector, +sectors or +size{K,M,G,T,P} (2048-937703087, default 937703087): +100G Created a new partition 1 of type 'Linux' and of size 100 GiB. Command (m for help): n Partition type p primary (1 primary, 0 extended, 3 free) e extended (container for logical partitions) Select (default p): p Partition number (2-4, default 2): First sector (209717248-937703087, default 209717248): Last sector, +sectors or +size{K,M,G,T,P} (209717248-937703087, default 937703087): +100G Created a new partition 2 of type 'Linux' and of size 100 GiB. Command (m for help): n Partition type p primary (2 primary, 0 extended, 2 free) e extended (container for logical partitions) Select (default p): p Partition number (3,4, default 3): First sector (419432448-937703087, default 419432448): Last sector, +sectors or +size{K,M,G,T,P} (419432448-937703087, default 937703087): +100G Created a new partition 3 of type 'Linux' and of size 100 GiB. Command (m for help): n Partition type p primary (3 primary, 0 extended, 1 free) e extended (container for logical partitions) Select (default e): p Selected partition 4 First sector (629147648-937703087, default 629147648): Last sector, +sectors or +size{K,M,G,T,P} (629147648-937703087, default 937703087): +100G Created a new partition 4 of type 'Linux' and of size 100 GiB. Command (m for help): t Partition number (1-4, default 4): 1 Hex code (type L to list all codes): fd Changed type of partition 'Linux' to 'Linux raid autodetect'. Command (m for help): t Partition number (1-4, default 4): 2 Hex code (type L to list all codes): fd Changed type of partition 'Linux' to 'Linux raid autodetect'. Command (m for help): t Partition number (1-4, default 4): 3 Hex code (type L to list all codes): fd Changed type of partition 'Linux' to 'Linux raid autodetect'. Command (m for help): t Partition number (1-4, default 4): 4 Hex code (type L to list all codes): fd Changed type of partition 'Linux' to 'Linux raid autodetect'. Command (m for help): p Disk /dev/sdb: 447.1 GiB, 480103981056 bytes, 937703088 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x2caf8b68 Device Boot Start End Sectors Size Id Type /dev/sdb1 2048 209717247 209715200 100G fd Linux raid autodetect /dev/sdb2 209717248 419432447 209715200 100G fd Linux raid autodetect /dev/sdb3 419432448 629147647 209715200 100G fd Linux raid autodetect /dev/sdb4 629147648 838862847 209715200 100G fd Linux raid autodetect Command (m for help): w The partition table has been altered. Calling ioctl() to re-read partition table. Syncing disks. # fdisk /dev/sdc Welcome to fdisk (util-linux 2.32.1). Changes will remain in memory only, until you decide to write them. Be careful before using the write command. Device does not contain a recognized partition table. Created a new DOS disklabel with disk identifier 0x9007f5bc. Command (m for help): n Partition type p primary (0 primary, 0 extended, 4 free) e extended (container for logical partitions) Select (default p): p Partition number (1-4, default 1): First sector (2048-937703087, default 2048): Last sector, +sectors or +size{K,M,G,T,P} (2048-937703087, default 937703087): +100G Created a new partition 1 of type 'Linux' and of size 100 GiB. Command (m for help): n Partition type p primary (1 primary, 0 extended, 3 free) e extended (container for logical partitions) Select (default p): p Partition number (2-4, default 2): First sector (209717248-937703087, default 209717248): Last sector, +sectors or +size{K,M,G,T,P} (209717248-937703087, default 937703087): +100G Created a new partition 2 of type 'Linux' and of size 100 GiB. Command (m for help): n Partition type p primary (2 primary, 0 extended, 2 free) e extended (container for logical partitions) Select (default p): p Partition number (3,4, default 3): First sector (419432448-937703087, default 419432448): Last sector, +sectors or +size{K,M,G,T,P} (419432448-937703087, default 937703087): +100G Created a new partition 3 of type 'Linux' and of size 100 GiB. Command (m for help): n Partition type p primary (3 primary, 0 extended, 1 free) e extended (container for logical partitions) Select (default e): p Selected partition 4 First sector (629147648-937703087, default 629147648): Last sector, +sectors or +size{K,M,G,T,P} (629147648-937703087, default 937703087): +100G Created a new partition 4 of type 'Linux' and of size 100 GiB. Command (m for help): t Partition number (1-4, default 4): 1 Hex code (type L to list all codes): fd Changed type of partition 'Linux' to 'Linux raid autodetect'. Command (m for help): t Partition number (1-4, default 4): 2 Hex code (type L to list all codes): fd Changed type of partition 'Linux' to 'Linux raid autodetect'. Command (m for help): t Partition number (1-4, default 4): 3 Hex code (type L to list all codes): fd Changed type of partition 'Linux' to 'Linux raid autodetect'. Command (m for help): t Partition number (1-4, default 4): 4 Hex code (type L to list all codes): fd Changed type of partition 'Linux' to 'Linux raid autodetect'. Command (m for help): p Disk /dev/sdc: 447.1 GiB, 480103981056 bytes, 937703088 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x9007f5bc Device Boot Start End Sectors Size Id Type /dev/sdc1 2048 209717247 209715200 100G fd Linux raid autodetect /dev/sdc2 209717248 419432447 209715200 100G fd Linux raid autodetect /dev/sdc3 419432448 629147647 209715200 100G fd Linux raid autodetect /dev/sdc4 629147648 838862847 209715200 100G fd Linux raid autodetect Command (m for help): w The partition table has been altered. Calling ioctl() to re-read partition table. Syncing disks. # fdisk /dev/sdd Welcome to fdisk (util-linux 2.32.1). Changes will remain in memory only, until you decide to write them. Be careful before using the write command. Device does not contain a recognized partition table. Created a new DOS disklabel with disk identifier 0x23adeb66. Command (m for help): n Partition type p primary (0 primary, 0 extended, 4 free) e extended (container for logical partitions) Select (default p): p Partition number (1-4, default 1): First sector (2048-937703087, default 2048): Last sector, +sectors or +size{K,M,G,T,P} (2048-937703087, default 937703087): +100G Created a new partition 1 of type 'Linux' and of size 100 GiB. Command (m for help): n Partition type p primary (1 primary, 0 extended, 3 free) e extended (container for logical partitions) Select (default p): p Partition number (2-4, default 2): First sector (209717248-937703087, default 209717248): Last sector, +sectors or +size{K,M,G,T,P} (209717248-937703087, default 937703087): +100G Created a new partition 2 of type 'Linux' and of size 100 GiB. Command (m for help): n Partition type p primary (2 primary, 0 extended, 2 free) e extended (container for logical partitions) Select (default p): p Partition number (3,4, default 3): First sector (419432448-937703087, default 419432448): Last sector, +sectors or +size{K,M,G,T,P} (419432448-937703087, default 937703087): +100G Created a new partition 3 of type 'Linux' and of size 100 GiB. Command (m for help): n Partition type p primary (3 primary, 0 extended, 1 free) e extended (container for logical partitions) Select (default e): p Selected partition 4 First sector (629147648-937703087, default 629147648): Last sector, +sectors or +size{K,M,G,T,P} (629147648-937703087, default 937703087): +100G Created a new partition 4 of type 'Linux' and of size 100 GiB. Command (m for help): t Partition number (1-4, default 4): 1 Hex code (type L to list all codes): fd Changed type of partition 'Linux' to 'Linux raid autodetect'. Command (m for help): t Partition number (1-4, default 4): 2 Hex code (type L to list all codes): fd Changed type of partition 'Linux' to 'Linux raid autodetect'. Command (m for help): t Partition number (1-4, default 4): 3 Hex code (type L to list all codes): fd Changed type of partition 'Linux' to 'Linux raid autodetect'. Command (m for help): t Partition number (1-4, default 4): 4 Hex code (type L to list all codes): fd Changed type of partition 'Linux' to 'Linux raid autodetect'. Command (m for help): p Disk /dev/sdd: 447.1 GiB, 480103981056 bytes, 937703088 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x23adeb66 Device Boot Start End Sectors Size Id Type /dev/sdd1 2048 209717247 209715200 100G fd Linux raid autodetect /dev/sdd2 209717248 419432447 209715200 100G fd Linux raid autodetect /dev/sdd3 419432448 629147647 209715200 100G fd Linux raid autodetect /dev/sdd4 629147648 838862847 209715200 100G fd Linux raid autodetect Command (m for help): w The partition table has been altered. Calling ioctl() to re-read partition table. Syncing disks. # fdisk /dev/sde Welcome to fdisk (util-linux 2.32.1). Changes will remain in memory only, until you decide to write them. Be careful before using the write command. Device does not contain a recognized partition table. Created a new DOS disklabel with disk identifier 0x2c205079. Command (m for help): n Partition type p primary (0 primary, 0 extended, 4 free) e extended (container for logical partitions) Select (default p): p Partition number (1-4, default 1): First sector (2048-937703087, default 2048): Last sector, +sectors or +size{K,M,G,T,P} (2048-937703087, default 937703087): +100G Created a new partition 1 of type 'Linux' and of size 100 GiB. Command (m for help): n Partition type p primary (1 primary, 0 extended, 3 free) e extended (container for logical partitions) Select (default p): p Partition number (2-4, default 2): First sector (209717248-937703087, default 209717248): Last sector, +sectors or +size{K,M,G,T,P} (209717248-937703087, default 937703087): +100G Created a new partition 2 of type 'Linux' and of size 100 GiB. Command (m for help): n Partition type p primary (2 primary, 0 extended, 2 free) e extended (container for logical partitions) Select (default p): p Partition number (3,4, default 3): First sector (419432448-937703087, default 419432448): Last sector, +sectors or +size{K,M,G,T,P} (419432448-937703087, default 937703087): +100G Created a new partition 3 of type 'Linux' and of size 100 GiB. Command (m for help): n Partition type p primary (3 primary, 0 extended, 1 free) e extended (container for logical partitions) Select (default e): p Selected partition 4 First sector (629147648-937703087, default 629147648): Last sector, +sectors or +size{K,M,G,T,P} (629147648-937703087, default 937703087): +100G Created a new partition 4 of type 'Linux' and of size 100 GiB. Command (m for help): t Partition number (1-4, default 4): 1 Hex code (type L to list all codes): fd Changed type of partition 'Linux' to 'Linux raid autodetect'. Command (m for help): t Partition number (1-4, default 4): 2 Hex code (type L to list all codes): fd Changed type of partition 'Linux' to 'Linux raid autodetect'. Command (m for help): t Partition number (1-4, default 4): 3 Hex code (type L to list all codes): fd Changed type of partition 'Linux' to 'Linux raid autodetect'. Command (m for help): t Partition number (1-4, default 4): 4 Hex code (type L to list all codes): fd Changed type of partition 'Linux' to 'Linux raid autodetect'. Command (m for help): p Disk /dev/sde: 447.1 GiB, 480103981056 bytes, 937703088 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x2c205079 Device Boot Start End Sectors Size Id Type /dev/sde1 2048 209717247 209715200 100G fd Linux raid autodetect /dev/sde2 209717248 419432447 209715200 100G fd Linux raid autodetect /dev/sde3 419432448 629147647 209715200 100G fd Linux raid autodetect /dev/sde4 629147648 838862847 209715200 100G fd Linux raid autodetect Command (m for help): w The partition table has been altered. Calling ioctl() to re-read partition table. Syncing disks.
パーティションの状況を確認。
# fdisk -l Disk /dev/sda: 20 GiB, 21474836480 bytes, 41943040 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x5a0fe596 Device Boot Start End Sectors Size Id Type /dev/sda1 * 2048 4196351 4194304 2G 83 Linux /dev/sda2 4196352 12584959 8388608 4G 82 Linux swap / Solaris /dev/sda3 12584960 41943039 29358080 14G 83 Linux Disk /dev/sdd: 447.1 GiB, 480103981056 bytes, 937703088 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x23adeb66 Device Boot Start End Sectors Size Id Type /dev/sdd1 2048 209717247 209715200 100G fd Linux raid autodetect /dev/sdd2 209717248 419432447 209715200 100G fd Linux raid autodetect /dev/sdd3 419432448 629147647 209715200 100G fd Linux raid autodetect /dev/sdd4 629147648 838862847 209715200 100G fd Linux raid autodetect Disk /dev/sdc: 447.1 GiB, 480103981056 bytes, 937703088 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x9007f5bc Device Boot Start End Sectors Size Id Type /dev/sdc1 2048 209717247 209715200 100G fd Linux raid autodetect /dev/sdc2 209717248 419432447 209715200 100G fd Linux raid autodetect /dev/sdc3 419432448 629147647 209715200 100G fd Linux raid autodetect /dev/sdc4 629147648 838862847 209715200 100G fd Linux raid autodetect Disk /dev/sdb: 447.1 GiB, 480103981056 bytes, 937703088 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x2caf8b68 Device Boot Start End Sectors Size Id Type /dev/sdb1 2048 209717247 209715200 100G fd Linux raid autodetect /dev/sdb2 209717248 419432447 209715200 100G fd Linux raid autodetect /dev/sdb3 419432448 629147647 209715200 100G fd Linux raid autodetect /dev/sdb4 629147648 838862847 209715200 100G fd Linux raid autodetect Disk /dev/sde: 447.1 GiB, 480103981056 bytes, 937703088 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x2c205079 Device Boot Start End Sectors Size Id Type /dev/sde1 2048 209717247 209715200 100G fd Linux raid autodetect /dev/sde2 209717248 419432447 209715200 100G fd Linux raid autodetect /dev/sde3 419432448 629147647 209715200 100G fd Linux raid autodetect /dev/sde4 629147648 838862847 209715200 100G fd Linux raid autodetect
sdb ~ sde に対して、パーティション 1 ~ 4 まで 100GB ずつ作成されたことを確認できたので、Software RAID を作成する。
# mdadm --create /dev/md0 --level=raid4 --raid-devices=4 /dev/sdb1 /dev/sdc1 /dev/sdd1 /dev/sde1 mdadm: Defaulting to version 1.2 metadata mdadm: array /dev/md0 started. # mdadm --create /dev/md1 --level=raid5 --raid-devices=4 /dev/sdb2 /dev/sdc2 /dev/sdd2 /dev/sde2 mdadm: Defaulting to version 1.2 metadata mdadm: array /dev/md1 started. # mdadm --create /dev/md2 --level=raid6 --raid-devices=4 /dev/sdb3 /dev/sdc3 /dev/sdd3 /dev/sde3 mdadm: Defaulting to version 1.2 metadata mdadm: array /dev/md2 started. # mdadm --create /dev/md3 --level=raid10 --raid-devices=4 /dev/sdb4 /dev/sdc4 /dev/sdd4 /dev/sde4 mdadm: Defaulting to version 1.2 metadata mdadm: array /dev/md3 started.
作成された Software RAID を確認する。
# cat /proc/mdstat Personalities : [raid6] [raid5] [raid4] [raid10] md3 : active raid10 sde4[3] sdd4[2] sdc4[1] sdb4[0] 209582080 blocks super 1.2 512K chunks 2 near-copies [4/4] [UUUU] md2 : active raid6 sde3[3] sdd3[2] sdc3[1] sdb3[0] 209582080 blocks super 1.2 level 6, 512k chunk, algorithm 2 [4/4] [UUUU] md1 : active raid5 sde2[4] sdd2[2] sdc2[1] sdb2[0] 314373120 blocks super 1.2 level 5, 512k chunk, algorithm 2 [4/4] [UUUU] md0 : active raid4 sde1[4] sdd1[2] sdc1[1] sdb1[0] 314373120 blocks super 1.2 level 4, 512k chunk, algorithm 0 [4/4] [UUUU] unused devices:
問題なく作成されたようだ・w・
■Block Discard の有効化確認
作成された Software RAID の md Device に対して、Block Discard を発行してみる。
# blkdiscard /dev/md0 blkdiscard: /dev/md0: BLKDISCARD ioctl failed: Operation not supported # blkdiscard /dev/md1 blkdiscard: /dev/md1: BLKDISCARD ioctl failed: Operation not supported # blkdiscard /dev/md2 blkdiscard: /dev/md2: BLKDISCARD ioctl failed: Operation not supported # blkdiscard /dev/md3
RAID 4/5/6 では、Block Discard が動かなかった。
なお、SystemTap の出力も、RAID10 でのみ以下の出力があった。
blkdiscard, sector=0, nr_sects=419164160, return=0 (0 - 209582079 KiB)
■RAID 4/5/6 における Block Discard の有効化
Linux Kernel のソースコードを確認してみた結果、RHEL に置いては追加の設定が必要ということが分かった。
まずは Linux Kernel 内にある mdraid RAID5 のコードにて「Discard」を検索すると、【 devices_handle_discard_safely 】というものが見つかる。
[Linux Kernel] raid5.c
devices_handle_discard_safely で検索していくと、Red Hat のドキュメントが見つかる
[Red Hat] 第21章 ソリッドステートディスクの導入ガイドライン
確認してみたところ、私が過去に書いた記事の通り Read Zero after TRIM の SSD を使わないと危険であるため、デフォルトでは RAID4/5/6 にて Block Discard ができないようになっているそうだ。
今回使ったディスクは Samsung PM863a MZ7LM480HMHQ であるため、RZAT に対応しているので、有効化処理を行う。
# vi /etc/modprobe.d/raid456.conf
options raid456 devices_handle_discard_safely=Y
# dracut -f # reboot
リブート後、Block Discard を再び試してみると、今度はエラーが発生せずに無事 Block Discard が実行できた。
# blkdiscard /dev/md0 # blkdiscard /dev/md1 # blkdiscard /dev/md2 # blkdiscard /dev/md3
SystemTap 上でも、無事に Block Discard が発行されている様子が確認できた。
blkdiscard, sector=0, nr_sects=628746240, return=0 (0 - 314373119 KiB) blkdiscard, sector=0, nr_sects=628746240, return=0 (0 - 314373119 KiB) blkdiscard, sector=0, nr_sects=419164160, return=0 (0 - 209582079 KiB) blkdiscard, sector=0, nr_sects=419164160, return=0 (0 - 209582079 KiB)
■md Device 上に作成した ext4 Filesystem 上で Block Discard が有効であることを確認
まずは各 md Device 上に ext4 Filesystem を作成する。
# mkfs -t ext4 /dev/md0 mke2fs 1.45.4 (23-Sep-2019) Discarding device blocks: done Creating filesystem with 78593280 4k blocks and 19652608 inodes Filesystem UUID: 23b6b4dc-7ab1-4dbf-ba6b-d592c6e5a9ee Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000, 7962624, 11239424, 20480000, 23887872, 71663616 Allocating group tables: done Writing inode tables: done Creating journal (262144 blocks): done Writing superblocks and filesystem accounting information: done # mkfs -t ext4 /dev/md1 mke2fs 1.45.4 (23-Sep-2019) Discarding device blocks: done Creating filesystem with 78593280 4k blocks and 19652608 inodes Filesystem UUID: bcdead1e-f403-4fda-b387-a6c28e50b988 Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000, 7962624, 11239424, 20480000, 23887872, 71663616 Allocating group tables: done Writing inode tables: done Creating journal (262144 blocks): done Writing superblocks and filesystem accounting information: done # mkfs -t ext4 /dev/md2 mke2fs 1.45.4 (23-Sep-2019) Discarding device blocks: done Creating filesystem with 52395520 4k blocks and 13099008 inodes Filesystem UUID: 44551a84-1407-41e3-a76a-007b27c2bf87 Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000, 7962624, 11239424, 20480000, 23887872 Allocating group tables: done Writing inode tables: done Creating journal (262144 blocks): done Writing superblocks and filesystem accounting information: done # mkfs -t ext4 /dev/md3 mke2fs 1.45.4 (23-Sep-2019) Discarding device blocks: done Creating filesystem with 52395520 4k blocks and 13099008 inodes Filesystem UUID: 382c87f1-98c6-4726-a640-b51e12727757 Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000, 7962624, 11239424, 20480000, 23887872 Allocating group tables: done Writing inode tables: done Creating journal (262144 blocks): done Writing superblocks and filesystem accounting information: done
ext4 Filesystem 作成中に Block Discard の結果が SystemTap により出力される。
mkfs.ext4, sector=0, nr_sects=32768, return=0 (0 - 16383 KiB) mkfs.ext4, sector=32768, nr_sects=4194304, return=0 (16384 - 2113535 KiB) mkfs.ext4, sector=4227072, nr_sects=4194304, return=0 (2113536 - 4210687 KiB) ... snip ... mkfs.ext4, sector=616595456, nr_sects=4194304, return=0 (308297728 - 310394879 KiB) mkfs.ext4, sector=620789760, nr_sects=4194304, return=0 (310394880 - 312492031 KiB) mkfs.ext4, sector=624984064, nr_sects=3762176, return=0 (312492032 - 314373119 KiB) mkfs.ext4, sector=0, nr_sects=32768, return=0 (0 - 16383 KiB) mkfs.ext4, sector=32768, nr_sects=4194304, return=0 (16384 - 2113535 KiB) mkfs.ext4, sector=4227072, nr_sects=4194304, return=0 (2113536 - 4210687 KiB) ... snip ... mkfs.ext4, sector=616595456, nr_sects=4194304, return=0 (308297728 - 310394879 KiB) mkfs.ext4, sector=620789760, nr_sects=4194304, return=0 (310394880 - 312492031 KiB) mkfs.ext4, sector=624984064, nr_sects=3762176, return=0 (312492032 - 314373119 KiB) mkfs.ext4, sector=0, nr_sects=32768, return=0 (0 - 16383 KiB) mkfs.ext4, sector=32768, nr_sects=4194304, return=0 (16384 - 2113535 KiB) mkfs.ext4, sector=4227072, nr_sects=4194304, return=0 (2113536 - 4210687 KiB) ... snip ... mkfs.ext4, sector=406880256, nr_sects=4194304, return=0 (203440128 - 205537279 KiB) mkfs.ext4, sector=411074560, nr_sects=4194304, return=0 (205537280 - 207634431 KiB) mkfs.ext4, sector=415268864, nr_sects=3895296, return=0 (207634432 - 209582079 KiB) mkfs.ext4, sector=0, nr_sects=32768, return=0 (0 - 16383 KiB) mkfs.ext4, sector=32768, nr_sects=4194304, return=0 (16384 - 2113535 KiB) mkfs.ext4, sector=4227072, nr_sects=4194304, return=0 (2113536 - 4210687 KiB) ... snip ... mkfs.ext4, sector=406880256, nr_sects=4194304, return=0 (203440128 - 205537279 KiB) mkfs.ext4, sector=411074560, nr_sects=4194304, return=0 (205537280 - 207634431 KiB) mkfs.ext4, sector=415268864, nr_sects=3895296, return=0 (207634432 - 209582079 KiB)
マウントポイントを作成し、マウントの実行。
# mkdir /root/md0 # mkdir /root/md1 # mkdir /root/md2 # mkdir /root/md3 # mount /dev/md0 /root/md0 # mount /dev/md1 /root/md1 # mount /dev/md2 /root/md2 # mount /dev/md3 /root/md3
テストデータの書き込み。
# dd if=/dev/urandom of=/root/md0/random01.dat bs=1M status=progress & # dd if=/dev/urandom of=/root/md1/random01.dat bs=1M status=progress & # dd if=/dev/urandom of=/root/md2/random01.dat bs=1M status=progress & # dd if=/dev/urandom of=/root/md3/random01.dat bs=1M status=progress & # dd if=/dev/urandom of=/root/md0/random02.dat bs=1M status=progress & # dd if=/dev/urandom of=/root/md1/random02.dat bs=1M status=progress & # dd if=/dev/urandom of=/root/md2/random02.dat bs=1M status=progress & # dd if=/dev/urandom of=/root/md3/random02.dat bs=1M status=progress & # dd if=/dev/urandom of=/root/md0/random03.dat bs=1M status=progress & # dd if=/dev/urandom of=/root/md1/random03.dat bs=1M status=progress & # dd if=/dev/urandom of=/root/md2/random03.dat bs=1M status=progress & # dd if=/dev/urandom of=/root/md3/random03.dat bs=1M status=progress & # dd if=/dev/urandom of=/root/md0/random04.dat bs=1M status=progress & # dd if=/dev/urandom of=/root/md1/random04.dat bs=1M status=progress & # dd if=/dev/urandom of=/root/md2/random04.dat bs=1M status=progress & # dd if=/dev/urandom of=/root/md3/random04.dat bs=1M status=progress &
テストデータの消去。
# ls -la /root/md*/random01.dat -rw-r--r--. 1 root root 78964064256 Oct 04 17:31 /root/md0/random01.dat -rw-r--r--. 1 root root 78896955392 Oct 04 17:31 /root/md1/random01.dat -rw-r--r--. 1 root root 52465500160 Oct 04 16:56 /root/md2/random01.dat -rw-r--r--. 1 root root 52464451584 Oct 04 16:56 /root/md3/random01.dat # rm -f /root/md*/random01.dat # sync # fstrim -av /root/md3: 48.9 GiB (52478418944 bytes) trimmed /root/md2: 48.9 GiB (52454936576 bytes) trimmed /root/md1: 73.5 GiB (78900338688 bytes) trimmed /root/md0: 73.6 GiB (78972014592 bytes) trimmed /boot: 0 B (0 bytes) trimmed /: 0 B (0 bytes) trimmed
問題なく fstrim によって Block Discard が実行できた。
SystemTap からは 5000 行ほどの Block Discard の発行が検知されていたので、確実に実行された。
せっかくなので、ファイル消去と同時に Block Discard が実行されるモードも正常に動くことを確認したい。
まずは、アンマウント。
# umount /root/md0 # umount /root/md1 # umount /root/md2 # umount /root/md3
オプション discard を付与してマウントの実施。
# mount -o discard /dev/md0 /root/md0 # mount -o discard /dev/md1 /root/md1 # mount -o discard /dev/md2 /root/md2 # mount -o discard /dev/md3 /root/md3
マウント後に一度 fstrim を実行し、空き領域を Block Discard しておく。
# fstrim -av
/root/md3: 0 B (0 bytes) trimmed
/root/md2: 0 B (0 bytes) trimmed
/root/md1: 0 B (0 bytes) trimmed
/root/md0: 0 B (0 bytes) trimmed
/boot: 0 B (0 bytes) trimmed
/: 0 B (0 bytes) trimmed
テストデータの消去。
# ls -la /root/md*/random02.dat -rw-r--r--. 1 root root 78897737728 Oct 04 17:31 /root/md0/random02.dat -rw-r--r--. 1 root root 78950432768 Oct 04 17:31 /root/md1/random02.dat -rw-r--r--. 1 root root 52583989248 Oct 04 16:56 /root/md2/random02.dat -rw-r--r--. 1 root root 52529463296 Oct 04 16:56 /root/md3/random02.dat # rm -f /root/md*/random02.dat
何かバックグラウンドで処理が動いているようだが、SystemTap では何も出力されない。
そのため、fstrim をしてみる。
# fstrim -av
/root/md3: 0 B (0 bytes) trimmed
/root/md2: 20.1 GiB (21560033280 bytes) trimmed
/root/md1: 41.7 GiB (44744699904 bytes) trimmed
/root/md0: 54.4 GiB (58382602240 bytes) trimmed
/boot: 0 B (0 bytes) trimmed
/: 108.1 MiB (113344512 bytes) trimmed
どうやらバックグラウンドで Block Discard が動いていた模様。
fstrim 等で一気に実施するとパフォーマンスに影響があるためか、徐々に実施するようだ。
また、RHEL7 のときは SystemTap で観測できていたので、何か仕様が変わったようだ。
■Block Discard の有効化後における、データの整合性確認
Block Discard を実施後、RAID が正常に稼働していることを確認する。
手順としては、ひとつ前に実施した”md Device 上に作成した ext4 Filesystem 上で Block Discard が有効であることを確認”テストをしたものをそのまま使う。
各 RAID テストパターンに作られたファイルシステム上からファイルを削除し、実際に Block Discard が実行された後であるため、RAID 整合性試験を行うのにちょうどよいからだ。
まずは、各 md Device に対して、整合性チェックの指示。
# echo check > /sys/block/md0/md/sync_action # echo check > /sys/block/md1/md/sync_action # echo check > /sys/block/md2/md/sync_action # echo check > /sys/block/md3/md/sync_action
チェックが進行中であることを確認。
# cat /proc/mdstat Personalities : [raid10] [raid6] [raid5] [raid4] md2 : active raid6 sde3[3] sdd3[2] sdb3[0] sdc3[1] 209582080 blocks super 1.2 level 6, 512k chunk, algorithm 2 [4/4] [UUUU] resync=DELAYED md0 : active raid4 sde1[4] sdb1[0] sdd1[2] sdc1[1] 314373120 blocks super 1.2 level 4, 512k chunk, algorithm 0 [4/4] [UUUU] [=>...................] check = 6.1% (6489916/104791040) finish=4.2min speed=381759K/sec md1 : active raid5 sde2[4] sdb2[0] sdd2[2] sdc2[1] 314373120 blocks super 1.2 level 5, 512k chunk, algorithm 2 [4/4] [UUUU] resync=DELAYED md3 : active raid10 sde4[3] sdd4[2] sdc4[1] sdb4[0] 209582080 blocks super 1.2 512K chunks 2 near-copies [4/4] [UUUU] resync=DELAYED unused devices:
チェックの完了を Syslog にて確認。
Oct 4 21:32:18 sasya kernel: md: data-check of RAID array md0 Oct 4 21:32:20 sasya kernel: md: delaying data-check of md1 until md0 has finished (they share one or more physical units) Oct 4 21:32:22 sasya kernel: md: delaying data-check of md2 until md0 has finished (they share one or more physical units) Oct 4 21:32:22 sasya kernel: md: delaying data-check of md1 until md2 has finished (they share one or more physical units) Oct 4 21:32:24 sasya kernel: md: delaying data-check of md3 until md0 has finished (they share one or more physical units) Oct 4 21:37:19 sasya kernel: md: md0: data-check done. Oct 4 21:37:19 sasya kernel: md: delaying data-check of md2 until md3 has finished (they share one or more physical units) Oct 4 21:37:19 sasya kernel: md: data-check of RAID array md3 Oct 4 21:42:24 sasya kernel: md: md3: data-check done. Oct 4 21:42:24 sasya kernel: md: data-check of RAID array md2 Oct 4 21:48:08 sasya kernel: md: md2: data-check done. Oct 4 21:48:09 sasya kernel: md: data-check of RAID array md1 Oct 4 21:52:53 sasya kernel: md: md1: data-check done.
Software RAID ステータスを確認。
# cat /proc/mdstat Personalities : [raid10] [raid6] [raid5] [raid4] md2 : active raid6 sde3[3] sdd3[2] sdb3[0] sdc3[1] 209582080 blocks super 1.2 level 6, 512k chunk, algorithm 2 [4/4] [UUUU] md0 : active raid4 sde1[4] sdb1[0] sdd1[2] sdc1[1] 314373120 blocks super 1.2 level 4, 512k chunk, algorithm 0 [4/4] [UUUU] md1 : active raid5 sde2[4] sdb2[0] sdd2[2] sdc2[1] 314373120 blocks super 1.2 level 5, 512k chunk, algorithm 2 [4/4] [UUUU] md3 : active raid10 sde4[3] sdd4[2] sdc4[1] sdb4[0] 209582080 blocks super 1.2 512K chunks 2 near-copies [4/4] [UUUU] unused devices:
md Device 的に問題がないため、アンマウントを実施した後に Filesystem の整合性チェックの実行。
# umount /root/md0 # umount /root/md1 # umount /root/md2 # umount /root/md3 # fsck /dev/md0 fsck from util-linux 2.32.1 e2fsck 1.45.4 (23-Sep-2019) /dev/md0: clean, 12/19652608 files, 20785720/78593280 blocks # fsck /dev/md1 fsck from util-linux 2.32.1 e2fsck 1.45.4 (23-Sep-2019) /dev/md1: clean, 12/19652608 files, 20785464/78593280 blocks # fsck /dev/md2 fsck from util-linux 2.32.1 e2fsck 1.45.4 (23-Sep-2019) /dev/md2: clean, 12/13099008 files, 13928205/52395520 blocks # fsck /dev/md3 fsck from util-linux 2.32.1 e2fsck 1.45.4 (23-Sep-2019) /dev/md3: clean, 12/13099008 files, 13933583/52395520 blocks
最後に、Block Device としてエラーが無いかを badblocks の Read Only Test にて確認。
# badblocks -sv /dev/md0 -c 32768 Checking blocks 0 to 314373119 Checking for bad blocks (read-only test): done Pass completed, 0 bad blocks found. (0/0/0 errors) # badblocks -sv /dev/md1 -c 32768 Checking blocks 0 to 314373119 Checking for bad blocks (read-only test): done Pass completed, 0 bad blocks found. (0/0/0 errors) # badblocks -sv /dev/md2 -c 32768 Checking blocks 0 to 209582079 Checking for bad blocks (read-only test): done Pass completed, 0 bad blocks found. (0/0/0 errors) # badblocks -sv /dev/md3 -c 32768 Checking blocks 0 to 209582079 Checking for bad blocks (read-only test): done Pass completed, 0 bad blocks found. (0/0/0 errors)
結果、問題がなかったと判断できた。
■速度確認
何も考えず、Disk Dump で Zero を書き込み、その後読み込む。
ベンチマークソフト使うべきなのはわかるけど、殆どの場合 Page Cache が効いてしまうので、Cache 無効にできる Disk Dump のほうが素直に感じたのでこの手法で試す。
# dd if=/dev/zero of=/dev/md0 bs=1G oflag=direct status=progress 321048805376 bytes (321 GB, 299 GiB) copied, 557 s, 577 MB/s dd: error writing '/dev/md0': No space left on device 300+0 records in 299+0 records out 321918074880 bytes (322 GB, 300 GiB) copied, 558.491 s, 576 MB/s # dd if=/dev/zero of=/dev/md1 bs=1G oflag=direct status=progress 321048805376 bytes (321 GB, 299 GiB) copied, 590 s, 544 MB/s dd: error writing '/dev/md1': No space left on device 300+0 records in 299+0 records out 321918074880 bytes (322 GB, 300 GiB) copied, 591.578 s, 544 MB/s # dd if=/dev/zero of=/dev/md2 bs=1G oflag=direct status=progress 213674622976 bytes (214 GB, 199 GiB) copied, 493 s, 433 MB/s dd: error writing '/dev/md2': No space left on device 200+0 records in 199+0 records out 214612049920 bytes (215 GB, 200 GiB) copied, 495.475 s, 433 MB/s # dd if=/dev/zero of=/dev/md3 bs=1G oflag=direct status=progress 213674622976 bytes (214 GB, 199 GiB) copied, 387 s, 552 MB/s dd: error writing '/dev/md3': No space left on device 200+0 records in 199+0 records out 214612049920 bytes (215 GB, 200 GiB) copied, 389.045 s, 552 MB/s # dd if=/dev/md0 of=/dev/null bs=1G status=progress 321048805376 bytes (321 GB, 299 GiB) copied, 207 s, 1.5 GB/s 299+1 records in 299+1 records out 321918074880 bytes (322 GB, 300 GiB) copied, 211.475 s, 1.5 GB/s # dd if=/dev/md1 of=/dev/null bs=1G status=progress 321048805376 bytes (321 GB, 299 GiB) copied, 208 s, 1.5 GB/s 299+1 records in 299+1 records out 321918074880 bytes (322 GB, 300 GiB) copied, 212.563 s, 1.5 GB/s # dd if=/dev/md2 of=/dev/null bs=1G status=progress 213674622976 bytes (214 GB, 199 GiB) copied, 140 s, 1.5 GB/s 199+1 records in 199+1 records out 214612049920 bytes (215 GB, 200 GiB) copied, 144.594 s, 1.5 GB/s # dd if=/dev/md3 of=/dev/null bs=1G status=progress 214612049920 bytes (215 GB, 200 GiB) copied, 139 s, 1.5 GB/s 199+1 records in 199+1 records out 214612049920 bytes (215 GB, 200 GiB) copied, 142.974 s, 1.5 GB/s
RAID Level | Read (MByte/Sec) | Write (MByte/Sec) |
---|---|---|
RAID 4 | 1522 | 577 |
RAID 5 | 1514 | 544 |
RAID 6 | 1486 | 433 |
RAID 10 | 1503 | 552 |
読み書き速度を見る限り、書き込み速度はどうも SSD そのものの速度に足を引っ張られているように見える。
iostat 1 -m 等でモニタリングしていても、md Device I/O には余裕がみられるが、SSD そのものである sdX 側は張り付いたままの様子。
これでは比較にならないので、I/O は発生しないが RAID として処理が発生する Block Discard の速度も調査する。
md Device に対して Block Discard を実行。
# time blkdiscard /dev/md0 real 2m15.833s user 0m0.001s sys 0m53.701s # time blkdiscard /dev/md1 real 2m17.624s user 0m0.001s sys 0m55.085s # time blkdiscard /dev/md2 real 2m2.712s user 0m0.000s sys 0m47.870s # time blkdiscard /dev/md3 real 2m52.710s user 0m0.001s sys 0m1.147s
どう判断すればいいんだこれ・x・?
Real はまあわかるが、 Sys が乖離しすぎている。
一応、SystemTap では、しっかり Block Discard が発行されているが・・・。
blkdiscard, sector=0, nr_sects=628746240, return=0 (0 - 314373119 KiB) blkdiscard, sector=0, nr_sects=628746240, return=0 (0 - 314373119 KiB) blkdiscard, sector=0, nr_sects=419164160, return=0 (0 - 209582079 KiB) blkdiscard, sector=0, nr_sects=419164160, return=0 (0 - 209582079 KiB)
一回で Discard 投げる量が多すぎる気がするため、ext4 Filesystem を作成し、その上で fstrim -v を実行して測定することにする。
追試験をするために、以下のようにパーティションを作成する。
# fdisk -l | grep md Disk /dev/md3: 199.9 GiB, 214612049920 bytes, 419164160 sectors /dev/md3p1 2048 209717247 209715200 100G 83 Linux Disk /dev/md1: 299.8 GiB, 321918074880 bytes, 628746240 sectors /dev/md1p1 3072 209719295 209716224 100G 83 Linux Disk /dev/md0: 299.8 GiB, 321918074880 bytes, 628746240 sectors /dev/md0p1 3072 209719295 209716224 100G 83 Linux Disk /dev/md2: 199.9 GiB, 214612049920 bytes, 419164160 sectors /dev/md2p1 2048 209717247 209715200 100G 83 Linux
各パーティションに、ext4 Filesystem を作成する。
# time mkfs -t ext4 /dev/md0p1 mke2fs 1.45.4 (23-Sep-2019) Discarding device blocks: done Creating filesystem with 26214400 4k blocks and 6566400 inodes Filesystem UUID: bd2de3ca-093d-4818-80e5-ea67f396734a Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000, 7962624, 11239424, 20480000, 23887872 Allocating group tables: done Writing inode tables: done Creating journal (131072 blocks): done Writing superblocks and filesystem accounting information: done real 0m49.741s user 0m0.010s sys 0m19.423s # time mkfs -t ext4 /dev/md1p1 mke2fs 1.45.4 (23-Sep-2019) Discarding device blocks: done Creating filesystem with 26214400 4k blocks and 6566400 inodes Filesystem UUID: 6bbc758e-f5d7-4790-918b-4827a848eb77 Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000, 7962624, 11239424, 20480000, 23887872 Allocating group tables: done Writing inode tables: done Creating journal (131072 blocks): done Writing superblocks and filesystem accounting information: done real 0m50.821s user 0m0.007s sys 0m20.563s # time mkfs -t ext4 /dev/md2p1 mke2fs 1.45.4 (23-Sep-2019) Discarding device blocks: done Creating filesystem with 26214400 4k blocks and 6553600 inodes Filesystem UUID: 08706b6c-9507-4879-a161-121ec9b1987f Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000, 7962624, 11239424, 20480000, 23887872 Allocating group tables: done Writing inode tables: done Creating journal (131072 blocks): done Writing superblocks and filesystem accounting information: done real 1m6.767s user 0m0.006s sys 0m24.637s # time mkfs -t ext4 /dev/md3p1 mke2fs 1.45.4 (23-Sep-2019) Discarding device blocks: done Creating filesystem with 26214400 4k blocks and 6553600 inodes Filesystem UUID: 980407a5-dc3a-43af-ae94-bf896a1a5748 Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000, 7962624, 11239424, 20480000, 23887872 Allocating group tables: done Writing inode tables: done Creating journal (131072 blocks): done Writing superblocks and filesystem accounting information: done real 0m1.561s user 0m0.003s sys 0m0.284s
もうこの時点で、答えは見えてしまっているが、一応試験継続する。
マウントの実施。
# mount /dev/md0p1 /root/md0 # mount /dev/md1p1 /root/md1 # mount /dev/md2p1 /root/md2 # mount /dev/md3p1 /root/md3
ext4 Filesystem に対して Block Discard の実施。
# time fstrim -v /root/md0 /root/md0: 97.9 GiB (105085960192 bytes) trimmed real 0m47.667s user 0m0.002s sys 0m12.520s # time fstrim -v /root/md1 /root/md1: 97.9 GiB (105085960192 bytes) trimmed real 0m48.620s user 0m0.001s sys 0m13.596s # time fstrim -v /root/md2 /root/md2: 97.9 GiB (105089236992 bytes) trimmed real 1m7.436s user 0m0.002s sys 0m20.157s # time fstrim -v /root/md3 /root/md3: 97.9 GiB (105089236992 bytes) trimmed real 0m9.499s user 0m0.004s sys 0m0.313s
これらの結果を見るに、どうも blkdiscard で md Device を直接 Block Discard した場合、時間がかかるようだ。
fstrim にて Filesystem を Block Discard した場合は、それなりの速度で動く模様。
また、top で観測していると、md0_raid4, md1_raid5, md2_raid6, md3_raid10 というプロセスの負荷が sys に該当している様子。
そうなると、sys が一番少ない RAID10 が最も負荷が低いということになる。
違いを探してみたら、Kernel から認識されてる Block Discard に関する情報が問題に思えてきた。
# more /sys/block/sd[b,c,d,e]/queue/discard_* :::::::::::::: /sys/block/sdb/queue/discard_granularity :::::::::::::: 512 :::::::::::::: /sys/block/sdb/queue/discard_max_bytes :::::::::::::: 4294966784 :::::::::::::: /sys/block/sdb/queue/discard_max_hw_bytes :::::::::::::: 4294966784 :::::::::::::: /sys/block/sdb/queue/discard_zeroes_data :::::::::::::: 0 :::::::::::::: /sys/block/sdc/queue/discard_granularity :::::::::::::: 512 :::::::::::::: /sys/block/sdc/queue/discard_max_bytes :::::::::::::: 4294966784 :::::::::::::: /sys/block/sdc/queue/discard_max_hw_bytes :::::::::::::: 4294966784 :::::::::::::: /sys/block/sdc/queue/discard_zeroes_data :::::::::::::: 0 :::::::::::::: /sys/block/sdd/queue/discard_granularity :::::::::::::: 512 :::::::::::::: /sys/block/sdd/queue/discard_max_bytes :::::::::::::: 4294966784 :::::::::::::: /sys/block/sdd/queue/discard_max_hw_bytes :::::::::::::: 4294966784 :::::::::::::: /sys/block/sdd/queue/discard_zeroes_data :::::::::::::: 0 :::::::::::::: /sys/block/sde/queue/discard_granularity :::::::::::::: 512 :::::::::::::: /sys/block/sde/queue/discard_max_bytes :::::::::::::: 4294966784 :::::::::::::: /sys/block/sde/queue/discard_max_hw_bytes :::::::::::::: 4294966784 :::::::::::::: /sys/block/sde/queue/discard_zeroes_data :::::::::::::: 0 # more /sys/block/md[0,1,2,3]/queue/discard_* :::::::::::::: /sys/block/md0/queue/discard_granularity :::::::::::::: 2097152 :::::::::::::: /sys/block/md0/queue/discard_max_bytes :::::::::::::: 4294966784 :::::::::::::: /sys/block/md0/queue/discard_max_hw_bytes :::::::::::::: 4294966784 :::::::::::::: /sys/block/md0/queue/discard_zeroes_data :::::::::::::: 0 :::::::::::::: /sys/block/md1/queue/discard_granularity :::::::::::::: 2097152 :::::::::::::: /sys/block/md1/queue/discard_max_bytes :::::::::::::: 4294966784 :::::::::::::: /sys/block/md1/queue/discard_max_hw_bytes :::::::::::::: 4294966784 :::::::::::::: /sys/block/md1/queue/discard_zeroes_data :::::::::::::: 0 :::::::::::::: /sys/block/md2/queue/discard_granularity :::::::::::::: 1048576 :::::::::::::: /sys/block/md2/queue/discard_max_bytes :::::::::::::: 4294966784 :::::::::::::: /sys/block/md2/queue/discard_max_hw_bytes :::::::::::::: 4294966784 :::::::::::::: /sys/block/md2/queue/discard_zeroes_data :::::::::::::: 0 :::::::::::::: /sys/block/md3/queue/discard_granularity :::::::::::::: 512 :::::::::::::: /sys/block/md3/queue/discard_max_bytes :::::::::::::: 524288 :::::::::::::: /sys/block/md3/queue/discard_max_hw_bytes :::::::::::::: 524288 :::::::::::::: /sys/block/md3/queue/discard_zeroes_data :::::::::::::: 0
この辺のチューニングとかできないかといくつか試してみたものの、現時点では解決できなかった。
mdadm にて md Device を作成するときの chunk サイズをいろいろ試したものの、劇的に改善はしなかった。
なお RAID1 の場合は、Raw Device と同等の速度で Block Discard が実行できた。
■■■ 実際の構築 ■■■
■構成の確定
ディスク 2 本同時障害を考えると、RAID6 が一番良いと考える。
ただし、ファイルの削除が頻繁に行われる場合は、RAID10 のほうが良いように見えてくる。
容量を取るなら RAID5 がベストかもしれないが、一本壊れただけで後がなくなるのは怖い。
今回の用途は、仮想マシンのファイル置き場として VDO (Virtual Data Optimizer) も挟むため、負荷が少ない物を選びたい。
そのため今回は、RAID10 を採用することとした。
■テスト用 md Device の削除
まずは md Device の停止
# mdadm --misc --stop /dev/md3 mdadm: stopped /dev/md3 # mdadm --misc --stop /dev/md2 mdadm: stopped /dev/md2 # mdadm --misc --stop /dev/md1 mdadm: stopped /dev/md1 # mdadm --misc --stop /dev/md0 mdadm: stopped /dev/md0
次に、使っていたディスクの初期化。Block Discard を使って FTL の初期化を願う。
# blkdiscard /dev/sdb # blkdiscard /dev/sdc # blkdiscard /dev/sdd # blkdiscard /dev/sde
■RAID10 md Device の作成
新しい RAID10 md Device 用パーティションの作成。
480GB の SSD なので、オーバープロビジョニングも考慮して、fdisk にて 400GB ずつパーティションを作成する。
作成した結果は以下の通り。
# fdisk -l | grep sd[b,c,d,e]
Disk /dev/sdb: 447.1 GiB, 480103981056 bytes, 937703088 sectors
/dev/sdb1 2048 838862847 838860800 400G fd Linux raid autodetect
Disk /dev/sdd: 447.1 GiB, 480103981056 bytes, 937703088 sectors
/dev/sdd1 2048 838862847 838860800 400G fd Linux raid autodetect
Disk /dev/sdc: 447.1 GiB, 480103981056 bytes, 937703088 sectors
/dev/sdc1 2048 838862847 838860800 400G fd Linux raid autodetect
Disk /dev/sde: 447.1 GiB, 480103981056 bytes, 937703088 sectors
/dev/sde1 2048 838862847 838860800 400G fd Linux raid autodetect
RAID10 md Device を作成する。
# mdadm --create /dev/md0 --level=raid10 --raid-devices=4 /dev/sdb1 /dev/sdc1 /dev/sdd1 /dev/sde1
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md0 started.
■VDO Volume の作成
今回は、作成した一つの md Device を利用する。
そのため、永続的な命名属性として、直接 /dev/md0 を利用してしまう。
RAID10 によりおよそ 800GB の md Device が作成されているため、実効容量 5 倍と雑に考えて 4TB の VDO Volume を作成する。
# vdo create \ --name=VDO-vol01 \ --device=/dev/md0 \ --sparseIndex=enabled --indexMem=0.25 \ --vdoLogicalSize=4T Creating VDO VDO-vol01 The VDO volume can address 776 GB in 388 data slabs, each 2 GB. It can grow to address at most 16 TB of physical storage in 8192 slabs. If a larger maximum size might be needed, use bigger slabs. Starting VDO VDO-vol01 Starting compression on VDO VDO-vol01 VDO instance 1 volume is ready at /dev/mapper/VDO-vol01 # fdisk -l /dev/mapper/VDO-vol01 Disk /dev/mapper/VDO-vol01: 4 TiB, 4398046511104 bytes, 1073741824 sectors Units: sectors of 1 * 4096 = 4096 bytes Sector size (logical/physical): 4096 bytes / 4096 bytes I/O size (minimum/optimal): 4096 bytes / 4096 bytes
■マウントポイント
VMware vSphere HA 向けハートビート データストア領域向けマウントポイントも作る必要があるため、マウントポイントは 3 つ作るとする。
/export/heartbeat1 Heartbeat 用 1 /export/heartbeat2 Heartbeat 用 2 /export/VDO-vol01 VDO Volume
上記要件を満たすようにするため、マウントポイントの作成する。
# mkdir -p /export/heartbeat1 # mkdir -p /export/heartbeat2 # mkdir -p /export/VDO-vol01
■Filesystem の作成とマウント
・VDO Volume に、ext4 Filesystem を作成
# mkfs.ext4 -E nodiscard /dev/mapper/VDO-vol01 mke2fs 1.45.4 (23-Sep-2019) Creating filesystem with 1073741824 4k blocks and 134217728 inodes Filesystem UUID: c376314f-ccd9-4023-a9c8-659a73dfa6a4 Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968, 102400000, 214990848, 512000000, 550731776, 644972544 Allocating group tables: done Writing inode tables: done Creating journal (262144 blocks): done Writing superblocks and filesystem accounting information: done
・マウント回数や最終 fsck から経過時間でのオート fsck を OFF にする
# tune2fs -c 0 -i 0 /dev/mapper/VDO-vol01 tune2fs 1.45.4 (23-Sep-2019) Setting maximal mount count to -1 Setting interval between checks to 0 seconds
・VDO Volume をマウント
# mkdir -p /export/VDO-vol01 # cp -piav /etc/fstab /etc/fstab.org # ls -la /etc/fstab* # echo "/dev/mapper/VDO-vol01 /export/VDO-vol01 ext4 defaults,_netdev,x-systemd.device-timeout=0,x-systemd.requires=vdo.service 0 0" >> /etc/fstab # diff /etc/fstab.org /etc/fstab # mount -a # mount # mount | grep VDO-vol01 /dev/mapper/VDO-vol01 on /export/VDO-vol01 type ext4 (rw,relatime,seclabel,_netdev,x-systemd.device-timeout=0) # df -h /export/VDO-vol01 Filesystem Size Used Avail Use% Mounted on /dev/mapper/VDO-vol01 4.0T 89M 3.8T 1% /export/VDO-vol01
システム起動時に自動的にマウントさせるため、/etc/fstab に追記する。ただし、VDO ボリュームの場合、vdo.service が起動する前にはマウントすることができないため、上記のように requires=vdo を付与する必要がある。
参考:VDO ボリュームのマウント
・初回ブロック破棄(discard)の実施
# fstrim -av
/export/VDO-vol01: 4 TiB (4362206064640 bytes) trimmed
かかる時間は CPU の性能に左右されます。
・定期的なブロック破棄(discard)の有効化
# systemctl enable --now fstrim.timer
これを仕込むことで、/usr/sbin/fstrim -av が週に一度動くようになる。
・VMware vSphere HA 向けハートビート データストア領域の作成
# dd if=/dev/zero of=/export/heartbeat1.img bs=1G count=1 1+0 records in 1+0 records out 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 1.16528 s, 921 MB/s # dd if=/dev/zero of=/export/heartbeat2.img bs=1G count=1 1+0 records in 1+0 records out 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 1.2624 s, 851 MB/s # mkfs -t ext4 /export/heartbeat1.img mke2fs 1.45.4 (23-Sep-2019) Discarding device blocks: done Creating filesystem with 262144 4k blocks and 65536 inodes Filesystem UUID: c50ccc72-21ed-4662-a859-fdb9d01f3989 Superblock backups stored on blocks: 32768, 98304, 163840, 229376 Allocating group tables: done Writing inode tables: done Creating journal (8192 blocks): done Writing superblocks and filesystem accounting information: done # mkfs -t ext4 /export/heartbeat2.img mke2fs 1.45.4 (23-Sep-2019) Discarding device blocks: done Creating filesystem with 262144 4k blocks and 65536 inodes Filesystem UUID: 9f0a7644-fca4-4b89-bf01-519f970de954 Superblock backups stored on blocks: 32768, 98304, 163840, 229376 Allocating group tables: done Writing inode tables: done Creating journal (8192 blocks): done Writing superblocks and filesystem accounting information: done # tune2fs -c 0 -i 0 /export/heartbeat1.img tune2fs 1.45.4 (23-Sep-2019) Setting maximal mount count to -1 Setting interval between checks to 0 seconds # tune2fs -c 0 -i 0 /export/heartbeat2.img tune2fs 1.45.4 (23-Sep-2019) Setting maximal mount count to -1 Setting interval between checks to 0 seconds # echo "/export/heartbeat1.img /export/heartbeat1 ext4 defaults 0 0" >> /etc/fstab # echo "/export/heartbeat2.img /export/heartbeat2 ext4 defaults 0 0" >> /etc/fstab # mount -a # mount # mount | grep heartbeat /export/heartbeat1.img on /export/heartbeat1 type ext4 (rw,relatime,seclabel) /export/heartbeat2.img on /export/heartbeat2 type ext4 (rw,relatime,seclabel) # df -h /export/heartbeat[1,2] Filesystem Size Used Avail Use% Mounted on /dev/loop0 976M 2.6M 907M 1% /export/heartbeat1 /dev/loop1 976M 2.6M 907M 1% /export/heartbeat2
■NFS Server 設定
・NFS サーバ用パッケージのインストール
# yum install nfs-utils
・NFS v4 の Disable
# cp -piav /etc/nfs.conf /etc/nfs.conf.org # sed -i -e 's/^# vers4=y/vers4=n/g' /etc/nfs.conf # sed -i -e 's/^# vers4.0=y/vers4.0=n/g' /etc/nfs.conf # sed -i -e 's/^# vers4.1=y/vers4.1=n/g' /etc/nfs.conf # sed -i -e 's/^# vers4.2=y/vers4.2=n/g' /etc/nfs.conf # diff /etc/nfs.conf.org /etc/nfs.conf 53,56c53,56 < # vers4=y < # vers4.0=y < # vers4.1=y < # vers4.2=y --- > vers4=n > vers4.0=n > vers4.1=n > vers4.2=n
VMware ESXi は、NFS version 4 の対応が微妙である。
※参考:[VMware] NFS プロトコルと ESXi
また、一つの Datastore を複数バージョンの NFS でマウントすることは禁忌とされる。
そのため、NFS version 3 でしか動かないようにしてしまう。
・NFS サーバの起動
# systemctl enable rpcbind.service # systemctl enable nfs-server.service # systemctl start rpcbind.service # systemctl start nfs-server.service
・マウントポイントの設定
# cp -piav /etc/exports /etc/exports.org # echo -e "/export/heartbeat1\t192.168.24.0/24(rw,no_root_squash)" >> /etc/exports # echo -e "/export/heartbeat2\t192.168.24.0/24(rw,no_root_squash)" >> /etc/exports # echo -e "/export/VDO-vol01\t192.168.24.0/24(rw,no_root_squash)" >> /etc/exports # diff /etc/exports.org /etc/exports 0a1,3 > /export/heartbeat1 192.168.24.0/24(rw,no_root_squash) > /export/heartbeat2 192.168.24.0/24(rw,no_root_squash) > /export/VDO-vol01 192.168.24.0/24(rw,no_root_squash) # exportfs -v # exportfs -ra # exportfs -v /export/heartbeat1 192.168.24.0/24(sync,wdelay,hide,no_subtree_check,sec=sys,rw,secure,no_root_squash,no_all_squash) /export/heartbeat2 192.168.24.0/24(sync,wdelay,hide,no_subtree_check,sec=sys,rw,secure,no_root_squash,no_all_squash) /export/VDO-vol01 192.168.24.0/24(sync,wdelay,hide,no_subtree_check,sec=sys,rw,secure,no_root_squash,no_all_squash)