メインマシンはデータ保存用に3TBのハードディスクを4本積んでいます。前回換装してから3年半ほどが経ち、使用時間が軒並3万2000時間を越えている状態です。 去年の10月に新しいマシンを組んだ際にハードディスクをそのまま移し騙し騙し使っていたのですが、先週になってとうとう1台がシステム側から認識しない自体が発生しました。システムを再起動すると正常に認識し、特に物理的なエラーも論理的なエラーも発生していなかったものの、良いタイミングだと思い換装することにしました。
将来の換装のためと全12TBのストレージ領域中5.5TBまでデータの整理を行なっていたので、新しい3TBストレージを4本準備してRAID10を組んでみます。
準備
下記のものを4台購入しました。
これらを使って標準的な RAID10 構成にしたいと思います。新規のストレージをマシンに接続するとそれぞれ sdc, sdd, sde, sdf と認識されているとします。
システムから認識される論理デバイスは /dev/md0
になる予定です。ストレージの利用率は50%のミラーリング+ストライピング構成です。
早速、それぞれのストレージを parted を使って初期化します。以降はほぼずっと root 権限での作業になります。
for t in /dev/sd{c,d,e,f}; do \
parted --script $t "mklabel gpt"; \
parted --script $t "mkpart primary 0% 100%"; \
parted --script $t "set 1 raid on"; \
done
GPT に設定し、パーティションを作成後、RAID フラグを立てています。初期化に成功すると、
$ ls /dev/sd*1
/dev/sdc1
/dev/sdd1
/dev/sde1
/dev/sdf1
パーティションに対応するデバイスファイルが生成されます。
ソフトウェア RAID の構築
Linux でソフトウェア RAID を実現するには、例に漏れず mdadm
を使います。インストールは次のとおり。
apt update
apt install mdadm
実行します。
mdadm --create /dev/md0 -v --raid-devices=4 --level=raid10 \
/dev/sdc1 /dev/sdd1 /dev/sde1 /dev/sdf1
/dev/md0
は作成したい論理デバイスファイル名です。 --level=raid10
で RAID10 を指定しています。最後にデバイスを指定しています。 こちらの記事によると、デバイスの順序によってどのデバイス同士が RAID1 ペアなのかの構成が変わるようですね。 コマンドを実行すると、最終確認をしてくるので y
と入力。
mdadm: array /dev/md0 started.
と表示されシェルに戻ってくれば設定終了です。あとはバックグラウンドで初回の resync 処理が走るので
watch -n 5 -d cat /proc/mdstat
で進捗状況を見ましょう。私の環境では処理が終わるまでに6、7時間を要しました。resync している最中でも /dev/md0 を使うことは可能ですがパフォーマンスが凄く落ちてしまうので、できるだけ放っておく方が無難。処理している間に、アレイ情報をファイルに書き出しておきます。これをしないと次回起動時にアレイを正しく扱ってくれません。
mdadm --detail --scan >> /etc/mdadm/mdadm.conf
mdadm.conf の内容は下記のようになりました。
# mdadm.conf
#
# Please refer to mdadm.conf(5) for information about this file.
#
# by default (built-in), scan all partitions (/proc/partitions) and all
# containers for MD superblocks. alternatively, specify devices to scan, using
# wildcards if desired.
#DEVICE partitions containers
# auto-create devices with Debian standard permissions
CREATE owner=root group=disk mode=0660 auto=yes
# automatically tag new arrays as belonging to the local system
HOMEHOST <system>
# instruct the monitoring daemon where to send mail alerts
MAILADDR root
# definitions of existing MD arrays
ARRAY /dev/md0 metadata=1.2 name=**********:0 UUID=********:********:********:********
末尾にアレイ情報が追記されています。これで再起動しても正しくアレイを認識できるようになります。なお、resync 中に再起動をかけると処理が最初からやり直しで、自動的に実行もしてくれないので手動で実行する必要があります。 アレイとしてスキャンしたいデバイスを明示的に指定したりするには、 DEVICE
部分を指定します。
resync 処理が完了したら /proc/mdstat
の内容が
cat /proc/mdstat
Personalities : [raid10]
md0 : active raid10 sdd1[0] sde1[3] sdf1[2] sdc1[1]
5860268032 blocks super 1.2 512K chunks 2 near-copies [4/4] [UUUU]
bitmap: 0/44 pages [0KB], 65536KB chunk
unused devices: <none>
となります。 [UUUU]
の部分が「4本すべて正常」を表しています。異常が出た場合には、この U
が _
(アンダースコア)になります。例えば、sed1 に異常があった場合は [U_UU]
という表示になります。
論理デバイスを初期化
論理デバイスの /dev/md0
が使える状態になったので、後は通常どおりフォーマットしてマウントします。
mkfs.ext4 /dev/md0
mkdir /mnt/raid10
mount /dev/md0 /mnt/raid10
私の環境の場合、 df -h
で5.5TBボリュームとして認識しました。
定期チェック設定の確認
mdadm をインストールすると、自動的に cron に定期チェックのスクリプトが登録されます。
cat /etc/cron.d/mdadm
#
# cron.d/mdadm -- schedules periodic redundancy checks of MD devices
#
# Copyright © martin f. krafft <madduck@madduck.net>
# distributed under the terms of the Artistic Licence 2.0
#
# By default, run at 00:57 on every Sunday, but do nothing unless the day of
# the month is less than or equal to 7. Thus, only run on the first Sunday of
# each month. crontab(5) sucks, unfortunately, in this regard; therefore this
# hack (see #380425).
57 0 * * 0 root if [ -x /usr/share/mdadm/checkarray ] && [ $(date +\%d) -le 7 ]; \
then /usr/share/mdadm/checkarray --cron --all --idle --quiet; fi
毎週日曜日の午前0時57分に実行され、その日が毎月7日より前…つまり毎月最初の日曜日であれば、 checkarray
コマンドが実行されます。「平日は避けたいけど、実行は月に1回だけでいい」という設定を crontab では素直に書けないのでコメントで軽くdisってますねー。実行するトリガーを決めるのは実行したいもの各々によって違うはずなので、cron は今以上高機能化する必要もない気もします。一方で「日付や曜日、何分毎…といったある程度の時間の概念を扱っているし、可読性が落ちてバグも増えるから、このくらい標準機能で出来てもいいじゃない」と言いたくなる気持ちも分かります。
手動でのチェック
cron にも登録されている /usr/share/mdadm/checkarray
はスケジュールを考慮しており、最近チェックが走ったアレイはチェックをスキップします。手動で強制的にチェックを行いたい場合は次のコマンドを実行します。
echo check > /sys/block/md0/md/sync_action
また、停止したい場合は
echo idle > /sys/block/md1/md/sync_action
を実行します。リビルド中に sync_action に書き込んでもエラーになって弾かれるため注意が必要です。
様子は構築時同様に cat /proc/mdstat
で確認することができます。
気付いた点
- 今回はあわてて作業をしたため忘れていましたが、障害発生時にどのストレージを換装すればいいかスムーズに見極めるため、ラベルを付けていた方がいいです。
- 通電したまま電源やSATAケーブルをいじるのが怖くて今回は試してませんが、SATAもホットスワップに対応してるんですねー。内蔵デバイスでの運用ばっかりなので考えてもみませんでした。
確かに外付けSATAがある訳だ…。 - 暇が出来たら、今度は既存のストレージ(しかもブートデバイス)のRAID化をやってみようと思います。最近、CUDA 環境を整えようといろいろやっていたら
update-initramfs
の実行処理が帰って来なくなるようになってブートシーケンスを触るのは毎回どきどきします。まあ、ブートデバイス周りだけだから GRUB 設定だけでいけるのかな…。
参考
- Ubuntu 16.04 LTS : RAID 1 を構成する : Server World
- RAID10構築手順の記録 – 夜間飛行
- RHEL系のmdadmのraid-check を調べてみた – うまいぼうぶろぐ
[…] 今、僕のメインで使っている手元 PC は次のストレージ構成になっています。今から4年半前に入れ替えたままの構成です。 […]