HDFSの新しい機能を確認 (3) – HDFSスナップショット

現在、Hadoop 2.x系では HDFSのスナップショット機能が含まれています [1]。CDH5からこの機能がサポートされました。

HDFSスナップショットとは?

HDFSでのスナップショットとは、HDFSサービスを停止せず、特定の時点での「状態」を保持するための機能です。従来のHDFSには、

  • 削除したファイルの復旧ができない(HDFSにゴミ箱機能はありますが、、)
  • ある時点でのリカバリができない
  • 定期的なスナップショットを取る仕組みがない

という課題がありました。
たとえば、ある時点でHDFSの一貫性があるバックアップを取りたい場合、厳密に一貫性を確保するためにはネームノードを一旦セーフモードにするなどの操作の必要がありました。が、この際にダウンタイムが生じてしまいます。HDFSスナップショットにより、HDFSを停止せずに、特定の時点でのバックアップを取得することが可能になります。
HDFSのスナップショットの仕組みはLinuxのLVM snapshot [4]などと似ており、スナップショットの情報はメタ情報に記録され、変更はCopy-on-writeで管理されます。つまり、スナップショットはネームノードで実現されています。実際のデータは従来通りデータノード上にブロックとして保持されており、スナップショットを取る度にブロックが複製されるわけではありません。元のブロックを参照するだけです。なお、スナップショットはディレクトリに対して行い、現時点では読み込み専用です。メタ情報の操作だけなので、作成にかかる時間は一瞬です。 (作成にかかる時間はO(1) => 一定時間)。
snapshot_1

図 スナップショット前

snapshot_2

図 スナップショット後

スナップショットの操作

スナップショットの取得方法の詳細はドキュメントにも詳しく書かれていますが、簡単に作ってみましょう。
まず、スナップショットを有効にしなければいけません。

スナップショットの有効化

hdfs dfsadmin -allowSnapshot <スナップショットを取得したいディレクトリ>

※HDFSの管理権限がないと失敗します。

kawasaki@hadoop11:~$ hdfs dfsadmin -allowSnapshot /user/kawasaki/dir1
allowSnapshot: Access denied for user kawasaki. Superuser privilege is required
at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.checkSuperuserPrivilege(FSPermissionChecker.java:108)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.checkSuperuserPrivilege(FSNamesystem.java:5430)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.allowSnapshot(FSNamesystem.java:6864)
(略

成功例

kawasaki@hadoop11:~$ sudo -u hdfs hdfs dfsadmin -allowSnapshot /user/kawasaki/dir1
Allowing snaphot on /user/kawasaki/dir1 succeeded

なお、スナップショットを取得したディレクトリ以下のディレクトリに対してスナップショットを取ることはできません。

kawasaki@hadoop11:~$ sudo -u hdfs hdfs dfsadmin -allowSnapshot /user/kawasaki/dir1/a
allowSnapshot: Nested snapshottable directories not allowed: path=/user/kawasaki/dir1/a, the ancestor /user/kawasaki/dir1 is already a snapshottable directory.

スナップショットの無効化

hdfs dfsadmin -disallowSnapshot <スナップショットを無効化したいディレクトリ>

スナップショット対象ディレクトリの一覧

hdfs lsSnapshottableDir

スナップショットが有効になったディレクトリを表示します。

kawasaki@hadoop11:~$ hdfs lsSnapshottableDir
drwxr-xr-x 0 kawasaki kawasaki 0 2014-04-09 05:10 0 65536 /user/kawasaki/dir1

スナップショットの取得

hdfs dfs -createSnapshot <取得したいパス(絶対|相対パス)> [<スナップショット名>]
kawasaki@hadoop11:~$ hdfs dfs -createSnapshot dir1 s1
Created snapshot /user/kawasaki/dir1/.snapshot/s1
kawasaki@hadoop11:~$ hdfs dfs -createSnapshot dir1
Created snapshot /user/kawasaki/dir1/.snapshot/s20140409-060117.621
スナップショット名は省略することができますが、その場合は上記のように、スナップショットを取得した日時を元に名前が生成されます。
s'yyyyMMdd-HHmmss.SSS

スナップショットの削除

hdfs dfs -deleteSnapshot <削除したいパス(絶対|相対パス)> [<スナップショット名>]

この状態でHueから見ようとしても表示されませんが、hdfs (hadoop) コマンドで直接参照することはできます。
snap_hue

kawasaki@hadoop11:~$ hadoop fs -ls dir1/.snapshot
Found 2 items
drwxr-xr-x   - kawasaki kawasaki          0 2014-04-09 05:53 dir1/.snapshot/s1
drwxr-xr-x   - kawasaki kawasaki          0 2014-04-09 06:01 dir1/.snapshot/s20140409-060117.621
kawasaki@hadoop11:~$ hadoop fs -ls -R dir1/.snapshot/s1/
drwxr-xr-x   - kawasaki kawasaki          0 2014-04-09 05:10 dir1/.snapshot/s1/a
-rw-r--r--   3 kawasaki kawasaki   75288655 2014-04-09 03:38 dir1/.snapshot/s1/bigfile
-rw-r--r--   3 kawasaki kawasaki         24 2014-04-09 03:40 dir1/.snapshot/s1/small.txt

スナップショットの比較

hdfs snapshotDiff <パス> <スナップショット名1> <スナップショット名2>
※スナップショット名に . を指定することで、現在の状態と比較することが可能

では、ディレクトリからファイルを削除して、スナップショットと比較してみましょう。

kawasaki@hadoop11:~$ hadoop fs -rm dir1/bigfile
14/04/09 06:30:19 INFO fs.TrashPolicyDefault: Namenode trash configuration: Deletion interval = 1440 minutes, Emptier interval = 0 minutes.
Moved: 'hdfs://hadoop11.localdomain:8020/user/kawasaki/dir1/bigfile' to trash at: hdfs://hadoop11.localdomain:8020/user/kawasaki/.Trash/Current
kawasaki@hadoop11:~$ hadoop fs -ls dir1
Found 2 items
drwxr-xr-x   - kawasaki kawasaki          0 2014-04-09 05:10 dir1/a
-rw-r--r--   3 kawasaki kawasaki         24 2014-04-09 03:40 dir1/small.txt
kawasaki@hadoop11:~$ hadoop fs -put /etc/services dir1/a/
kawasaki@hadoop11:~$ hdfs snapshotDiff dir1 s1 .
Difference between snapshot s1 and current directory under directory /user/kawasaki/dir1:
M    .
-    ./bigfile
M    ./a
+    ./a/services

ディレクトリが変更 (Modify)され、bigfileが削除 (-)、aディレクトリにservicesファイルが追加 (+) されたことがわかりますね。
スナップショットの一覧は、hdfsコマンドで、ディレクトリ一覧と同じように確認することができます。(この例では2つのスナップショットがあります)

kawasaki@hadoop11:~$ hdfs dfs -ls dir1/.snapshot
 Found 2 items
 drwxr-xr-x   - kawasaki kawasaki          0 2014-04-09 05:53 dir1/.snapshot/s1
 drwxr-xr-x   - kawasaki kawasaki          0 2014-04-09 06:01 dir1/.snapshot/s20140409-060117.621

スナップショットからファイルを戻すには、hdfsコマンドを使用して、スナップショットのフォルダからコピーするだけです。

hdfs dfs -cp dir1/.snapshot/s1/bigfile dir1/

Cloudera Managerによるスナップショットの管理

Cloudera Manager のEnterprise版では、GUIからスナップショットの有効化/作成/削除などを行うこともできます。
cm_snapshotこの機能はClouderaのBackup and Disaster Recoveryでも使用されています。
最後に、HDFSのスナップショットでは日本語でも素晴らしいブログがあるので、ご覧になってみて下さい。([2],[3]など)。

参考資料

[1] Apache プロジェクトのページ HDFS Snapshots
[2] HDFSのスナップショット
[3] HDFSスナップショットの備忘録
[4] レッドハットのドキュメント: スナップショットボリューム

コメント