分散ファイルシステム/ブロックデバイスをまとめる

昨日KLab勉強会#2の資料を公開しましたが、その中で動的な分散ファイルシステムを設計していると書きました。分散ファイルシステムというのは既にいろいろ存在しているわけですが、情報が分散していてサッパリ分からないので、このあたりでまとめてみたいと思います。
間違っていたり古かったりするに違いないので、正確な情報は本家の情報を参照してください。

ファイルシステムレイヤー

NFS GFS(Global File System) OCFS GlusterFS Lustre
下位レイヤー Filesystem Block Device Block Device Filesystem Block Device
読み込み
書き込み
アクセスの冗長化 × ○(負荷分散と排他) ×
データの冗長化 下位レイヤーに依存 下位レイヤーに依存 下位レイヤーに依存
読み込みの負荷分散 × 下位レイヤーに依存 下位レイヤーに依存
書き込みの負荷分散 × 下位レイヤーに依存 下位レイヤーに依存 ○(冗長化と排他)
動的なサーバーの追加 - ○(離脱できない) △(アクセスを停止させる必要がある)
動的なサイズの拡張 下位レイヤーに依存 × ×
動的なサイズの縮小 下位レイヤーに依存 × ×

ブロックデバイスレイヤー

NBD SCSI Linux RAID Linux LVM DRBD V-FIELD
下位レイヤー Block Device/File Disk Block Device Block Device Block Device File
読み込み
書き込み ×
アクセスの冗長化 × × ×
データの冗長化 下位レイヤーに依存 下位レイヤーに依存 下位レイヤーに依存 -(書き込みできない)
読み込みの負荷分散 × × × ○(8.x)
書き込みの負荷分散 × × × ○(8.x) -
動的なサーバー(ディスク)の追加 - - ×
動的なサイズの拡張 × × × × ×
動的なサイズの縮小 × × × × ×


アクセスの冗長化というのは、サーバーやディスクが落ちても問題なくアクセスを受け付けられるか否かです。データの冗長化は、サーバーやディスクが落ちたときにデータが保護されるか否かです。

面白いのはやっぱりGFSとOCFSで、分散ファイルシステムでありながら、下位レイヤーにブロックデバイスを使っています。Lustreもブロックデバイスですが、アクセスの冗長性がない(サービスを継続できない)のでとりあえず脇に。
開発元がそれぞれRedHatOracleということで、動的なファイルシステムサイズの拡大縮小もそのうち実装されそうです。

組み合わせる

必ずしも単独で使う必要はなく、複数を組み合わせて使うことができます。たとえば、下位レイヤーにブロックデバイスを使うOCFSと、ブロックデバイスであるSCSIは組み合わせることができます。むしろその組み合わせでの利用を前提とした組み合わせもありますし、突如として落ちるなどの問題が発生する組み合わせもあるかもしれません。
以下、私が勝手に考えた組み合わせも含めて列挙してみます。(左ほど下位のレイヤーです)

RAID + LVM + XFS/ext3/…

良くある組み合わせで、データの冗長化はできるが動的にサイズを変更できないRAIDと、データの冗長化はできないが動的にサイズが変更できるLVMと、動的にサイズを拡張できるファイルシステムを組み合わせる手法です。この方法はネットワークを越えないので、CPUなどなどが壊れるとアクセスが停止します。

DRBD + GFS/OCFS + NFS + keepalived/heartbeat

DRBD 8.xとGFSかOCFSを組み合わせる方法。サーバーは2台まで。

RAID + SCSI + GFS/OCFS

GFSやOCFSは、そもそもこの組み合わせでの利用が想定されています。SCSIプロトコルを通す物理層EthernetになるとIP-SAN、ファイバーチャネルになるとFC-SANと呼ばれます。
データの冗長化ができ、読み書きの負荷分散ができます。コントローラが故障すると全体が落ちるので、アクセスの冗長性はありません。コントローラがどれだけ頑丈であるかは、SCSIストレージベンダー依存というところでしょうか。

RAID + SCSI + RAID + GFS/OCFS

この組み合わせが実際に利用されているのかどうかは分からないですが、SCSIコントローラを多重化できるはずです。

NBD + RAID + OCFS

ファイバチャネルストレージはトンでもなく高い、iSCSIストレージも高い、ソフトウェアiSCSIは複雑、というわけで、信頼性のほどは分からないのですが、iSCSIの代わりにNBDを使う方法があります。
GFSは試していませんが、とりあえずOCFSは動きます。信頼性を持って動くかどうかは試していません。

(((NBD×rd + RAID 1)×n + RAID 0)×s + LVM + XFS/ext3/... + NFS)×ra + keepalived/heartbeat

私がほのかにコレはいけそうだ!と思っている方法です。アクセスの冗長化、データの冗長化、動的なファイルシステムサイズの拡張・縮小、動的な負荷分散、動的な冗長化が全部できます。試していませんが…。
rdはデータの多重化度、nは負荷分散度、sはファイルシステムサイズの係数、raはアクセスの多重化度です。KLab勉強会#2で紹介されているように、読み込みだけならNFSの代わりにHTTPでも良いはずです。
NBD×rd + RAID 1を一つのユニットとし、これをnユニット使ってRAID 0を作ります(要するにNBDでRAID 1+0です)。これをsセット使ってLVMを作ります。この上にXFSなどのファイルシステムを作り、NFSでエクスポートします。NFSではアクセスが冗長化されないので、RAID10+LVM+NFSを構成するノードをra台つくり、keepalivedかheartbeatで冗長化します。
データノードとNFSノードとわけると分かりやすいかもしれません。NBD×(rd+n+s)台がデータノードで、データノードをRAID10+LVM+XFSでまとめてNFSでエクスポートするノードがNFSノード。そしてNFSノードをアクティブ1台-スタンバイたくさんで冗長化します。
ファイルシステムサイズを増やしたいときは、データノードをrd+n台追加し、RAID10を組んでLVMに追加します。サービスを止めずにファイルシステムサイズを拡張できます。
また、LVMのsnapshot機能を使えば、サービスを止めずにバックアップが取れます。
組み合わせが多く、メンテナンス性が悪いのが難点。どこかにバグがあると泣ける。それからスマートさに欠けます。
GFS/OCFSやiSCSIなどの使うのに気合いが必要な技術はなく、NFSやRAIDなどの枯れた技術ばかりなので(NBDも相当枯れてます)、意外に把握しやすくて良いのかもしれません。一度イジメ倒しても落ちないかどうか、どのくらいの性能が出るか試してみたいところです。




取るべき道、作るべき将来

動的なサーバーの冗長化、動的な負荷分散、動的なファイルシステムサイズの拡張・縮小、そしてメンテナンス性をすべて兼ね備えたストレージは、現時点では構築できないようです。

では、何を補えば実現できるのか。方法は2つ考えられます。
1つは、GFSかOCFSに動的なファイルシステムサイズの拡張・縮小機能を追加し(あるいは追加されるのを待ち)、V-FIELDに書き込み機能を追加する方法。もう1つは、そもそも新しい分散ファイルシステムを作る方法です。
どちらを取るべきかは、非常に悩ましい問題です。

V-FIELDに書き込み機能を追加してGFSかOCFSと組み合わせる方法では、必然的にV-FIELD下位レイヤーはブロックデバイスになるので、V-FIELD + GFS/OCFSを通さないと、ファイルを読み取れません。V-FIELDにバグがあった場合、あるいは外部からのクラックで冗長化されたデータの整合性が破壊された場合、ファイルを復元できなくなる可能性があります(iSCSI+GFS/OCFSとは異なり、データが分散されています)

一方、新しい分散ファイルシステムを作るのは、実装が非常に困難です。1年やそこらではできないでしょう。しかしバグなどで分散ファイルシステムを構成できない状態に陥っても、下位レイヤーがファイルシステムであれば、データを人間の手で回収することができます。

…前者の実装も非常に困難なわけですが、ファイルシステムを1から作るのに比べれば、多少マシです。多少というのは、ロックとファイルシステムのインターフェースを作らなくて良い分です。