めもめも

このブログに記載の内容は個人の見解であり、必ずしも所属組織の立場、戦略、意見を代表するものではありません。

RHS2.0Beta2(glusterfs-3.3.0qa38)のSelf-heal Daemon

何の話かというと

Gluster3.2.xのレプリケーションボリュームでは、ノード障害などでレプリケーションができなくなった場合、障害ノードが復帰した後に、クライアントが明示的にファイルアクセスを行ったタイミングで、該当ファイルの再レプリケーションが行われました。

一方、RHS2.0では、新しくできた「Self-heal Daemon」がバックグラウンドで自動的に再レプリケーションを行うようになりました。現在開発中の「RHS2.0Beta2」にはまだありませんが、今後、再レプリケーションに伴うI/O負荷を軽減するために、再レプリケーションの速度を調整する方法なども用意される予定です。

ここでは、RHS2.0Beta2(glusterfs-3.3.0qa38)のSelf-heal Daemonの基本的な動作確認を行います。

事前準備

2ノードのGlusterサーバ(gluster01, gluster02)で、レプリケーションボリュームvol01を用意します。

[root@gluster01 ~]# gluster peer status
Number of Peers: 1

Hostname: gluster02
Uuid: f2d13861-0950-4181-a3ac-453a890d56af
State: Peer in Cluster (Connected)

[root@gluster01 ~]# gluster vol create vol01 replica 2 gluster01:/data/brick01 gluster02:/data/brick01
Creation of volume vol01 has been successful. Please start the volume to access data.

[root@gluster01 ~]# gluster vol start vol01
Starting volume vol01 has been successful

ボリュームの状態を確認すると、両ノードでSelf-heal Daemonが稼働していることが分かります。

[root@gluster01 ~]# gluster vol status vol01
Status of volume: vol01
Gluster process						Port	Online	Pid
------------------------------------------------------------------------------
Brick gluster01:/data/brick01				24009	Y	4961
Brick gluster02:/data/brick01				24009	Y	4914
NFS Server on localhost					38467	Y	4967
Self-heal Daemon on localhost				N/A	Y	4973
NFS Server on gluster02				38467	Y	4919
Self-heal Daemon on gluster02				N/A	Y	4925

これをGlusterFSクライアント(client01)で、/mnt/vol01にマウントしておきます。

[root@client01 ~]# mount -t glusterfs gluster01:/vol01 /mnt/vol01

Self-heal Daemonの動作は、GlusterFSサーバの「/var/log/glusterfs/glustershd.log」で確認できます。これをtailで見ながら作業をすすめます。

単純障害からの回復

クライアントでファイル「file0.txt〜file9.txt」を作成します。

[root@client01 ~]# for num in $(seq 0 9); do date > /mnt/vol01/file$num.txt; done

[root@client01 ~]# ls -l /mnt/vol01/
合計 40
-rw-r--r--. 1 root root 43  5月  8 01:26 2012 file0.txt
-rw-r--r--. 1 root root 43  5月  8 01:26 2012 file1.txt
-rw-r--r--. 1 root root 43  5月  8 01:26 2012 file2.txt
-rw-r--r--. 1 root root 43  5月  8 01:26 2012 file3.txt
-rw-r--r--. 1 root root 43  5月  8 01:26 2012 file4.txt
-rw-r--r--. 1 root root 43  5月  8 01:26 2012 file5.txt
-rw-r--r--. 1 root root 43  5月  8 01:26 2012 file6.txt
-rw-r--r--. 1 root root 43  5月  8 01:26 2012 file7.txt
-rw-r--r--. 1 root root 43  5月  8 01:26 2012 file8.txt
-rw-r--r--. 1 root root 43  5月  8 01:26 2012 file9.txt

[root@client01 ~]# cat /mnt/vol01/file0.txt 
2012年  5月  8日 火曜日 01:26:39 UTC

gluster02のデーモンをおもむろに強制停止します。

[root@gluster02 ~]# pkill -9 gluster

クライアントからはアクセスを継続することができます。

[root@client01 ~]# for num in $(seq 0 4); do date >> /mnt/vol01/file$num.txt; done
[root@client01 ~]# ls -l /mnt/vol01/
合計 40
-rw-r--r--. 1 root root 86  5月  8 01:29 2012 file0.txt
-rw-r--r--. 1 root root 86  5月  8 01:29 2012 file1.txt
-rw-r--r--. 1 root root 86  5月  8 01:29 2012 file2.txt
-rw-r--r--. 1 root root 86  5月  8 01:29 2012 file3.txt
-rw-r--r--. 1 root root 86  5月  8 01:29 2012 file4.txt
-rw-r--r--. 1 root root 43  5月  8 01:26 2012 file5.txt
-rw-r--r--. 1 root root 43  5月  8 01:26 2012 file6.txt
-rw-r--r--. 1 root root 43  5月  8 01:26 2012 file7.txt
-rw-r--r--. 1 root root 43  5月  8 01:26 2012 file8.txt
-rw-r--r--. 1 root root 43  5月  8 01:26 2012 file9.txt

[root@client01 ~]# cat /mnt/vol01/file0.txt 
2012年  5月  8日 火曜日 01:26:39 UTC
2012年  5月  8日 火曜日 01:29:37 UTC

gluster02のデーモンを再起動します。

[root@gluster02 ~]# service glusterd start
Starting glusterd:                                         [  OK  ]

そのまま10分ほど待つと、Self-heal Daemonが再レプリケーションを開始します。gluster01のglustershd.logに次のようなログが出ます。

[2012-05-08 01:38:52.707438] I [afr-self-heald.c:1098:afr_start_crawl] 0-vol01-replicate-0: starting crawl 1 for vol01-client-0
[2012-05-08 01:38:52.722143] W [afr-self-heal-data.c:828:afr_lookup_select_read_child_by_txn_type] 0-vol01-replicate-0: : Possible split-brain
[2012-05-08 01:38:52.722859] W [afr-self-heal-data.c:828:afr_lookup_select_read_child_by_txn_type] 0-vol01-replicate-0: : Possible split-brain
[2012-05-08 01:38:52.723457] W [afr-self-heal-data.c:828:afr_lookup_select_read_child_by_txn_type] 0-vol01-replicate-0: : Possible split-brain
[2012-05-08 01:38:52.724493] I [afr-common.c:1195:afr_detect_self_heal_by_iatt] 0-vol01-replicate-0: size differs for  
[2012-05-08 01:38:52.724535] I [afr-common.c:1347:afr_launch_self_heal] 0-vol01-replicate-0: background  data self-heal triggered. path: , reason: lookup detected pending operations
[2012-05-08 01:38:52.726532] I [afr-self-heal-algorithm.c:125:sh_loop_driver_done] 0-vol01-replicate-0: full self-heal completed on 
[2012-05-08 01:38:52.727884] I [afr-self-heal-common.c:2054:afr_self_heal_completion_cbk] 0-vol01-replicate-0: background  data self-heal completed on 
[2012-05-08 01:38:52.728375] I [afr-common.c:1195:afr_detect_self_heal_by_iatt] 0-vol01-replicate-0: size differs for  
[2012-05-08 01:38:52.728408] I [afr-common.c:1347:afr_launch_self_heal] 0-vol01-replicate-0: background  data self-heal triggered. path: , reason: lookup detected pending operations
[2012-05-08 01:38:52.729868] I [afr-self-heal-algorithm.c:125:sh_loop_driver_done] 0-vol01-replicate-0: full self-heal completed on 
[2012-05-08 01:38:52.731278] I [afr-self-heal-common.c:2054:afr_self_heal_completion_cbk] 0-vol01-replicate-0: background  data self-heal completed on 
[2012-05-08 01:38:52.732012] I [afr-common.c:1195:afr_detect_self_heal_by_iatt] 0-vol01-replicate-0: size differs for  
[2012-05-08 01:38:52.732049] I [afr-common.c:1347:afr_launch_self_heal] 0-vol01-replicate-0: background  data self-heal triggered. path: , reason: lookup detected pending operations
[2012-05-08 01:38:52.733664] I [afr-self-heal-algorithm.c:125:sh_loop_driver_done] 0-vol01-replicate-0: full self-heal completed on 
[2012-05-08 01:38:52.734928] I [afr-self-heal-common.c:2054:afr_self_heal_completion_cbk] 0-vol01-replicate-0: background  data self-heal completed on 
[2012-05-08 01:38:52.735495] I [afr-common.c:1195:afr_detect_self_heal_by_iatt] 0-vol01-replicate-0: size differs for  
[2012-05-08 01:38:52.735531] I [afr-common.c:1347:afr_launch_self_heal] 0-vol01-replicate-0: background  data self-heal triggered. path: , reason: lookup detected pending operations
[2012-05-08 01:38:52.737049] I [afr-self-heal-algorithm.c:125:sh_loop_driver_done] 0-vol01-replicate-0: full self-heal completed on 
[2012-05-08 01:38:52.738491] I [afr-self-heal-common.c:2054:afr_self_heal_completion_cbk] 0-vol01-replicate-0: background  data self-heal completed on 
[2012-05-08 01:38:52.738915] I [afr-common.c:1195:afr_detect_self_heal_by_iatt] 0-vol01-replicate-0: size differs for  
[2012-05-08 01:38:52.738949] I [afr-common.c:1347:afr_launch_self_heal] 0-vol01-replicate-0: background  data self-heal triggered. path: , reason: lookup detected pending operations
[2012-05-08 01:38:52.740472] I [afr-self-heal-algorithm.c:125:sh_loop_driver_done] 0-vol01-replicate-0: full self-heal completed on 
[2012-05-08 01:38:52.741906] I [afr-self-heal-common.c:2054:afr_self_heal_completion_cbk] 0-vol01-replicate-0: background  data self-heal completed on 
[2012-05-08 01:38:52.742213] I [afr-self-heald.c:1003:afr_dir_crawl] 0-vol01-replicate-0: Crawl completed on vol01-client-0

gluster02のブリック内のファイルを見ると、「file0.txt〜file4.txt」がきちんと更新されています。

[root@gluster02 ~]# ls -l /data/brick01/
合計 40
-rw-r--r--. 2 root root 86  5月  8 01:29 2012 file0.txt
-rw-r--r--. 2 root root 86  5月  8 01:29 2012 file1.txt
-rw-r--r--. 2 root root 86  5月  8 01:29 2012 file2.txt
-rw-r--r--. 2 root root 86  5月  8 01:29 2012 file3.txt
-rw-r--r--. 2 root root 86  5月  8 01:29 2012 file4.txt
-rw-r--r--. 2 root root 43  5月  8 01:26 2012 file5.txt
-rw-r--r--. 2 root root 43  5月  8 01:26 2012 file6.txt
-rw-r--r--. 2 root root 43  5月  8 01:26 2012 file7.txt
-rw-r--r--. 2 root root 43  5月  8 01:26 2012 file8.txt
-rw-r--r--. 2 root root 43  5月  8 01:26 2012 file9.txt

Self-heal Daemonの動作を待たずに、強制的に再レプリケーションを行う際は、GlusterFSサーバで次のコマンドを実行します。

[root@gluster01 ~]# gluster vol heal vol01 full

Split-brainについて

次のような障害シナリオを考えます。

gluster02停止 -> クライアントがfile0.txtに書き込み -> gluster01停止 -> gluster02起動 -> クライアントがfile0.txtに書き込み -> gluster01起動

この場合、gluster01とgluster02が保持するfile0.txtの内容に矛盾が生じて、Self-heal Daemonはどちらからどちらに再レプリケーションしてよいかわからなくなります。このような状態をSplit-brainと呼びます。

Split-brain状態のファイルを検知したクライアントは、安全のためにそのファイルへのアクセスを停止します。(アクセスするとI/Oエラーを返す。)

また、Split-brain状態のファイルの存在は、GlusterFSサーバ上で、次のコマンドで確認できます。

[root@gluster01 ~]# gluster vol heal vol01 info split-brain

Split-brain状態のファイルに対しては、利用者自身がどちらのファイルを正とするかを決めて、再レプリケーションを行う必要があります。ただし、具体的な方法については、まだ開発中の様です。手順が確定したら、あらためて追記します。