概要
これまでの,数値計算の結果がHDDを圧迫しており,データの引っ越しやバックアップを含め運用方法を検討しbtrbkを用いたsoftware RAIDによるNASの構築ということに至ったのでその運用記録である.必要に応じて加筆を続ける.
背景
ハードウェアRAID か ソフトウェアRAIDか
RAIDの選択しとしてハードウェアRAID(RAID card)とソフトウェアRAIDの選択肢があるが,以下の理由にソフトウェアRAIDを選択した.
- check sumによる整合性がとられていない場合がある
- raid levelの変更が容易ではない
- 新品は高い(ebayで中古なら数千円)
とくにcheck sumによるファイル整合性についてはLevel1Tech Pert1.とPert2.で興味深い考察(実験)がされている.そこで,言及されているように,ハードウェアRAID(youtubeではmega raid)はcheck sumによるファイル整合性がとられていない場合が有るようだ.
端的に言うと,RAID1で運用して,何らかのイベント(宇宙線,電磁ノイズ,高温,あるいは内・外的要因)で片方のデータが書き換えられてしまった場合,どちらのデータが正しいかチェックする機構がないとのこと.RAID5でも同様で,parityからデータを復元する際にどのHDDを信頼すればよいか判断できないという事が指摘されている.
これらの問題を解決したハードウェアRAIDコントローラがあってもおかしくないと思うが,私は知らないし実在しても安価にではないと思われる.
zfs か btrfsか
主要なソフトウェアRAIDにzfs, btrfがしばし挙げられる.
zfs
zfsはOracle Solarisのファイルシステムで,zfs on linuxとしてlinuxでも使用することができるが,ライセンス上の問題があるとしてしばし議論されているが,こことでは立ち入らない.
ubuntu server 18.04ではapt経由でzfsを標準のリポジトリからインストールすることができ,ubuntu 19.10や20.04ではroot on zfsがexperimentalとしてインストーラーに同梱されている.
zfsはドキュメントも多くArchWikiやあるBlogあるいはOracleが参考になるとおもう.
結果としてNASではzfsを使用しなかった.主な理由として,
- RAID-Zはraid poolをdestroyしないとRAIDレベル変更ができない
- strip pool (raid0)ではディクス追加可能だがデフラグメント機能がない
- 容量の異なるHDDを扱えない
- zfs-auto-snapshotによるスナップショットの自動取得はあるものの,backupの自動化ツールが無さそう.
4に関しては,znapzendというのも有るらしいが,1.-3.の要件を満たさないのでNASのファイルシステムをzfsで運用することは無かった.
ただ,desktop環境ubuntu 20.04のexperimental機能である,root on zfsを導入して見たところ,非常に使い勝手が良くメモリもそれほど使用しないので(oracleとの訴訟問題になるかもしれないが)ubuntuのzfsサポートには期待したいところである.ただしroot on zfsのinstall時に,ディレクトリ全体に暗号化をかけるというオプションはなかった.スナップショットによるrevertはランサムエウェアなどのクリプトマルエウェアへの強力な対策なので,rootディレクトリの暗号化にも対応してもらえるとより強力になると思うので,ライセンスの問題と含めて今後の進展に期待している.
一応良い点を挙げておくと,
- 高信頼性 (btrfsにはraid5/6に既知の問題がある)
- Btrfsよりperfomanceが優れるらしい.たとえばZFS, BTRFS, XFS, EXT4 and LVM with KVM – a storage performance comparison.(ただしLinux 5.4 EXT4 / XFS / Btrfs RAID Performance On Four HDDsをみると環境とテストに依存しそう).
- キャッシュによるパフォーマンスの向上が望めるZFSはどう活用できるか
- 複数の圧縮アルゴリズムが利用可能
- 暗号化やファイル割当(quota)が容易
- nfsなどがzfsの側の設定で可能
ただ,2, 3,に関してはローカルネットワークが1GBase-Tなので定格で125MB/sec程度しか転送できないので,その恩恵は体感できなかった.
使用したことはないがfreeNASはZFSを採用している.
btrfs
btrfsはzfsよりずっと新しいファイルシステムでArchWikiや公式のWikiが参考になる.
良い点として
- ライセンスの問題がない
- 柔軟にRAIDレベルの変更ができる
- ディスク追加やRAIDレベル変更した際のデフラグメントをサポート
- 任意のタイミングで圧縮アルゴリズムをでフラグメントによって変更可能
- btrbkによる自動スナップショット,自動バックアップが容易
悪い点として
- RAID5/6にwrite holeの問題がある
- ssdをキャッシュデバイスとして使用するためにはbcacheと組み合わせる必要がある(関係が有るのかどうか知らないがbcachefsというファイルシステムが現れた)
- CentOS 8 でディスコンにされた
- 公式のWikiが分かりづらい
- ファイル割当(quota)に不具合があった(後述)
ただし私の環境では
- btrfsに限らずRAID5/6はrebuild時に,HDDに高負荷な影響を与え,故障する確率が高くなるそうなので利用しない.
- NASの場合,1GBase-TのNetworkがボトルネックとなっているので,必要性を感じない.
というと事からデメリットは現在のところあまり感じていない.
なお,使用したことはないがunraidはbtrfsを採用している.
(macはapplefsにsnapshotがサポートされた.ファイルシステムははbtrfsと同じB treeアルゴリズム)
環境
NAS用HDDとして東芝 MNシリーズが安価なので利用する.恐らくToshiba MG06ACA800Eが最もコストパフォーマンスが良く,10TBより大きな容量はヘリウム充填となり高価になる.なおWestan degital RADがNAS用HDDとして売られているのにもかかわらず,RAIDに不向きなSMR方式を採用している問題が指摘されているが,東芝がSMR方式を採用しているHDDのリストは公開されており,消去法的にMNシリーズはRAIDに有利なCMR方式を採用しているように読める.
debian系でbtrfsのinstall は
# apt install btrfs-progs
本番環境
- OS : Debian 10
- CPU: intel core i3-6100
- RAM: DDR4 16GT (非ECC)
- HDD1: TOSHIBA MN06ACA10T HDD [10TB]
- HDD2: TOSHIBA MN06ACA10T HDD [10TB]
- HDD3: Seagate ST8000DM004-2CX188 [8TB]
HDD1, HDD2 をraid 0としてlzo圧縮をかけdata poolとしてnfsを運用.ちなみにcore i3はなぜかECC対応だったりする.現環境では非ECCだが.
# btrfs filesystem show /data/
Label: 'data' uuid: a5eeeef7-4f23-48c8-8eaf-a357fc0e6783
Total devices 2 FS bytes used 5.01TiB
devid 1 size 9.10TiB used 5.01TiB path /dev/sdd
devid 2 size 9.10TiB used 5.01TiB path /dev/sda
HDD3はbackup用にzstd圧縮をかけ運用
$ btrfs filesystem show /backup/
Label: 'backup' uuid: aeca9446-e211-469c-b4f2-1356be6b02bc
Total devices 1 FS bytes used 5.96TiB
devid 1 size 7.28TiB used 6.05TiB path /dev/sdb
なお圧縮レベルはいずれもデフォルトで圧縮によるperformanceはWhat are the differences between compression methods?やbtrfs: Add zstd support
が詳しい.
snapshotの取得とbackupはbtrbkを使う(aptでinstall可能).
実験環境として
- OS : Debian 10
- CPU: AMD E2-3200 (2010年ごろのものだと思われる)
- RAM: DDR3 4GB
- HDD1: Western Digital Green WD30EZRX [3TB]
- HDD2: Hitachi Ultrastar A7K2000 [1TB]
- HDD3: Seagate Barracuda 3.5 ST2000DM006 [2TB]
- HDD4: HGST HCC541010A9E680 [1TB]
HDD1-HDD4をRAID10としてlstd圧縮でsamba poolとして運用.この場合,1TBのデバイスとしてマウントされる.
# btrfs filesystem show /samba-pool/
Label: 'btrfs-pool' uuid: 7b1f20bf-5944-48a6-98e1-6e267168d0b3
Total devices 4 FS bytes used 900.24GiB
devid 1 size 931.51GiB used 452.00GiB path /dev/sdb
devid 2 size 931.51GiB used 450.01GiB path /dev/sdc
devid 3 size 2.73TiB used 453.01GiB path /dev/sdd
devid 4 size 1.82TiB used 451.00GiB path /dev/sde
運用記録
quotaのトラブル
実験環境下でquota を使ってsubvolumeの上限を100Gにかえる
# btrfs qgroup limit 100G <subvol_path>
ということをしたところ,btrfs-transacti(on?)とbtrfs-cleanerがCPU使用率100%になってまともに書き込みできなくなり,その後kernel crashするという問題が生じた.8GBへ換装後,クラッシュすることは無くなったがbtrfs-transactiが大量に発生しパフォーマンスが低い状態となるので,quotaは使用しないほうが良いかもしれない.
実際ArchWikiのquotaでは
警告: Qgroup はまだ安定状態ではなくサブボリュームのスナップショットとクォータを組み合わせると操作によってパフォーマンスに問題をきたします (スナップショットの削除など)。さらに 既知の問題 が存在しています。
とあるので,quotaを無効化しておく.
# btrfs quota disable <subvol_path>
quotaを使わなければ実験環境の低スペックマシンでも問題なく運用することができた.
zstd圧縮によるトラブル
本番環境
# btrfs filesystem show /data/
Label: 'data' uuid: a5eeeef7-4f23-48c8-8eaf-a357fc0e6783
Total devices 2 FS bytes used 5.01TiB
devid 1 size 9.10TiB used 5.01TiB path /dev/sdd
devid 2 size 9.10TiB used 5.01TiB path /dev/sda
現在はlzo圧縮で運用しているが,圧縮アルゴリズムをzstdに変更すると5TBのデータが2TB弱まで圧縮される.これ幸いとzstd圧縮で数ヶ月運用していたが,nfsとの相性が良くなかった.
具体的には,data以下のディレクトリをnfsを非同期オプションで(async)で運用していた.リモート先でdataをマウントしてプログラムファイルの編集をし,異なるリモートで実行したところ,ファイルの更新がされていないという状況が頻発した.ファイルをcatするなどすると更新される.nfsを同期(sync)オプションで運用したところ,前述の問題は生じなかったもののパフォーマンスが著しく低下してしまった.
btrfsの圧縮アルゴリズムをlzoにしたところ,nfsを非同期オプションで(async)で運用してもファイルの更新に時間が掛かるの問題は現在起きていないのでlzoで運用することにした.
load averageが高い
ある日を境に,本番環境のload average が15程度ある.
# iostat -x
Linux 4.19.0-10-amd64 (eular) 08/19/2020 _x86_64_ (4 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
1.98 0.82 10.64 66.12 0.00 20.44
Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util
nvme0n1 4.94 10.53 37.18 142.95 0.00 5.21 0.00 33.09 0.02 0.81 1.01 7.53 13.58 64.44 99.66
sda 79.81 3.50 23940.68 221.91 164.24 2.53 67.30 41.94 34.94 12.10 2.58 299.96 63.38 2.39 19.95
sdd 89.33 3.44 24979.15 221.91 179.70 2.59 66.80 42.94 36.33 16.43 3.08 279.64 64.48 3.10 28.74
sdb 142.77 43.87 29283.33 4244.05 129.90 70.13 47.64 61.52 51.04 166.47 14.19 205.11 96.74 5.30 98.87
をみるに%iowaitが60%強もあり高め.具体的なプロセスを確認するため
# pidstat -dhIl
Linux 4.19.0-10-amd64 08/19/2020 _x86_64_ (4 CPU)
# Time UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command
02:55:23 PM 0 1 77675.45 14.06 0.06 3 /sbin/init
03:01:52 PM 0 2492 1.03 0.32 0.00 0 /usr/bin/perl /usr/sbin/btrbk -c /etc/btrbk/btrbk.conf -q run
03:02:01 PM 0 2511 1118.26 0.00 0.00 4293272 btrfs send -p /data/snapshots/nfs.20200803T0017 /data/snapshots/nfs.20200812T0017
(省略)
をながめるとbtrfs関係のコマンドでiodelayの数値が大きくなっている.よくよく見ると
# pidstat -dhIl | grep -e "btrbk" -e "btrfs"
# Time UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command
(省略)
03:01:52 PM 0 2492 1.03 0.32 0.00 0 /usr/bin/perl /usr/sbin/btrbk -c /etc/btrbk/btrbk.conf -q run
03:01:52 PM 0 6430 0.00 0.04 0.00 0 /usr/bin/perl /usr/sbin/btrbk -c /etc/btrbk/btrbk.conf -q run
03:01:52 PM 0 7025 0.07 0.29 0.00 0 /usr/bin/perl /usr/sbin/btrbk -c /etc/btrbk/btrbk.conf -q run
03:01:52 PM 0 11531 0.04 0.26 0.00 0 /usr/bin/perl /usr/sbin/btrbk -c /etc/btrbk/btrbk.conf -q run
03:01:52 PM 0 16036 0.04 0.19 0.00 0 /usr/bin/perl /usr/sbin/btrbk -c /etc/btrbk/btrbk.conf -q run
03:01:52 PM 0 19403 0.01 0.02 0.00 0 /usr/bin/perl /usr/sbin/btrbk -c /etc/btrbk/btrbk.conf -q run
03:01:52 PM 0 20587 0.04 0.22 0.00 0 /usr/bin/perl /usr/sbin/btrbk -c /etc/btrbk/btrbk.conf -q run
03:01:52 PM 0 31189 0.01 0.05 0.00 0 /usr/bin/perl /usr/sbin/btrbk -c /etc/btrbk/btrbk.conf -q run
03:02:01 PM 0 2511 1118.26 0.00 0.00 4293272 btrfs send -p /data/snapshots/nfs.20200803T0017 /data/snapshots/nfs.20200812T0017
03:02:01 PM 0 6445 712.17 0.00 0.00 3500343 btrfs send -p /data/snapshots/nfs.20200803T0017 /data/snapshots/nfs.20200817T0017
03:02:01 PM 0 7040 1295.01 0.00 0.00 3099643 btrfs send -p /data/snapshots/nfs.20200803T0017 /data/snapshots/nfs.20200813T0017
03:02:01 PM 0 11546 1260.44 0.00 0.00 3177812 btrfs send -p /data/snapshots/nfs.20200803T0017 /data/snapshots/nfs.20200814T0017
03:02:01 PM 0 16051 817.53 0.00 0.00 4124371 btrfs send -p /data/snapshots/nfs.20200803T0017 /data/snapshots/nfs.20200815T0017
03:02:01 PM 0 19417 481.58 0.00 0.00 1787004 btrfs send -p /data/snapshots/nfs.20200803T0017 /data/snapshots/nfs.20200818T0017
03:02:01 PM 0 20601 791.50 0.00 0.00 3951755 btrfs send -p /data/snapshots/nfs.20200803T0017 /data/snapshots/nfs.20200816T0017
03:02:01 PM 0 31204 68.50 0.00 0.00 752956 btrfs send -p /data/snapshots/nfs.20200803T0017 /data/snapshots/nfs.20200819T0017
btrbkで1時間毎にsnapshotを作成しているのだが,nfs.20200803T0017のスナップショットが別の名前で何度もsendされている.なぜこの様な状況になっているのか,理解できないがprocess をkillしないとsnapshotを削除できないので
# pidstat -dhIl | grep "btrfs send" | awk '{print $4}'
して問題を起こしたsnapショットを削除しておく.
# btrfs subvolume delete -c /data/snapshots/nfs.20200803T0017
Delete subvolume (commit): '/data/snapshots/nfs.20200803T0017'
これでload averageが3程度まで落ち着いた.それでも普段(1以下)より高く
# pidstat -dhIl | grep -e "btrbk" -e "btrfs"
# Time UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command
04:00:49 PM 0 542 0.00 0.00 0.00 0 btrfs-delalloc
04:00:49 PM 0 572 0.00 0.03 0.00 0 btrfs-delalloc
04:00:49 PM 0 721 0.01 0.10 0.00 502 btrfs-cleaner
04:00:49 PM 0 722 0.07 4.86 0.00 26411 btrfs-transacti
04:00:49 PM 0 1434 0.21 0.98 0.00 26850 kworker/u8:6-btrfs-freespace-write
04:00:49 PM 0 1724 0.13 0.23 0.00 3423 btrfs-cleaner
04:00:49 PM 0 1725 1.74 85.49 0.00 280897 btrfs-transacti
04:00:49 PM 0 1736 2.09 2.58 0.00 67700 btrfs-cleaner
04:00:49 PM 0 1737 12.79 175.22 0.00 18215402 btrfs-transacti
04:00:49 PM 0 5003 0.06 0.37 0.00 9639 kworker/u8:15-btrfs-endio-meta
04:00:49 PM 0 6124 0.05 0.25 0.00 6927 kworker/u8:16-btrfs-freespace-write
btrfs-transacti(on?)が足をひっぱている気がする.似たような事例でhttps://myn.meganecco.org/1480038240.html でbtrfs のiowaitについて調査してあるのを発見する.dstatというコマンドがあることはが知らなかったので,導入してみると
# dstat --top-bio -d -n -c
----most-expensive---- -dsk/total- -net/total- --total-cpu-usage--
block i/o process | read writ| recv send|usr sys idl wai stl
systemd 75M 14k| 83M 5227k| 0 0 | 3 10 21 66 0
badblocks 10M 0 | 10M 62M| 70B 826B| 1 2 57 40 0
badblocks 5120k 0 |5328k 2016k| 70B 466B| 2 1 73 24 0
badblocks 6144k 0 |6304k 2272k| 70B 338B| 1 1 62 36 0
...
badblocksには思いたるふしがって,backup用HDD
- HDD3: Seagate ST8000DM004-2CX188 [8TB]
が不良セクタが生じたのでその調査でbadblocksコマンドをbackgroundで動かしていたのを忘れていた.
load average が3程度あるのはおそらくその影響だろう.実際bacblocksが終了するとload averageが1以下に落ち着いた.
HDD不良
上述でも言及したがSegete ST8000DM004に不良セクタが生じた.smartctlの主要な情報を抜き出すと
SMART Attributes Data Structure revision number: 10
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME FLAG VALUE WORST THRESH TYPE UPDATED WHEN_FAILED RAW_VALUE
5 Reallocated_Sector_Ct 0x0033 100 100 010 Pre-fail Always - 0
9 Power_On_Hours 0x0032 087 087 000 Old_age Always - 11585 (151 153 0)
197 Current_Pending_Sector 0x0012 100 100 000 Old_age Always - 0
SMART Error Log Version: 1
ATA Error Count: 8 (device log contains only the most recent five errors)
SMART Self-test log structure revision number 1
Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error
# 1 Short offline Interrupted (host reset) 00% 11538 -
# 2 Short offline Completed without error 00% 11507 -
# 3 Extended offline Completed: read failure 50% 11492 -
Extended offline testで不良セクタがあると報告されてCurrent_Pending_SectorのRAW_VALも10程度となっていたはずだが,short offlineテストをpassしたせいか Current_Pending_SectorのRAW_VALが0になっていた(単調増加だと思っていが・・・).しかしながら,btrfsからデバイスの状態を見ると,
# btrfs device stats /backup/
[/dev/sdb].write_io_errs 0
[/dev/sdb].read_io_errs 2
[/dev/sdb].flush_io_errs 0
[/dev/sdb].corruption_errs 13
[/dev/sdb].generation_errs 0
となっているので異常が出ているのは間違いない.約1年半ほぼ無休運用.やはりNAS用を買うべきだったかもしれない.8TBあるとbadblocksコマンドがそのまま動いてくれないので
# badblocks -b 4096 -vs -o badblocks.txt /dev/sdb
として不良セクタの調査をする.得られたデータから
# fsck -l badblocks.txt /dev/sdb
とすれば不良セクタのマーキンが完了する.なお上述のコマンドは
# fsck -t -y -f -c /dev/sdb
とすれば一行で終わらせる・・・.というのが一般的だが,btrfsの場合fsckを実行すると
# fsck -t -y -f -c /dev/sdb
fsck from util-linux 2.33.1
If you wish to check the consistency of a BTRFS filesystem or
repair a damaged filesystem, see btrfs(8) subcommand 'check'.
となる.mountしたままだとcheckコマンドが動かない.不良セクタを出したHDDではraidを組んでいなかったので,umountしてcheckを実行する.
# sudo umount /backup
# btrfs check /dev/sdb
Opening filesystem to check...
Checking filesystem on /dev/sdb
UUID: aeca9446-e211-469c-b4f2-1356be6b02bc
[1/7] checking root items
実行後にbtrfs checkコマンドについて調べて見たところ,ArchWikiにbtrfs checkに
警告: Btrfs はまだ開発途上であり、特に btrfs check コマンドについては仕様が固まっていないので、--repair スイッチを付けてbtrfs check を実行するときはあらかじめ Btrfs のドキュメントを読んでバックアップを作成することを強く推奨します。
との記述を発見.repairをかける分けじゃないし,まあ壊れてもよいバックアップディスクなので,とりあえず様子見.その結果,foregroundでもbackgroundで動かしても
[1/7] checking root items
[2/7] checking extents
あたりでプロセスがkillされてbtrfs checkを完了できない.google先生によるとOOM(メモリが足りな)でkillされる場合があるようだ.muninではそれらしい兆候は確認できなかったが念の為low memroy modeで動かして様子見.
$ btrfs check -p --mode=lowmem /dev/sdb
``