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