なぜストレージを自分で作るのか
研究を行っていると、大きめの(1つのHDDに収まりきらないぐらいの)ファイルを長期間保存する必要が度々出てきます。通常であれば、外付けUSBHDDを買って分けて格納したり、業者さんに見積もりを依頼してRAIDの組まれたサーバーを購入することになるのが普通かと思いますが、自分の研究室ではOpenZFSによる大容量(700TB+)ストレージを作成し、NFSでアクセスできるようにして自前で長期運用しています。
こういう構成にたどり着いたのには次のような理由があります:
- テープデバイスは保存に最適だが、2世代前の規格が読めなくなるため、ドライブと媒体双方の更新が必要になる。
- 外付けHDDはACアダプタ等を間違えてHDDを冗長性もろとも吹き飛ばすケースがある。Centuryの裸族のお立ち台などを使って、内蔵HDDを使う場合でも、冗長性を確保しようとするとミラーリングしかないため2倍の容量が必要になる。
- RAIDの組まれたサーバーは、多くの場合保証期限を遙かに過ぎたあたりでRAIDコントローラが故障し、代替部品の確保が困難ですべてのデータにアクセスできなくなる。研究費から保守費用を捻出することは今の予算規定だと難しい。
- いずれの場合も、オペレーションミスには対応できない - 多くの場合、ファイル喪失のトラブルは
mv
のdestinationを書かずに実行したり、cp
で上書きしたり、うっかりrm * -rf
と等価なコマンドを実行するところから発生する。 - HDDの故障は、長期にアクセスしていない場合に気づかれにくく、気づかないうちに取り返しの付かないレベルまで被害が拡大していることがある。
- 予算は常に安定しない - 潤沢な年と日帰り出張に苦心する年はランダムに訪れる。
OpenZFS + RAIDZ2 (or RAIDZ3) + snapshotを使うことで、上の問題の大部分をカバーできるため、これを使っています。一方で、OpenZFSは速度の面で優れているわけではありません。このため、計算結果をすぐに格納するストレージとして使うことは推奨できません。弊研では計算クラスタの/homeなどの高速アクセスが必要な場所はXFSなどを利用し、NFS経由でOpenZFSが見えるようにしています。
最近だと、東大のストレージや、名大のコールドストレージなどの便利なサービスが増えていますが、いずれも継続性がよく分からない1という問題があります(名大のものは終了時にデバイスを返却する・ドライブ貸し出しという点でよく考えられていると思いますが、n年後にドライブ自体が故障したらどうするんでしょう……)。そういうわけで、最後には自分で面倒を見る前提でストレージを自前運用しています。本当はこういうのこそ大型計算機センターに任せたいのですが、昨今の予算制約ではまぁ仕方が無いか、という感じです。
ハードウェアの選択
OpenZFS用のサーバー構成を組んでくれる業者さんはレアだと思うので、ストレージを組もうとすると自前で構成を考える必要があります。自分が使っているHW構成は以下のようなものです。
- ホストサーバー (1U-2Uサイズ)
-
- ECC付きの充分な(32G+)メモリを持つこと
-
- PCIeにホストバスアダプタ(HBA)を付ける。HBAは外部(external)からケーブルを挿せるものを選ぶ。
-
- PCIeにNFSからのアクセスのために10GbE を付ける。
- JBOD2エンクロージャ (大体4Uサイズ)
-
- ディスクと電源だけが入る。
- HBA-JBOD 接続用ケーブル
- JBOD用UPS (推奨)
ホストサーバーとJBODストレージを1つのシャーシに突っ込むこともできます。その場合、HBAのケーブルはinternalから挿せるものを選びましょう。UPSは強く推奨します – 皆さんも全データを落雷一発で焼きたくないですよね。
HBAの選択
HBAは次の条件を満たすように選びます。
- 「RAIDカード」では無く「HBA」であること (システムからすべてのHDDが1枚ずつ見えること)
-
- 一部のRAIDカードはfirmware書き換えでITモードと呼ばれるRAIDなしモードに切り替え可能ですが、値段上も利点が無いので最初からRAIDカードは選ばない方が推奨です。
- JBODストレージと同じインターフェースであること。
-
- JBOD←→HBA間はSATAケーブル等とは別のインターフェースで繋がります。いくつか規格がありますが、SFF-8644等が代表的です。このケーブルも買い忘れないようにしましょう。
- JBODの全ディスク枚数を接続できることを確認すること
本当は速度とかも考慮した方が良いのですが、前述の通りパフォーマンスを要求しないことを前提としているので、無視します。ZFSはHDDが1枚ずつ見えることが前提になって設計されており、RAIDを組んだ上にZFSを構成するケースは考慮されていません。管理も面倒になるのでやめた方が良いです。
ほとんどの<=2Uサーバーはlow profileと呼ばれる短いブラケット(PCIeカードから外に出るインターフェース部の長さ)を使うので、HBAがちゃんとlow profile対応か確認してください(普通は対応だと思いますが)。 特にホストサーバーを1Uにすると、カードの配置やインターフェースが特殊であることが多いので、よく確認してください。
JBODの選択
特に悩む点は無いですが、
- 執筆時点(2022年)の価格だと、3.5" のものを選ぶのが良いと思います。
- 今回は値段を優先するので、特にSATA3がサポートされるメディアに入っているか確認しましょう(SASだけというのはまず見ませんが)
- ツールレス(ドライブをネジなしで固定できる)のものを選びましょう。ディスク30枚以上を一人でネジ止め(1枚4回なのでトータル120回+)するとある種の悟りを開けます。とはいえ今ツールレスでないものの方が珍しいですが。
自分は SuperMicro の SuperChassis の66HDDモデルを購入しました。SuperMicro, Dellあたりは取扱業者も多いので、困ることは少ないと思います(クラスタ計算機を扱っている会社の大部分は見積もりに対応してくれると思います)。
HDDの選択
基本的には価格面でSATA3 ディスクを選ぶのが最適ですが、HDDにはSMRとCMRという二つの記録方式があります。SMRはZFSと致命的に相性が悪いので絶対に避けてください。判別方法はHDD各社の公式カタログを見ることで、SMR / CMRどちらであるか記載されています。WD redシリーズやSeagate IronWolfシリーズ、東芝の監視カメラ向けシリーズ(MN)あたりが良い価格帯かと思います(2022年現在、このあたりの大容量はすべてCMRだったはずです)。交換含めて5%ぐらい多めに買っておくと良いです。
ソフトウェアの設定
ここでは細かなコマンドを逐一書くことはしません(マニュアルを自分で読んで行動できる人の為に書いています)。
RAIDZの構成
OSにはLinuxを使います。最近だとRocky Linux, Ubuntuあたりが定番でしょうか。OSをインストールし、HBAやGbEのファームウェアを最新に更新しましょう。
OpenZFSをページに従いインストールします。Linux kernelの更新に対応できるよう、DKMS経由でOpenZFSのカーネルモジュールを自動でコンパイルできるようにしてください。3最近だとkABIベースの手法もありますが、私は使ってみたことが無いのでわかりません。
ZFSの構成はzpool create
で行います。冗長性を確保するため、raidz2 以上を使用し、枚数が多い(>15)場合は1枚以上のspareを入れておくことを推奨します。(最近のOpenZFSだとraidzの代わりにdRAIDがありますが、その場合もparity2枚以上、spare1枚以上を推奨する、ということです)。リスク計算はこの辺が便利です4。また、ZFSの構成に用いるパスは/dev/disk/by-pathまたはby-vdevを推奨します。
# zpool create/addは必ず--dry-runでできあがりを確認してから実行しましょう
zpool create --dry-run tank raidz2 /dev/disk/by-path/foobar-0-baz-baaz-1 /dev/disk/by-path/foobar-0-baz-baaz-2 /dev/disk/by-path/foobar-0-baz-baaz-3 ... spare ...
zpool create tank raidz2 /dev/disk/by-path/foobar-0-baz-baaz-1 /dev/disk/by-path/foobar-0-baz-baaz-2 /dev/disk/by-path/foobar-0-baz-baaz-3 ... spare ...
巨大な1枚のraidzにするのが良いか、中規模のraidzを2-3個作って1つのpoolにするのが良いかは私も分かりません。誰か詳しい人がいれば教えてください。管理の上ではraidz2/3を1個+spareが楽だと思います。
zpool create
が終わったらzfs create
でドライブを作成した後、マウントされるパスを調整(zfs set mountpoint=/foo/bar tank
)し、/etc/exports
または/etc/export.d
以下のファイルを記述してnfsからディスクを見えるようにしましょう。最後に各ユーザーの名前でディレクトリを掘ってpermissionを設定します。
定期scrubと定期snapshotと定期チェック
HDDの故障は、アクセスをしないと気づきにくいため、定期的にチェックをすることが好ましいです。ZFSの場合、zpool scrub
で書き込まれ済みのデータに対してチェックサムの照合を行います。zpool scrub
をcronで毎月実行することを強く推奨します。
# crontab -e でcronを設定しよう
@monthly /sbin/zpool scrub tank
また、データ消失の原因の多くはオペミスに起因します。このため、自分はZFSのsnapshot機能を使って定期的にread-onlyのスナップショットを作り、時間の経ったものを消すようにしています。これにより、オペミスによるファイル消去に気休め程度の対策が可能です。こんな感じです:
# 普段はzshで書いていますがbashでも動くはず……?
# このscriptは@weeklyで動かす
/sbin/zfs snapshot shared@$(/bin/date '+%Y-%m-%d')
str2weeks() {
S=$1
sec=$(/bin/date -d $S '+%s')
echo $(( sec / (60 * 60 * 24 * 7) ))
}
thisweek=$(str2weeks $(/bin/date '+%Y-%m-%d'))
# clean up snapshots
for snap in $(/sbin/zfs list -t snapshot -H | cut -f1); do
d=${snap##*@}
wk=$(str2weeks $d)
# keep only 4 weeks
if (( wk < thisweek - 4 )); then
/sbin/zfs destroy -d $snap
fi
done
最後に、定期scrubをしても警報が送られないと困るので、cronで毎日、チェックスクリプトを走らせてメールでも飛ばすことにしましょう。
# このscriptは@dailyで動かす
declare -a mailto=(foobar@example.com bazbaaz@example.com)
NC=$(/sbin/zpool status | /bin/grep -c -E 'DEGRADED')
/sbin/zpool status | /bin/grep -E '(ERR|FAULTED|UNAVAIL)' -q
Q=$?
if (( $NC > 0 )) || (( $Q == 0 )) ; then
for mail in ${mailto[@]}; do
{
/bin/cat << EOF
To: $mail
Subject: zpool detected error(s)
Disk shinderu pyon
EOF
/sbin/zpool status -v
} | /usr/sbin/sendmail $mail
done
fi
sendmail
が使えない環境の場合、slack bot等を作って通知を飛ばすのが楽だと思います。
上記の設定を行った後、/dev/urandom
あたりを用いて適当な巨大ファイルを作成し、scrubを掛けてみることを推奨します。 30枚を超えるHDDがあるとほぼ確実に1枚以上、初期不良HDDが見つかります。 メール送信用のスクリプトが動いているかどうかの確認にもなります。
これまでにやらかしたミスとbad-knowhow
このページを参考にストレージを構成する方に向けて、自分がやらかしたミスや注意事項をいくつか記載しておきます。
- JBODの電源ケーブルが短かったため、ディスクを交換しようとしてJBODをサーバーラックの手前に引き出したときに電源が全部落ちた
-
- 電源ケーブル長には余裕を持ちましょう
- HBAのBroadcom 9300にはバグがあってSATA3ディスクを大量に使って負荷を掛けるとランダムにエラーが出る
zpool add tank spare diskNN
コマンドを実行するつもりでzpool add tank diskNN
を実行してしまい、OpenZFSの再現困難ながらtoplevelに警告無しでspecial deviceを足せるbugと合わせてトップレベルに冗長性の無いディスクが追加されてしまった-
- これはundoできません(Solaris版ZFSはtoplevelからディスクを取り除けるが、OpenZFSは2022現在で未実装→最近git版で実装されたっぽいが色々とbugあり)。
zpool add
の操作は基本的にundoできないので、オペミスの頻発ポイントと認識してください。
- これはundoできません(Solaris版ZFSはtoplevelからディスクを取り除けるが、OpenZFSは2022現在で未実装→最近git版で実装されたっぽいが色々とbugあり)。
-
zpool add
するときは必ずzpool add --dry-run
をして結果を確認しましょう
-
- 新しいディスク群を追加するときは必ず別のstorage pool name (この場合tankをtank2にするとか)を使い、同じtankに追加するのはやめましょう。つまり、
zpool create tank2
を使うのは良くても、zpool add tank
はできるだけ実行しないことです。
- 新しいディスク群を追加するときは必ず別のstorage pool name (この場合tankをtank2にするとか)を使い、同じtankに追加するのはやめましょう。つまり、
- 騒音が酷いので、サーバールームが無い場合は推奨しない
- RAID is not a backup!
補遺
本ページのスクリプトおよび情報は参考用として置いているものです。スクリプトはas-is(あるがまま)で提供しており、万一スクリプトがユーザーの予想外の動作をした場合でも、ページ著者である桜庭は一切の責任を負わず、保障も保証もしません。スクリプトの実行はご自身の責任で行い、実行前にご自身で内容と動作の確認を行ってください。
-
継続性というと昨今ではどこでも研究室の継続性自体が怪しいのだが……。 ↩︎
-
2022年8月7日現在、日本語版wikipediaの説明は完全に間違っているので注意 ↩︎
-
DKMSを用いる都合上、OpenZFSをWSL上で走らせるのは非常に面倒で、非推奨です。 ↩︎
-
仮定はそれなりに雑なモデルなので過信しないこと。たとえばreal worldのHDDは同時期に買うとまとまって壊れる。 ↩︎