ストレージ実務 — RAID・スナップショット・iSCSI・fio
RAID は可用性でありバックアップではない — 再構築中が最も危険だ
一言でいうと
RAIDは、ディスク1枚が死んでもサーバーが止まらないようにする仕組みです。削除したファイル・間違った変更・暗号化攻撃は、すべてのディスクにそっくり複製されるので、RAIDは防げません。そして、死んだディスクを交換して再び合わせるリビルドの時間が、アレイ全体で最も危険な区間です。
なぜ必要なのか
ディスクは消耗品です。サーバー1台にディスクが複数枚あれば、そのうち1枚が死ぬのは「もし」ではなく「いつ」の問題です。ディスクが1枚死ぬたびにOSを入れ直してバックアップから復元していたら、何時間もサービスが止まります。RAID(Redundant Array of Independent Disks)は、複数枚を1つのようにまとめて、1枚の死を吸収します。
Linuxは、カーネルのmd(multiple devices)ドライバーでソフトウェアRAIDを提供し、mdadm(8)がアレイを作って管理します。ハードウェアRAIDカードは、同じことをコントローラーが行い、OSにはディスク1枚だけを見せます。そのため、カードの裏のディスクの状態は、たいてい製造元のツールで見る必要があります。原理は同じなので、このコースではmdで学びます。
どう動くのか
md(4)が説明するレベル(level)を表にまとめると、次のとおりです。
| レベル | 方式 | 耐えられる故障 | 使える容量 |
|---|---|---|---|
| RAID0 | ストライプ(stripe) | なし。1枚だけ死んでもすべて失う | N枚すべて |
| RAID1 | ミラー(mirror) | N−1枚 | 1枚 |
| RAID5 | 分散パリティ1個 | 1枚 | N−1枚 |
| RAID6 | パリティ2個 | 2枚 | N−2枚 |
| RAID10 | ミラーをストライプに | ミラーのペアごとに1枚 | 半分 |
RAID5・6は、容量が安いが小さな書き込みが高くつきます。1ブロックを直すには、古いデータと古いパリティを読んで新しいパリティを計算し、2つを書き直す必要があるからです。書き込みの多いデータベースボリュームにRAID10を選ぶ理由が、これです。
アレイの状態は、/proc/mdstatの1行にすべてあります。[2/2] [UU]は2枚のうち2枚が生きているという意味で、[2/1] [U_]は1枚が抜けたdegraded状態です。故障したデバイスは、名前のあとに(F)が付きます。mdadm --detailのState :行は、同じ事実をclean、degraded、recoveringのような言葉で見せてくれます。
ディスクの交換は、4つの動作です。--failで故障をマークし、--removeでアレイから外し、新しいディスクを--addで入れると、カーネルがrecoveryを開始して、生きている側の内容を新しいディスクにコピーします。このコピーが終わって初めて、再びcleanになります。mdadm --waitは、その作業が終わるまで待ちます。
リビルドが危険な理由は、その間、生きている1枚が唯一のコピーだからです。リビルドは、そのディスクのすべてのブロックを読みます。普段は誰も読まなかった隅に、読み取れないセクターが隠れていたら、まさにこのときに表面化し、そのブロックは復元する先がありません。そのため、mdは、普段から前もってすべてを読んでみるスクラブ(scrub)を提供します。カーネルのmdドキュメントによると、/sys/block/mdX/md/sync_actionにcheckを書くと、すべてのコピーを読んで比較し、異なるブロックの数をmismatch_cntに残し、終わるとsync_actionがidleに、last_sync_actionがcheckに変わります。Debian系のmdadmパッケージは、このチェックを定期的に実行するよう予約しています。
アレイは、起動時に再び組み立てられる必要があります。mdadmは、設定ファイルのARRAY行で、どのUUIDのデバイスが1つのアレイなのかを知ります。UbuntuやDebianでは/etc/mdadm/mdadm.confで、起動の初期に組み立てられるようにするには、update-initramfs -uでinitramfsにも入れます。mdadm --detail --briefが、その行を作ってくれます。コマンドを2回実行して>>で追記すると、同じ行が2回たまりますが、このファイルは障害のときに人があらためて読むドキュメントでもあるので、アレイごとに1行だけを残します。
現場での姿
最もよくある大きな事故は、生きているディスクを抜くことです。アラートが「ディスク1枚が故障」と言ったとき、スロット番号だけを信じて抜いたところ、それが無事なほうだったなら、RAID1が丸ごと落ちます。交換の前に、mdadm --detailで故障したデバイスの名前を見て、lsblk -o NAME,SERIALやsmartctl -iでシリアル番号を確認し、物理ディスクのラベルと合わせます。この確認を、作業計画書の1行として書いておくチームが多いです。
2つ目は、「RAIDだからバックアップは要らない」という思い込みです。rm -rfは2枚のディスクで同時に起き、間違ったマイグレーションも、ミラーのように正確に複製されます。RAIDは、ディスク故障という1種類の事故だけを防ぎます。元に戻すのは、スナップショットとバックアップの仕事で、それは次のモジュールと、容量計画と変更管理コースで扱います。
3つ目は、リビルドがサービスを遅くすることです。リビルドもディスクI/Oなので、業務のトラフィックと競合します。md(4)は、/proc/sys/dev/raid/speed_limit_min・speed_limit_maxで、リビルド速度の下限と上限を調整できるようにしています。業務時間には上限を下げ、夜に上げるように運用しますが、遅くするほど危険な区間が長くなるという代償を払います。
次のラボですること
256MiBのループデバイスを3つ作り、そのうち2つでRAID1の/dev/md/stoを立ち上げます。ext4でフォーマットして、20MiBのファイルとそのチェックサムを残し、mdadm.confにアレイを1行で登録します。そのあと1枚を故障させて外し、degraded状態を記録し、3つ目でリビルドしたあと、チェックサムでデータが無事かを確認します。最後に、チェック(check)を実行して、mismatch_cntを記録します。