2011/10/23 執筆中。随時、追記していきます。
GlusterFSとは
GlusterFSって何?という方は、まずはこちらを参照ください。
これらを読めば分かるように、GlusterFSを使用すると、非常にシンプルに分散ファイルシステムをつくりあげることができます。一方、シンプルな仕組みだからこそ、「こんな時は、いったいどんな風になるの?」という素朴な疑問もわいてきます。
そんな素朴な疑問を実機確認しながら見ていきます。
事前準備
RHEL6用のGlusterFSがEPELに含まれているので、これを利用して3ノードのGlusterFSをさくっと構築しておきます。
gluster01, gluster02, gluster03の3ノードで以下の準備をします。
EPELのリポジトリ準備
# yum -y localinstall http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-5.noarch.rpm
GlusterFSのRPMを導入して、デーモンを起動
# yum install glusterfs-server glusterfs-fuse # chkconfig glusterd on # service glusterd start
これで導入完了。
gluster01を作業用ノードとします。ここから、他の2ノードをpeer登録してクラスタを構成します。
[root@gluster01 ~]# gluster peer probe gluster02 Probe successful [root@gluster01 ~]# gluster peer probe gluster03 Probe successful [root@gluster01 ~]# gluster peer status Number of Peers: 2 Hostname: gluster02 Uuid: a4658b45-d431-4458-adce-1c7351054da0 State: Peer in Cluster (Connected) Hostname: gluster03 Uuid: c1927294-86ae-4f0b-9eda-ff2f1bab6e77 State: Peer in Cluster (Connected)
ファイルのリネーム
GlusterFSでは、ファイル名のハッシュ値で、ファイルが保存されるノード(ブリック)が決まります。
じゃあ、ファイルをリネームして、保存ノードが変わったらどうなるの・・・???? ファイルをわざわざノード間で移動するの?
結論を先に言うと、わざわざノード間で移動しません。新しいノード上には、オリジナルのノードへのリンク情報を持ったダミーファイルが作成されます。クライアントがハッシュ計算で新しいノードを見に行くと、リンクがあるので、それを見てオリジナルのノードにアクセスします。
実際にやってみます。
まず、gluster01とgluster02の2ノードのブリックを使ったボリュームdata00を作成して、/mnt/data00にマウントします。
[root@gluster01 ~]# mkdir /disk01/brick01 [root@gluster01 ~]# ssh gluster02 mkdir /disk01/brick01 [root@gluster01 ~]# ssh gluster03 mkdir /disk01/brick01 [root@gluster01 ~]# gluster volume create data00 gluster01:/disk01/brick01 gluster02:/disk01/brick01 Creation of volume data00 has been successful. Please start the volume to access data. [root@gluster01 ~]# gluster volume start data00 Starting volume data00 has been successful [root@gluster01 ~]# gluster volume info data00 Volume Name: data00 Type: Distribute Status: Started Number of Bricks: 2 Transport-type: tcp Bricks: Brick1: gluster01:/disk01/brick01 Brick2: gluster02:/disk01/brick01 [root@gluster01 ~]# mkdir /mnt/data00 [root@gluster01 ~]# mount -t glusterfs localhost:/data00 /mnt/data00
file100.txt〜file199.txtを作成して、それぞれのノードに分散保存されることを確認します。
[root@gluster01 ~]# for a in $(seq 100 199);do date > /mnt/data00/file$a.txt;done [root@gluster01 ~]# ls /disk01/brick01/ file106.txt file116.txt file126.txt file145.txt file160.txt file176.txt file195.txt file107.txt file118.txt file127.txt file146.txt file161.txt file180.txt file197.txt file108.txt file119.txt file130.txt file150.txt file167.txt file183.txt file198.txt file109.txt file121.txt file134.txt file153.txt file170.txt file185.txt file199.txt file112.txt file122.txt file138.txt file155.txt file171.txt file187.txt file113.txt file123.txt file139.txt file156.txt file172.txt file188.txt file114.txt file124.txt file142.txt file157.txt file174.txt file190.txt file115.txt file125.txt file144.txt file158.txt file175.txt file193.txt [root@gluster02 ~]# ls /disk01/brick01/ file100.txt file117.txt file136.txt file151.txt file166.txt file182.txt file101.txt file120.txt file137.txt file152.txt file168.txt file184.txt file102.txt file128.txt file140.txt file154.txt file169.txt file186.txt file103.txt file129.txt file141.txt file159.txt file173.txt file189.txt file104.txt file131.txt file143.txt file162.txt file177.txt file191.txt file105.txt file132.txt file147.txt file163.txt file178.txt file192.txt file110.txt file133.txt file148.txt file164.txt file179.txt file194.txt file111.txt file135.txt file149.txt file165.txt file181.txt file196.txt
gluster01に作成されたファイル、gluster02に作成されたファイルをそれぞれ適当にリネームしてみます。
[root@gluster01 ~]# mv /mnt/data00/file106.txt /mnt/data00/file206.txt [root@gluster01 ~]# mv /mnt/data00/file107.txt /mnt/data00/file207.txt [root@gluster01 ~]# mv /mnt/data00/file100.txt /mnt/data00/file200.txt [root@gluster01 ~]# mv /mnt/data00/file101.txt /mnt/data00/file201.txt
まちがって、ブリック上のファイルを直接リネームしないように。。。GlusterFSとしてマウントした方でリネームしてください。
結果を見ると、file207.txtがgluster02に移動して、file200.txtがgluster01に移動したようです。
次のように、元のノードのファイルがリネームされると同時に、相手ノードにファイルサイズ0の同名ファイルができています。
[root@gluster01 /]# ls -l /disk01/brick01/file207.txt -rw-r--r--. 1 root root 43 10月 23 16:19 2011 /disk01/brick01/file207.txt [root@gluster01 /]# ssh gluster02 ls -l /disk01/brick01/file207.txt ---------T. 1 root root 0 10月 23 16:20 2011 /disk01/brick01/file207.txt [root@gluster01 /]# ls -l /disk01/brick01/file200.txt ---------T. 1 root root 0 10月 23 16:45 2011 /disk01/brick01/file200.txt [root@gluster01 /]# ssh gluster02 ls -l /disk01/brick01/file200.txt -rw-r--r--. 1 root root 43 10月 23 16:19 2011 /disk01/brick01/file200.txt
GlusterFSでは、ファイルの拡張属性にさまざまなメタ情報を記録しています。ファイルサイズ0のファイルの拡張属性を見ると、本体へのリンク情報が入っています。
[root@gluster01 /] # ssh gluster02 getfattr -d -m . /disk01/brick01/file207.txt getfattr: Removing leading '/' from absolute path names # file: disk01/brick01/file207.txt security.selinux="unconfined_u:object_r:default_t:s0 trusted.gfid=0sj3QA5n6STBSESrT6pJW5dw== trusted.glusterfs.dht.linkto="data00-client-0 [root@gluster01 /]# getfattr -d -m . /disk01/brick01/file200.txt getfattr: Removing leading '/' from absolute path names # file: disk01/brick01/file200.txt security.selinux="unconfined_u:object_r:default_t:s0 trusted.gfid=0sJ06VrvJfRYyp2LSM+CImeg== trusted.glusterfs.dht.linkto="data00-client-1
上記の"trusted.glusterfs.dht.linkto"がリンク情報で、"
ボリュームの拡張
GlusterFSは、ボリュームを構成するブリックを追加して、動的にボリュームを拡張することができます。当然ながら、ブリックが増えるとハッシュ計算が変わって、ファイルの配置が変わります。ファイルの配置変更を動的にやることって可能なんでしょうか?
実際にやってみます。
先に作成したボリュームdata00に、gluster03のブリックを追加します。
[root@gluster01 /]# ssh gluster03 mkdir /disk01/brick01 [root@gluster01 /]# gluster volume add-brick data00 gluster03:/disk01/brick01
実は、追加しただけでは、ハッシュ計算の変更は行われません。いままで通りに、gluster01とgluster02のブリックのみが使用され続けます。
次のように新しいファイルを追加しても、gluster03のブリックには何も保存されません。
[root@gluster01 ~]# for a in $(seq 300 399);do date > /mnt/data00/file$a.txt;done
明示的にrebalance処理を実行することで、ファイルの配置変更とハッシュ計算の変更が行われます。
・・・って、rebalanceの実行中は、どうなるの? 動的なrebalanceって、難しくない?
という疑問に答えるために、rebalanceを開始して、即座に一時中止してみます。
[root@gluster01 ~]# gluster volume rebalance data00 start; gluster volume rebalance data00 stop starting rebalance on volume data00 has been successful stopped rebalance process of volume data00 (after rebalancing 0 files totaling 0 bytes)
この時、gluster03のブリックの中を見ると、例のリンクファイルが作成されています。
[root@gluster03 ~]# ls -l /disk01/brick01/ 合計 4 ---------T. 1 root root 0 10月 23 17:35 2011 file175.txt
そうなんです、rebalanceを開始すると、まずは、新しいファイル配置にあわせて、例のリンクファイルを作りまくります。で、リンクファイルが全部できたところで、ハッシュ計算の変更をクライアントに通知します。
この後、ゆっくりと、実際にファイルを移動して、移動が終わったらリンクファイルを削除します。移動前のファイルは、リンクによって正しくアクセスできるので心配ありません。万一、移動中にオリジナルファイルに書き込みがはいった場合は、ファイルの移動をやめて、リンクファイルをそのまま残します。
実際に、さらに5秒ほどrebalance処理を進めて、また中断してみます。
[root@gluster01 ~]# gluster volume rebalance data00 start; sleep 5;gluster volume rebalance data00 stop starting rebalance on volume data00 has been successful stopped rebalance process of volume data00 (after rebalancing 131 files totaling 5633 bytes)
この時、gluster03のブリックを見ると、移動前のリンクファイルと移動が終わったファイルが入り乱れています。
[root@gluster03 ~]# ls -l /disk01/brick01/ 合計 432 -rw-r--r--. 1 root root 43 10月 23 17:37 2011 file102.txt -rw-r--r--. 1 root root 43 10月 23 17:37 2011 file103.txt -rw-r--r--. 1 root root 43 10月 23 17:37 2011 file113.txt ---------T. 1 root root 0 10月 23 17:37 2011 file120.txt -rw-r--r--. 1 root root 43 10月 23 17:37 2011 file122.txt -rw-r--r--. 1 root root 43 10月 23 17:37 2011 file124.txt -rw-r--r--. 1 root root 43 10月 23 17:37 2011 file127.txt -rw-r--r--. 1 root root 43 10月 23 17:37 2011 file129.txt -rw-r--r--. 1 root root 43 10月 23 17:37 2011 file134.txt ---------T. 1 root root 0 10月 23 17:37 2011 file136.txt -rw-r--r--. 1 root root 43 10月 23 17:37 2011 file137.txt -rw-r--r--. 1 root root 43 10月 23 17:37 2011 file140.txt -rw-r--r--. 1 root root 43 10月 23 17:37 2011 file142.txt -rw-r--r--. 1 root root 43 10月 23 17:37 2011 file144.txt ---------T. 1 root root 0 10月 23 17:37 2011 file154.txt -rw-r--r--. 1 root root 43 10月 23 17:37 2011 file156.txt ---------T. 1 root root 0 10月 23 17:37 2011 file162.txt ---------T. 1 root root 0 10月 23 17:37 2011 file166.txt (以下略)
この後、rebalance処理を最後まで実行すれば、きれいな状態になります。
[root@gluster01 ~]# gluster volume rebalance data00 start
※先のリネーム処理によって作成されたリンクは、rebalance処理では移動されないようです。
特定ブリックを使い切った場合
ストライピング構成にした場合は、すべてのブリックが均等に使用されます。したがって、最初にブリックの容量をそろえておけば、特定のブリックだけを先に使い切ることはありません。
一方、ストライピングしない、ファイル単位の分散の場合は大容量ファイルが保存されたブリックが先に使用量100%になることがあります。この場合は残念ながら、使用量100%のブリックのファイルに書きこみを行うと容量不足でエラーになります。
この例では、ボリューム全体(/mnt/data01)としては空き容量がありますが、gluster01のブリック(/disk01)は100%なので、そちらにあるファイルに書きこむとエラーになります。
[root@gluster01 ~]# ls -l /mnt/data01 合計 93901 -rw-r--r-- 1 root root 45694976 11月 19 14:23 2011 bigfile01 -rw-r--r-- 1 root root 50454560 11月 19 14:23 2011 bigfile02 [root@gluster01 ~]# cat /mnt/data01/bigfile01 >> /mnt/data01/bigfile02 cat: 書き込みエラー: デバイスに空き領域がありません cat: 書き込みエラー: デバイスに空き領域がありません [root@gluster01 ~]# df Filesystem 1K-ブロック 使用 使用可 使用% マウント位置 /dev/vda2 4128448 1751404 2167332 45% / tmpfs 510788 0 510788 0% /dev/shm /dev/vda1 198337 26718 161379 15% /boot /dev/vda4 99553 99553 0 100% /disk01 localhost:/data01 1131520 133632 945408 13% /mnt/data01
一方、gluster02に保存されたファイルには、まだ書き込みができます。
[root@gluster01 ~]# cat /mnt/data01/bigfile01 >> /mnt/data01/bigfile03 [root@gluster01 ~]# ssh gluster02 ls -l /disk01/brick01/ 合計 44628 -rw-r--r-- 1 root root 45695019 11月 19 14:26 2011 bigfile03 [root@gluster01 ~]# ssh gluster02 df Filesystem 1K-ブロック 使用 使用可 使用% マウント位置 /dev/vda2 4128448 1748604 2170132 45% / tmpfs 510788 0 510788 0% /dev/shm /dev/vda1 198337 26718 161379 15% /boot /dev/vda4 1032056 78688 900904 9% /disk01