Chienomi

新しいストレージワーク(GlusterFS, AoE, lsyncd)

zfs

  • TOP
  • Old Archives
  • 新しいストレージワーク(GlusterFS, AoE, lsyncd)

問題点

分かってはいたことだが、先日の件でbtrfs mirrorでは不十分だ。データの冗長化は次のようなことが考えられる。

  • ストレージの故障
  • ファイルシステムの故障
  • RAIDハードウェアの故障
  • 誤操作による喪失
  • コンピュータノードの故障
  • コンピュータノードの喪失(災害や盗難など)

基本的な対応は次の通り。

ストレージの故障
ミラーリングを行い、故障したストレージを置き換える
ファイルシステムの故障
異なるファイルシステム間でミラーするか、バックアップする。
RAIDハードウェアの故障
同一のRAIDハードウェアに再接続するか、バックアップによって復元する
誤操作
gitやpdumpfs、あるいはLogFSなどスナップショットの活用
ノードの故障
新規ノードにストレージを移設する。可用性が不要ならばデータの冗長化は不要
ノードの喪失
可用性の損失は避けられない。同一箇所に保管していると同時に損失する可能性は高いため、クラウドバックアップが有効

一般にノードの損失は稀なケースだと考えられる。だが、実際はそこそこ可能性はある。落雷によっても起こりうる。この場合のことを考えれば、データを諦められないのであればバックアップは必要だ。

これまでは、btrfsの2レッグミラーを採用していた。これはストレージの故障に対する冗長性・可用性を担保する。しかし、それ以外には対応できていない。特に怖いのは、未だexperimentalであるbtrfs自体の異常だ。ファイルシステムが壊れてしまえばミラーされていたものも含めてすべてのデータがアクセス不能になる。

少々複雑な話に聞こえるかもしれないが、btrfsは「壊れにくいファイルシステム」だ。日常的な読み書きで起こるビットエラーをbtrfsは発見し、ミラーリングを行っていれば訂正することすら可能だ。そのため、他のファイルシステムと比べ非常に壊れにくい。それは他のジャーナリングファイルシステムと比べてもだ。そのためた信頼性が高いと言われ、この点を買って私は採用している。一方で、btrfsはまだ完成度が低く、btrfs自体が壊れる挙動を示す可能性がある。そのため信頼性が低いとされている。

データが既に2TiBを超えている現状にあっては、バックアップやその復元も容易ではない。ちなみに、この次にハードルが上がるのは、ストレージ1台ではすまなくなる時だ。コストを度外視すれば、8TBということになる。

基本的にはバックアップというよりも、ミラーリングによって冗長性を持たせ、データが損失しないことを前提とする方向としている。今後も情報増加は進む予定だし、それに対応する構成としておかなくてはならないからだ。そして、データ量は一般的なシングルストレージで済む量に収まる見込みはない。ストレージ増加よりもデータ増加の方がはるかに速い。

現在の対応は次の通りだ。

  • btrfsによるジャーナリング、自動訂正によるビットエラー対策
  • btrfsミラーによる冗長化
  • btrfsによる柔軟なストレージ追加。1台単位でディスク容量を問わず追加し任意のボリュームを切り出せる
  • 必要な箇所をgitとすることで誤操作による損失の防止
  • 一部データのリモートgitへのclone

だが、先日はそのストレージを格納するコンピュータノードがダウンした。そのため、データ自体にアクセスできなくなった。現在でも最低限、4台のストレージを搭載しなければデータを使うことができない。Proliant Microserverは搭載ストレージ台数は4なので、システムドライブを含めるとそれを搭載することができない。

もちろん、データは損失していないのだからコンピュータノードを追加すれば良いのだが、その間仕事は完全に停止してしまう。やはりこの点も冗長性が必要だろう。

機能問題は別として、別のコンピュータがデータを触れれば良いのだ。コンピュータノード全体がダウンしても機能するようにすれば、1台のコンピュータが損失しても問題ない、ということになる。もっとも、実際に必要となるのは完全なクラウドバックアップだが、現在のところそれは月額で8万円程度が必要になるため、現実的でない。

GlusterFS

GlusterFSはペタバイト規模に対応するクラスタストレージ技術だ。ユーザースペースで動作するデーモンであり、大きなファイルの読み書きはネイティブなコードで行う。FUSEでマウントできるだけでなく、NFSやCIFSでもマウント可能。

分散ファイルシステムだがネイティブファイルシステムではなく、各コンピュータはマウントされた特定のディレクトリをGlusterFSデーモンによって公開する(blickと呼ぶ)。クライアントはblickを束ねてvolumeとしてマウントすることができる。中央サーバーがないのがGlusterFSの特徴だ。

CephやGFSと比べかなりお手軽に使えそうに見えるGlusterFSだが、実際には意外と厳しい。それは、blickの容量をみずにファイルベースで振り分けていくこと、GlusterFSのレプリケーションはblickを組みとして複製するものであることによる。このことから、実質的にはblickはすべて同一容量でなくてはならない。しかも、blickの追加はRAID化している数をunitとして行わなくてはいけない。例えばstriped replicated volumeだとしたら、4 blicksが追加単位となるのだ。ディスク単位のblickにしても4台のディスク、コンピュータ単位だと4台のコンピュータだ!

また、このような技術はノードの停止は「障害」であるため、HAの理屈に基づき稼働停止が許されなくなる。電気代で考えても厳しいし、デスクトップユースでの無停止はそもそも難しい。結構よく見えたのだが、GlusterFS適用はかなり難しいように見えた。

ただし、適用方法はある。それは、「そもそも2組のストレージにしてしまい、2 blicks GlusterFS volumeにする」という方法だ。例えばiSCSI+LVMなどで複数のコンピュータノードからなるひとつのファイルシステムを編成し、それをマウントし、それをblickにすれば良い。そうすればコンピュータを2組に分けることができ、片方の組のコンピュータが停止しても全体はダウンしない。ストレージ追加はLVMなどの単位で行えるためかなり柔軟だ。容量の問題は、単に合計容量が小さいほうの組を上限としてそれを越えないように運用する、という制約があるだけだ。

lsyncd

だが、やはりこのようなHA技術は少々重い。それであれば少なくともデスクトップは使う側にしてデスクトップにストレージをもたせるのはやめるべきだ。

任意に停止しゆるい同期を行えれば良い。つまり、「手動で同期サービスを開始・停止し、ファイル更新時に反映してくれれば良い」という考えだ。可用性については、短時間の停止なら十分許容できる。

原始的には定期的にrsyncを回す方法もあるが、せめてファイル更新を監視したい。別にそれをスクリプトにしてもいいのだが、ionotifyというLinuxの機能があるのだから、それを活かしたいもの。そこで「ファイル変更を監視して同期する」というものを探したところ(正確には「なんて名前だっけ」だった)、lsyncdが見つかった。

lsyncdはファイル同期デーモンだが、実際にはミラーリングを行う機能はなく、rsyncなどをバックエンドとして使う。つまり、lsysncdはionotifyによってファイル更新を受け取り、それをトリガーとしてrsyncなどを起動するデーモンだ。

デスクトップレベルではこれが順当なところではないだろうか。台数が増えるとオンオフも困難になるので普通にHAストレージでいいのかもしれないが。

台数が少ないうちは普通にイーサネットケーブルでつなぎ、それをまとめて2つのストレージを編成すればいいのだが、台数が増えてきた場合、それぞれキーになるノード(片方はデスクトップ)をシングルにつなぎ、それぞれがストレージ用ハブを持っておくと良いだろう。構成手順は次のとおり

  • デスクトップは現在btrfsミラー
  • キーサーバーAを接続し、ZFSでストレージを束ねる
  • キーサーバーAにrsyncで全データをバックアップ
  • デスクトップのbtrfsのミラーをやめて構成しなおす
  • キーサーバーAからrsyncでデスクトップにデータを戻す
  • デスクトップとキーサーバーAにGbEインターフェイスを追加する
  • 追加されたGbEインターフェイスをハブに接続する
  • ストレージサーバーノードをGbEでストレージ側ハブに接続する
  • ストレージサーバーノードのディスクをAoEを用いてそれぞれのキーノードのブロックデバイスとしてみえるようにする
  • 追加されたストレージサーバーノードのディスク(AoE)をbtrfs/ZFSノードに加える
  • btrfs/ZFSをリバランス

10GbEに置き換えるところまで考えればかなりの規模までこれでいけるように思う。ただし、グループノードのいずれかがダウンすると障害発生なので、「故障率」は当然あがる。これはグリッドシステムでは常に起こることだ。