先日、もう社内勉強会でいいや的な何か(仮)で、GlusterFS について話したりデモしたりしたときの資料が出てきたので置いておきます。
212 番煎じぐらいで真新しいものではありません。
GlusterFS とは
- いわゆる分散ファイルシステム
- 分散並列フォールトトレラントファイルシステム
- POSIX互換(ファイルシステムとしてマウントできる)
- 当初は Gluster, Inc. で開発されていたが Red Hat に買収された
- RHEL では Red Hat Gluster Storage という名前になっている
- ネームノードとかメタデータノードとか分散ロックマネージャーとかのようなノードが無い
- クライアントががんばる
- レプリケーションもクライアントががんばって全部に書き込んでいる
- NFS のように普通のファイルシステムの上に分散ファイルシステムが構築される
- 必要なメタ情報はファイルシステムの拡張属性に保存される
- ので、下位ファイルシステムはある程度限定される(xfs/ext4/etc..)
- ので、下位ファイルシステム上には分散ファイルシステム上のファイルがそのまま見える
- レプリケーションやストライピングも可能
- レプリケーションで HA にすることもできる
- 復帰時の再レプリケーションも簡単
- ストライピングは1つのファイルを分散配置できる
- ファイル単位の分散配置もできる
- ファイルシステムなのにユーザー空間で動く
- ライブラリ(libglusterfs)を用いて直接アクセスも可能
- NFS でもマウントできる
- REST API でもアクセス可能
- 小さいファイルが大量にあるのは苦手
- 大きなファイルが少量が得意
- ストライプドじゃなくても大きいファイルは得意なのか?
用語とか
- ブリック
- GlusterFS が使う下位ファイルシステム上のディレクトリ
- ファイルシステムは XFS を奨励
- ボリューム
- 複数のノードのブリックで構成された GlusterFS 上の仮想的なボリューム
- ディストリビューテッドボリューム
- 複数のブリックにファイルを分散して配置する
- ファイル単位で配置が分散される(ストライピングではない)
- レプリケーテッドボリューム
- 複数のブリックに同じファイルを複製して配置する
- 可用性を求めるなら必須
- ストライプドボリューム
- 複数のブリックに一つのファイルを分散して配置する
- いわゆるストライピング
- あまり奨励されていない?(実験的?)
- 消し飛んでも構わないファイル用?
- ヒーリングデーモン
- レプリケーテッドで整合性が失われた時に自動的に復旧するためのデーモン
- リバランス
- ボリュームにブリックを追加/削除したときにファイルを再配置すること
- 手動で実行する必要がある(自動でリバランスはされない)
インストール
CentOS のリポジトリに GlusterFS 関連のパッケージが幾つかあるのですが・・なぜか glusterfs-server が無いので使えません。
yum list | grep ^glusterfs
glusterfs.x86_64 3.6.0.29-2.el7 base
glusterfs-api.x86_64 3.6.0.29-2.el7 base
glusterfs-api-devel.x86_64 3.6.0.29-2.el7 base
glusterfs-cli.x86_64 3.6.0.29-2.el7 base
glusterfs-devel.x86_64 3.6.0.29-2.el7 base
glusterfs-fuse.x86_64 3.6.0.29-2.el7 base
glusterfs-libs.x86_64 3.6.0.29-2.el7 base
glusterfs-rdma.x86_64 3.6.0.29-2.el7 base
なので、GlusterFS の yum リポジトリの設定をダウンロードします
cd /etc/yum.repos.d/
wget http://download.gluster.org/pub/gluster/glusterfs/LATEST/CentOS/glusterfs-epel.repo
サーバには glusterfs-server
をインストールします
yum -y install glusterfs-server
クライアント(マウントする側)は glusterfs-fuse
だけで十分です。
yum -y install glusterfs-fuse
下記のバージョンがインストールされました。
glusterfs.x86_64 3.7.3-1.el7 @glusterfs-epel
glusterfs-api.x86_64 3.7.3-1.el7 @glusterfs-epel
glusterfs-cli.x86_64 3.7.3-1.el7 @glusterfs-epel
glusterfs-client-xlators.x86_64 3.7.3-1.el7 @glusterfs-epel
glusterfs-fuse.x86_64 3.7.3-1.el7 @glusterfs-epel
glusterfs-libs.x86_64 3.7.3-1.el7 @glusterfs-epel
glusterfs-server.x86_64 3.7.3-1.el7 @glusterfs-epel
Vagrant box
ここまでの作業が適用された Vagrant box を作成します。
Vagrant.configure(2) do |config|
config.vm.box = "ngyuki/centos-7"
config.vm.provision "shell", inline: <<-SHELL
cd /etc/yum.repos.d/
wget http://download.gluster.org/pub/gluster/glusterfs/LATEST/CentOS/glusterfs-epel.repo
yum -y install glusterfs-server glusterfs-fuse
yum clean all
SHELL
config.vm.provider :virtualbox do |vb|
file_to_disk = "#{ENV["HOME"]}/glusterfs.vdi"
unless File.exist?(file_to_disk)
vb.customize ['createhd', '--filename', file_to_disk, '--size', 20 * 1024]
vb.customize ['storageattach', :id,
'--storagectl', 'SATA Controller',
'--port', 1,
'--device', 0,
'--type', 'hdd',
'--medium', file_to_disk]
end
end
end
provision で glusterfs-server と glusterfs-fuse をインストールし、さらに GlusterFS のためのディスクを作成してアタッチしています。
glusterfs という名前で Box を作成&追加します。
vagrant up
vagrant package --output ~/glusterfs.box
vagrant box add glusterfs ~/glusterfs.box --force
rm -f ~/glusterfs.box
vagrant destroy -f
Vagrant up
次の Vagrantfile で4台の GlusterFS のノードと、GlusterFS をマウントする1台のクライアントを作成します。
Vagrant.configure(2) do |config|
config.vm.box = "glusterfs"
config.vm.define :g1 do |cfg|
cfg.vm.hostname = "g1"
cfg.vm.network "private_network", ip: "192.168.33.11", virtualbox__intnet: "glusterfs"
end
config.vm.define :g2 do |cfg|
cfg.vm.hostname = "g2"
cfg.vm.network "private_network", ip: "192.168.33.12", virtualbox__intnet: "glusterfs"
end
config.vm.define :g3 do |cfg|
cfg.vm.hostname = "g3"
cfg.vm.network "private_network", ip: "192.168.33.13", virtualbox__intnet: "glusterfs"
end
config.vm.define :g4 do |cfg|
cfg.vm.hostname = "g4"
cfg.vm.network "private_network", ip: "192.168.33.14", virtualbox__intnet: "glusterfs"
end
config.vm.define :cl do |cfg|
cfg.vm.hostname = "cl"
cfg.vm.network "private_network", ip: "192.168.33.21", virtualbox__intnet: "glusterfs"
end
end
起動します。
vagrant up
すべてのゲストに ssh で接続します。
vagrant ssh g1
vagrant ssh g2
vagrant ssh g3
vagrant ssh g4
vagrant ssh cl
起動
ゲストの hosts にノードの一覧を追記しておきます。
cat <<EOS> /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
192.168.33.11 g1
192.168.33.12 g2
192.168.33.13 g3
192.168.33.14 g4
192.168.33.21 cl
EOS
glusterfs-server の インストール時に /var/lib/glusterd/glusterd.info というファイルの中にノードの UUID が作成されています。
cat /var/lib/glusterd/glusterd.info
UUID=7096ff3d-e640-494f-8409-b0fa52e74b8c
operating-version=30702
この値はクラスタのノードで重複しないようにする必要があります。もし、共通の AMI などからインスタンスを作ったのであれば、UUID が重複しないように GlusterFS の起動前にこのファイルを削除しておく必要があります。
今回は Vagrant box から起動したため重複しています。なので次のように削除しておきます。
rm -f /var/lib/glusterd/glusterd.info
と、思ったんだけど作成されていなかった。。。
3.7.2 で検証してたときはインストール時に作成されていた気がするのだけど・・?
3.7.3 から変わったのか、あるいは勘違いしていたのか・・・
GlusterFS のデーモンを起動します。
systemctl enable glusterd.service
systemctl start glusterd.service
systemctl status glusterd.service
起動時に UUID は自動生成されます。
初回の起動時にも /var/lib/glusterd/glusterd.info
は作成されなくて、gluster pool list
したら作成されました。
gluster pool list
cat /var/lib/glusterd/glusterd.info
Brick の作成
適当なディレクトリにファイルの置き場所となる Brick(ブリック)を作ります。
追加ディスクにパーティションを切ります。動作要件に i-node サイズが 512B とあるらしいのでファイルシステムの作成時に指定します。
parted -s -a optimal /dev/sdb mklabel msdos -- mkpart primary xfs 1 -1
mkfs.xfs -i size=512 /dev/sdb1
mkdir -p /glfs/vols
cat <<EOS>>/etc/fstab
/dev/sdb1 /glfs/vols xfs defaults 0 0
EOS
mount /glfs/vols
ブリックのディレクトリを作成します。
mkdir -p /glfs/vols/data
GlusterFS クラスタ
GlusterFS のノードでクラスタを組んでストレージプールを作ります。
gluster peer status
でクラスタのピア数を表示してみます。
gluster peer status
まだ 0 個です、つまり自分以外は居ません。
Number of Peers: 0
gluster pool list
でノードの一覧を表示してみます。
gluster pool list
自分しか表示されません。
UUID Hostname State
89a1b9b4-f7e0-4091-aeff-80279d8c0024 localhost Connected
gluster peer probe <remote>
でピアを追加できます。下記を g1 で実行してみます。
gluster peer probe g2
gluster peer probe g3
gluster peer probe g4
成功したっぽいメッセージが表示されます。
peer probe: success.
もう一度 gluster peer status
とか gluster pool list
とかを実行してみると、それっぽく表示されます。
gluster peer status
Number of Peers: 3
Hostname: g2
Uuid: 9256e049-e3f9-43a7-9fda-3ce631d4e5c1
State: Peer in Cluster (Connected)
Hostname: g3
Uuid: 9a5eaa0d-3db9-40af-a58e-e5caa804cb78
State: Peer in Cluster (Connected)
Hostname: g4
Uuid: 8fde5fcc-2e33-489b-976f-76171fcd162f
State: Peer in Cluster (Connected)
gluster pool list
UUID Hostname State
9256e049-e3f9-43a7-9fda-3ce631d4e5c1 g2 Connected
9a5eaa0d-3db9-40af-a58e-e5caa804cb78 g3 Connected
8fde5fcc-2e33-489b-976f-76171fcd162f g4 Connected
89a1b9b4-f7e0-4091-aeff-80279d8c0024 localhost Connected
Volume を作成
ボリュームを作成します。
この例だと、ボリュームの名前は data
で、g1=g2 と g3=g4 がそれぞれレプリカで、それぞれの組にファイルが分散されます。
gluster volume create data replica 2 \
g1:/glfs/vols/data \
g2:/glfs/vols/data \
g3:/glfs/vols/data \
g4:/glfs/vols/data
正常に作成されれば次のようなメッセージが表示されます。
volume create: data: success: please start the volume to access data
ボリュームを開始します。
gluster volume start data
正常に開始されれば次のようなメッセージが表示されます。
volume start: data: success
ボリュームの情報を見てみます。
gluster volume info data
それっぽい内容が表示されます。
Volume Name: data
Type: Distributed-Replicate
Volume ID: 48bf6f46-c6d8-4743-b65e-4ecba2e27969
Status: Started
Number of Bricks: 2 x 2 = 4
Transport-type: tcp
Bricks:
Brick1: g1:/glfs/vols/data
Brick2: g2:/glfs/vols/data
Brick3: g3:/glfs/vols/data
Brick4: g4:/glfs/vols/data
Options Reconfigured:
performance.readdir-ahead: on
ボリュームのステータスを見てみます。
gluster volume status data
それっぽい内容が表示されます。
Status of volume: data
Gluster process TCP Port RDMA Port Online Pid
------------------------------------------------------------------------------
Brick g1:/glfs/vols/data 49152 0 Y 2800
Brick g2:/glfs/vols/data 49152 0 Y 2752
Brick g3:/glfs/vols/data 49152 0 Y 2754
Brick g4:/glfs/vols/data 49152 0 Y 2753
NFS Server on localhost N/A N/A N N/A
Self-heal Daemon on localhost N/A N/A Y 2828
NFS Server on g4 N/A N/A N N/A
Self-heal Daemon on g4 N/A N/A Y 2781
NFS Server on g2 N/A N/A N N/A
Self-heal Daemon on g2 N/A N/A Y 2780
NFS Server on g3 N/A N/A N N/A
Self-heal Daemon on g3 N/A N/A Y 2782
Task Status of Volume data
------------------------------------------------------------------------------
There are no active volume tasks
クライアントからマウント
クライアントのノードからマウントしてみます。まずマウントポイントを作ります。
mkdir -p /glfs/data
適当なノードを指定してマウントする必要があります。そのため、次の例では g1 が停止しているとマウントに失敗します。
mount -t glusterfs g1:/data /glfs/data
次のようにマウントオプションを指定すると、g1 が停止しているときは g2 にフォールバックされるようにできます。
mount -t glusterfs g1:/data /glfs/data -o backupvolfile-server=g2
一旦マウントしてしまえばどのノードをマウントで指定したかは関係なくなるので、前者の方法でも g1 が SPOF になるというわけではありませんが・・どうせなら後者の方が良いと思います。
replica運用してるglusterfsボリュームでmount時のフォールバックオプションを付ける - Qiita
動作確認
クライアントから適当に書き込んでみます。
echo 1 > /glfs/data/1.txt
echo 2 > /glfs/data/2.txt
echo 3 > /glfs/data/3.txt
echo 4 > /glfs/data/4.txt
g1 や g2 のブリックを確認してみると、
ssh g1 ls -l /glfs/vols/data
ssh g2 ls -l /glfs/vols/data
-rw-r--r-- 2 root root 2 7月 3 16:48 4.txt
両方に 4.txt だけが保存されています。
g3 や g4 のブリックを確認してみると、
ssh g3 ls -l /glfs/vols/data
ssh g4 ls -l /glfs/vols/data
両方に残りのファイルが保存されています。
-rw-r--r-- 2 root root 2 7月 3 16:48 1.txt
-rw-r--r-- 2 root root 2 7月 3 16:48 2.txt
-rw-r--r-- 2 root root 2 7月 3 16:48 3.txt
レプリケーション&分散配置されています。
ノード障害時の動作
Vagrant のホストから、おもむろに g1 を強制終了します。
vagrant halt -f g1
適当なノード(例えば g2)から、ストレージプールの状態などを確認してみます。
gluster peer status
すると g1 が Disconnected になっています。
gluster peer status
Number of Peers: 3
Hostname: g1
Uuid: 89a1b9b4-f7e0-4091-aeff-80279d8c0024
State: Peer in Cluster (Disconnected)
Hostname: g3
Uuid: 9a5eaa0d-3db9-40af-a58e-e5caa804cb78
State: Peer in Cluster (Connected)
Hostname: g4
Uuid: 8fde5fcc-2e33-489b-976f-76171fcd162f
State: Peer in Cluster (Connected)
gluster pool list
でも同上です。
gluster pool list
UUID Hostname State
89a1b9b4-f7e0-4091-aeff-80279d8c0024 g1 Disconnected
9a5eaa0d-3db9-40af-a58e-e5caa804cb78 g3 Connected
8fde5fcc-2e33-489b-976f-76171fcd162f g4 Connected
9256e049-e3f9-43a7-9fda-3ce631d4e5c1 localhost Connected
gluster volume status data
だと g1 がいません。
gluster volume status data
Status of volume: data
Gluster process TCP Port RDMA Port Online Pid
------------------------------------------------------------------------------
Brick g2:/glfs/vols/data 49152 0 Y 2752
Brick g3:/glfs/vols/data 49152 0 Y 2754
Brick g4:/glfs/vols/data 49152 0 Y 2753
NFS Server on localhost N/A N/A N N/A
Self-heal Daemon on localhost N/A N/A Y 2780
NFS Server on g4 N/A N/A N N/A
Self-heal Daemon on g4 N/A N/A Y 2781
NFS Server on g3 N/A N/A N N/A
Self-heal Daemon on g3 N/A N/A Y 2782
Task Status of Volume data
------------------------------------------------------------------------------
There are no active volume tasks
いかにも g1 が死んでいる風になっていますが、g1 と g2 でレプリカになっているはずなのでクライアントから読み書きできるか試してみます。
クライアントからファイルを読んでみると・・なにごともなく読むことができます。
cat /glfs/data/1.txt
cat /glfs/data/2.txt
cat /glfs/data/3.txt
cat /glfs/data/4.txt
次はファイルを書き込んでみると・・なにごともなく書き込むことができます。
echo 5 > /glfs/data/5.txt
echo 6 > /glfs/data/6.txt
echo 7 > /glfs/data/7.txt
echo 8 > /glfs/data/8.txt
生きているノードのブリックを確認してみます。
まずは g2。
ssh g2 ls -l /glfs/vols/data
-rw-r--r-- 2 root root 2 7月 3 16:48 4.txt
-rw-r--r-- 2 root root 2 7月 3 16:58 8.txt
次は g3。
ssh g3 ls -l /glfs/vols/data
-rw-r--r-- 2 root root 2 7月 3 16:48 1.txt
-rw-r--r-- 2 root root 2 7月 3 16:48 2.txt
-rw-r--r-- 2 root root 2 7月 3 16:48 3.txt
-rw-r--r-- 2 root root 2 7月 3 16:58 5.txt
-rw-r--r-- 2 root root 2 7月 3 16:58 6.txt
-rw-r--r-- 2 root root 2 7月 3 16:58 7.txt
さらに g4。
ssh g4 ls -l /glfs/vols/data
-rw-r--r-- 2 root root 2 7月 3 16:48 1.txt
-rw-r--r-- 2 root root 2 7月 3 16:48 2.txt
-rw-r--r-- 2 root root 2 7月 3 16:48 3.txt
-rw-r--r-- 2 root root 2 7月 3 16:58 5.txt
-rw-r--r-- 2 root root 2 7月 3 16:58 6.txt
-rw-r--r-- 2 root root 2 7月 3 16:58 7.txt
g2 に保存されたファイルは g2 にしか存在しない状態です。
ノード復帰時の動作
Vagrant ホストから g1 を復帰させます。
vagrant up g1
vagrant ssh g1
適当なノード(例えば g2)からいろいろ確認してみます。
gluster peer status
で見ると g1 が Connected になっています。
gluster peer status
Number of Peers: 3
Hostname: 192.168.33.11
Uuid: 89a1b9b4-f7e0-4091-aeff-80279d8c0024
State: Peer in Cluster (Connected)
Hostname: g3
Uuid: 9a5eaa0d-3db9-40af-a58e-e5caa804cb78
State: Peer in Cluster (Connected)
Hostname: g4
Uuid: 8fde5fcc-2e33-489b-976f-76171fcd162f
State: Peer in Cluster (Connected)
gluster pool list
も同上です。
gluster pool list
UUID Hostname State
89a1b9b4-f7e0-4091-aeff-80279d8c0024 g1 Connected
9a5eaa0d-3db9-40af-a58e-e5caa804cb78 g3 Connected
8fde5fcc-2e33-489b-976f-76171fcd162f g4 Connected
9256e049-e3f9-43a7-9fda-3ce631d4e5c1 localhost Connected
gluster volume status data
にも g1 が追加されています。
gluster volume status data
Status of volume: data
Gluster process TCP Port RDMA Port Online Pid
------------------------------------------------------------------------------
Brick g1:/glfs/vols/data 49152 0 Y 1055
Brick g2:/glfs/vols/data 49152 0 Y 2752
Brick g3:/glfs/vols/data 49152 0 Y 2754
Brick g4:/glfs/vols/data 49152 0 Y 2753
NFS Server on localhost N/A N/A N N/A
Self-heal Daemon on localhost N/A N/A Y 2780
NFS Server on g4 N/A N/A N N/A
Self-heal Daemon on g4 N/A N/A Y 2781
NFS Server on 192.168.33.11 N/A N/A N N/A
Self-heal Daemon on 192.168.33.11 N/A N/A Y 2212
NFS Server on g3 N/A N/A N N/A
Self-heal Daemon on g3 N/A N/A Y 2782
Task Status of Volume data
------------------------------------------------------------------------------
There are no active volume tasks
ただし、まだ g1 と g2 は同期されていません。g1 が停止していた間のファイルは g1 にはありません。
ssh g1 ls -l /glfs/vols/data
-rw-r--r-- 2 root root 2 7月 3 16:48 4.txt
ssh g2 ls -l /glfs/vols/data
-rw-r--r-- 2 root root 2 7月 3 16:48 4.txt
-rw-r--r-- 2 root root 2 7月 3 16:58 8.txt
クライアントからそのファイルを読み込むと g1 のブリックにファイルが複製されました。
他にも次のようなタイミングで同期されます。
- Self-heal daemon によって自動的に
gluster volume heal <volume>
で手動で開始
ノードの交換
Vagrant のホストから、おもむろに g1 をぶっ壊して作り直します。
vagrant destroy g1
vagrant up g1
vagrant ssh g1
g1 を再セットアップします。まず、hosts を更新します。
cat <<EOS> /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
192.168.33.11 g1
192.168.33.12 g2
192.168.33.13 g3
192.168.33.14 g4
192.168.33.21 cl
EOS
適当な他のノードから、以前の g1 の UUID を調べます。
ssh g2 gluster pool list
新規の g1 の UUID を↑で調べた値に変更します。
vim /var/lib/glusterd/glusterd.info
UUID=89a1b9b4-f7e0-4091-aeff-80279d8c0024
operating-version=30703
ブリックを作ります。
parted -s -a optimal /dev/sdb mklabel msdos -- mkpart primary xfs 1 -1
mkfs.xfs -i size=512 /dev/sdb1
mkdir -p /glfs/vols
cat <<EOS>>/etc/fstab
/dev/sdb1 /glfs/vols xfs defaults 0 0
EOS
mount /glfs/vols
mkdir -p /glfs/vols/data
glusterd を起動します。
systemctl enable glusterd.service
systemctl start glusterd.service
systemctl status glusterd.service
g1 から g1 以外のすべてに gluster peer probe
します。
gluster peer probe g2
gluster peer probe g3
gluster peer probe g4
gluster pool list
で確認するとクラスタが復帰していることがわかります。
gluster pool list
これだけだとボリュームの情報が g1 に無いことがあるようです。
gluster volume list
そんなときは glusterd を再起動すると良いようです(gluster volume sync g2 all
でもいいのかもしれない?)。
systemctl stop glusterd.service
systemctl start glusterd.service
ボリュームの情報が得られることを確認します。
gluster volume info data
なぜか gluster volume status data
で見るとボリュームが Online になっていないことがあります。
gluster volume status data
Status of volume: data
Gluster process TCP Port RDMA Port Online Pid
------------------------------------------------------------------------------
Brick g1:/glfs/vols/data N/A N/A N N/A
Brick g2:/glfs/vols/data 49152 0 Y 2794
Brick g3:/glfs/vols/data 49152 0 Y 2754
Brick g4:/glfs/vols/data 49152 0 Y 2753
...snip...
そんなときは glusterd を再起動すると良い?らしい??です???(さっきもしたけど・・)
systemctl stop glusterd.service
systemctl start glusterd.service
3.4.0 以降だとこれでもダメなようです。
このとき、ブリックのログに次のように記録されています。
[2015-07-14 05:59:08.521960] E [posix.c:6012:init] 0-data-posix: Extended attribute trusted.glusterfs.volume-id is absent
[2015-07-14 05:59:08.521972] E [xlator.c:426:xlator_init] 0-data-posix: Initialization of volume 'data-posix' failed, review your volfile again
[2015-07-14 05:59:08.521978] E [graph.c:322:glusterfs_graph_init] 0-data-posix: initializing translator failed
[2015-07-14 05:59:08.521983] E [graph.c:661:glusterfs_graph_activate] 0-graph: init failed
[2015-07-14 05:59:08.522710] W [glusterfsd.c:1219:cleanup_and_exit] (--> 0-: received signum (0), shutting down
ブリックのディレクトリに trusted.glusterfs.volume-id
拡張属性が無いためらしいのですが、次のコマンドで再生成できます。
gluster volume start data force
今度こそボリュームがオンラインになっていることを確認します。
gluster volume status data
Status of volume: data
Gluster process TCP Port RDMA Port Online Pid
------------------------------------------------------------------------------
Brick g1:/glfs/vols/data 49153 0 Y 3281
Brick g2:/glfs/vols/data 49152 0 Y 2794
Brick g3:/glfs/vols/data 49152 0 Y 2754
Brick g4:/glfs/vols/data 49152 0 Y 2753
...snip...
オンラインになっても自動的に同期はされません。
ll /glfs/vols/data/
total 0
gluster volume heal <volume> full
で再同期します。
gluster volume heal data full
Launching heal operation to perform full self heal on volume data has been successful
Use heal info commands to check status
ご覧の通りです。
ll /glfs/vols/data/
total 4
-rw-r--r-- 2 root root 0 Jul 7 20:15 4.txt
-rw-r--r-- 2 root root 29 Jul 7 20:15 8.txt
の、はずなんですが、3.7.3 にバージョンアップしたらなぜか上手く行きませんでした、ディレクトリが空のままです。
マウントしているクライアントからファイルのアクセスするとレプリケートされましたけど・・・??
さらにブリックの拡張属性を見てみると trusted.glusterfs.dht
がなかったりするし・・・いっそのこと rsync で --xattr
を付けて拡張属性ごとブリックをコピーしてしまえばいいのだろうか??
古いメモ
これはだいぶ前に検証したときのメモです。
分散ハッシュテーブル
ファイル名を元にハッシュ値が計算される。ハッシュ値を元にどのブリックに保存するかが決定される。
ハッシュテーブルはディレクトリごとに異なる。
ハッシュレンジはディレクトリの拡張属性に保存される。
getfattr -d -m . /glfs/vols/data/
getfattr: Removing leading '/' from absolute path names
# file: glfs/vols/data/
trusted.afr.data-client-0=0sAAAAAAAAAAAAAAAA
trusted.afr.data-client-1=0sAAAAAAAAAAAAAAAA
trusted.afr.dirty=0sAAAAAAAAAAAAAAAA
trusted.gfid=0sAAAAAAAAAAAAAAAAAAAAAQ==
trusted.glusterfs.dht=0sAAAAAQAAAAAAAAAA/////w==
trusted.glusterfs.volume-id=0sE6WciNVBR7ekZgK1wu3xgw==
ファイルをリネームしてハッシュ値が変わり、別のブリックに保存される事になった場合、新しい保存先のブリックには sticky ビットのついた空のファイルが作成されて、拡張属性で元のブリックへのリンクが記録される。
ll 9.txt
---------T 2 root root 0 12月 13 17:12 9.txt
getfattr -n trusted.glusterfs.dht.linkto 9.txt
# file: 9.txt
trusted.glusterfs.dht.linkto="data-replicate-1"
リバランスによってこのようなファイルを本来の位置に再配置できる。
既存ボリュームにブリックを追加すると
- 追加直後は、既存のディレクトリは新しいブリックを使用しない
- ハッシュテーブルに当該ブリックのエントリがないため
- 新規作成したディレクトリには新しいブリックを含むハッシュテーブルが作成される
- リバランスすれば既存ディレクトリに新しいブリックを含むハッシュテーブルが作成される
既存ボリュームからブリックを削除すると
- 事前に削除対象ブリックを除いた新しいハッシュテーブルを作成して再配置する
- 再配置によって削除対象ブリックからファイルが無くなった後に当該ブリックを削除する
性能
大きなファイルをストライプ構成することで性能向上が見込めるが、小さい大量のファイルを扱う場合は性能が遅くなる(NFS より遅くなる可能性もある)。
v3.4.0 からのバグ
直接拡張属性を書いても大丈夫。
grep volume-id /var/lib/glusterd/vols/data/info | cut -d= -f2 | sed 's/-//g'
setfattr -n trusted.glusterfs.volume-id \
-v 0x$(grep volume-id /var/lib/glusterd/vols/data/info | cut -d= -f2 | sed 's/-//g') \
/glfs/vols/data
getfattr -n trusted.glusterfs.volume-id -e hex /glfs/vols/data
service glusterd restart
所感
- 分散ファイルシステムにしては構築が異様に簡単
- ノード交換時の作業が GlusterFS のバージョンがちょっと代わるたびに上手く行かなくなる気がする
- CentOS 7 の公式リポジトリだと server が無いので GlusterFS の公式のリポジトリを使うしか無い
- バージョンアップに追従していくのは大変そう
- ストレージなのでなるべく安定していた方がいい
- RHEL で Red Hat Gluster Storage とかのほうが良いかもしれない
- ストレージにはお金かけても良いと思う
- サーバの要件が異様に厳しそうだけど・・(RHCS は異様に厳しかった気がするし)
参考
- GlusterFS技術情報
- 10年効く分散ファイルシステム技術 GlusterFS & Red Hat Storage
- 分散ファイルシステム GlusterFS を使う上で知っておきたい 5つのこと « インフラ本舗
- IT検証ラボ - 分散ファイルシステムのGlusterFS:こんなとき、どうなる:ITpro