現在、Hadoop 2.x系では HDFSのスナップショット機能が含まれています [1]。CDH5からこの機能がサポートされました。
HDFSスナップショットとは?
HDFSでのスナップショットとは、HDFSサービスを停止せず、特定の時点での「状態」を保持するための機能です。従来のHDFSには、
- 削除したファイルの復旧ができない(HDFSにゴミ箱機能はありますが、、)
- ある時点でのリカバリができない
- 定期的なスナップショットを取る仕組みがない
という課題がありました。
たとえば、ある時点でHDFSの一貫性があるバックアップを取りたい場合、厳密に一貫性を確保するためにはネームノードを一旦セーフモードにするなどの操作の必要がありました。が、この際にダウンタイムが生じてしまいます。HDFSスナップショットにより、HDFSを停止せずに、特定の時点でのバックアップを取得することが可能になります。
HDFSのスナップショットの仕組みはLinuxのLVM snapshot [4]などと似ており、スナップショットの情報はメタ情報に記録され、変更はCopy-on-writeで管理されます。つまり、スナップショットはネームノードで実現されています。実際のデータは従来通りデータノード上にブロックとして保持されており、スナップショットを取る度にブロックが複製されるわけではありません。元のブロックを参照するだけです。なお、スナップショットはディレクトリに対して行い、現時点では読み込み専用です。メタ情報の操作だけなので、作成にかかる時間は一瞬です。 (作成にかかる時間はO(1) => 一定時間)。
図 スナップショット後
スナップショットの操作
スナップショットの取得方法の詳細はドキュメントにも詳しく書かれていますが、簡単に作ってみましょう。
まず、スナップショットを有効にしなければいけません。
スナップショットの有効化
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) コマンドで直接参照することはできます。
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からスナップショットの有効化/作成/削除などを行うこともできます。
この機能はClouderaのBackup and Disaster Recoveryでも使用されています。
最後に、HDFSのスナップショットでは日本語でも素晴らしいブログがあるので、ご覧になってみて下さい。([2],[3]など)。
参考資料
[1] Apache プロジェクトのページ HDFS Snapshots
[2] HDFSのスナップショット
[3] HDFSスナップショットの備忘録
[4] レッドハットのドキュメント: スナップショットボリューム
コメント