見出し画像

ZFSのミラーリングについて

こんにちは。辻村です。今回は、ZFSファイルシステムの中で、ミラーリングについてひもといてみたいと思います。参考にしたコードは、Illumos のコードです。最後に参考文献としてまとめてあります。

ZFSのディスクの管理の仕組み

zpool create <プール名> mirror <dev1> <dev2> mirror <dev3> <dev4> とコマンドを実行したとき、ZFSでは、7つの virtual device(略してvdevと呼びます)が作られます。それぞれの役割に応じ、root vdev、top level vdev、leaf vdevと呼んでいます。

画像1

ZFSではデバイスをまとめたものを「プール」よび、そこから必要な大きさをデータセットとして切り出すことで管理します。root vdevは各プールに一つあり、その配下の top level vdevをとりまとめています。配下のデバイスの状況を反映して、DEGRADEやONLINEのようなステータスを持ちますが、実際の物理デバイスに割り当てられているわけではありません。

top level vdev(以下TLV)は各RAID構成の一番上にあり、配下の leaf vdev (以下LVD)をまとめています。今回はミラーリングなので、TLV#1はLVD#1、LVD#2をまとめています。TLVが複数あるとき、I/Oは TLV間で分担され、ストライピングのように働きます。つまり、上の例は、RAID1+0となります。また、root vdev同様、ステータスは持ちますが、物理デバイスではありません。

LVDはそれぞれの物理デバイスと関連付けられています。leafと名付けられているのは、木構造で表されるvdevの関係で一番端の「葉っぱ」の部分だからです。LVDは自分がどのディスクと関連付くのかという情報を3種類の形で持っています。3種類必要な理由はおそらく Oracle Solaris のデバイス管理を引き継いでいるせいです。

 (a) /dev/dsk/c3t0d0のようなデバイス名
 (b) /pci@0,0/pci-ide@1f,2/ide@0/cmdk@0,0,a"のような物理デバイス名
 (c) デバイスのシリアル番号などが入った devid と呼ばれるもの

ZFS Storage についてはさらにデバイスが収納されているシャーシの情報なども格納されています。

プールを開くときには vdevがどういう関係になっているかという構成情報が必要ですが、このあたりの詳細については、またの機会とします。

ミラーリングの書き込み

ミラーリングとは、同じデータが複数のディスクに同じように書き込むことで、故障などの際にデータが損失することのないようにする仕組みです。つまり、ミラーリングが2本で構成されていたら、同じ情報を2本に書き込む必要があります。従って、同じデータを1本のディスクに書くよりも遅くなります。

ミラーリングの読みだし

ミラーリングされたプールからデータを呼び出すには、ミラーリングされたいずれかのディスクから読み出せばよいわけです。実際 ZFS のコードもそうなっています。Illumosの場合、以下の行で読みだしに使う leaf vdev を選択しています。

597 /*
598 * For normal reads just pick one child.
599 */
600 c = vdev_mirror_child_select(zio);

このコードのおかげで運良く読みだしが分散できれば、1台だけの時よりも早く読み出せます。(もちろん、ディレクトリキャッシュとか、ZFSのARCと呼ばれるキャッシュとか他に考慮すべきことは数多くありますが、ここでは触れません。)

このコードは私たちにスピードを提供してくれますが、一つ怖いネタを残します。つまり、運悪く読み出されないブロックができる可能性があるのです。(もう一度先ほどの図を載せます。)

画像2


極論ですが、たまたま読み出されたデータすべてが、Leaf vdev#1に入っていたとすると、Leaf vdev #2には全くアクセスされないことになってしまいます 。少し譲って多少分散して読み出されたとしても、エラーが発生するかを確認する方法は該当箇所を読み出すこと自身なので、このコードを使う限り見つからないままになることがあります。他社さんのRAID装置のコードなどは手元にありませんが、おおよそ同様のロジックであると想像します。つまり「読み出さないとわからない」ので、全ディスクにアクセスする「スクラブ」とか「メディアスキャン」と呼ばれる作業を行い、すべて読み出すという作業が定期的に必要なわけです。

かくいう私も自宅の機械ではスクラブを実行していなくて、あるとき、再構築(resilver)が始まってプールを飛ばした口です。スクラブは実施中は性能には悪い方に作用しますが、定期的におこなってください。

参考文献

・Illumos 上の mdb の vdev_t の出力
・Illumos gate: usr/src/uts/common/fs/zfs/vdev_mirror.c
https://github.com/illumos/illumos-gate.git



この記事はここまでです。 最後まで読んでいただいてありがとうございます。 気に入っていただいたなら、スキを押していただいたり、 共有していただけるとうれしいです。 コメントや感想大歓迎です!