1. 快照介绍和作用

HDFS snapshot 是 HDFS 整个文件系统,或者某个目录在某个时刻的镜像。该镜像并不会随着源目录的改变而进行动态的更新。可以将快照理解为拍照片时的那一瞬间的投影,过了那个时间之后,又会有新的一个投影。

HDFS 快照的核心功能包括:数据恢复、数据备份、数据测试。

数据恢复

可以通过滚动的方式来对重要的目录进行创建 snapshot 的操作,这样在系统中就存在针对某个目录的多个快照版本。当用户误删除掉某个文件时,可以通过最新的 snapshot 来进行相关的恢复操作。

数据备份

可以使用 snapshot 来进行整个集群,或者某些目录、文件的备份。管理员以某个时刻的 snapshot 作为备份的起始结点,然后通过比较不同备份之间差异性,来进行增量备份。

数据测试

在某些重要数据上进行测试或者实验,可能会直接将原始的数据破坏掉。可以临时的为用户针对要操作的数据来创建一个 snapshot,然后让用户在对应的 snapshot 上进行相关的实验和测试,从而避免对原始数据的破坏。

2. 快照目录

快照有一个根本的原则需要记住:快照不是简单的数据拷贝,快照只做差异的记录。这一原则在其他很多系统的快照概念中都是适用的,比如磁盘快照,也是不保存真实数据的。因为不保存实际的数据,所以快照的生成往往非常迅速。

在 HDFS 中,如果在其中一个目录比如 /A 下创建一个快照,则快照文件中将会存在与 /A 目录下完全一致的子目录文件结构以及相应的属性信息,通过命令也能看到快照里面具体的文件内容。但是这并不意味着快照已经对此数据进行完全的拷贝 。这里遵循一个原则:对于大多不变的数据,你所看到的数据其实是当前物理路径所指的内容,而发生变更的 inode 数据才会被快照额外拷贝,也就是所说的差异拷贝。

inode 译成中文就是索引节点,它用来存放文件及目录的基本信息,包含时间、名称、拥有者、所在组等信息。

HDFS 快照不会复制 DataNode 中的块(没有数据复制),只记录了块列表和文件大小。

HDFS 快照不会对常规 HDFS 操作产生不利影响,修改记录按逆时针顺序进行(当前数据排在最前面),因此可以直接访问当前数据。快照数据通过从当前数据中减去修改来计算快照数据。

只要目录被设置为 snapshottable,就可以在任何目录上拍摄快照,一个启用快照的目录能够同时容纳 65536 个快照,对于能够启用快照的目录数量不做限制,管理员或许会将每个目录设置为启用快照。

如果在启用快照的目录中存在快照,该目录在所有的快照删除之前既不可以被删除也不可以重命名。嵌套启用快照的目录目前是不支持的。换句话说如果一个目录的祖先或者后代是启用快照的目录,那么该目录是不能设置为 snapshottable。

3. Snapshot 相关命令

启用快照功能

hdfs dfsadmin -allowSnapshot <path>

停用快照功能

hdfs dfsadmin -disallowSnapshot <path>

列出快照目录

hdfs lsSnapshottableDir

Tips

普通用户只会列出可用的快照目录,超级管理员会列出所有快照目录

创建快照

hdfs dfs -createSnapshot <snapshotDir> [<snapshotName>]

删除快照

hdfs dfs -deleteSnapshot <snapshotDir> <snapshotName>

重命名快照

hdfs dfs -renameSnapshot <snapshotDir> <oldName> <newName>

对比两个快照的差异

hdfs snapshotDiff <snapshotDir> <snapshotName1> <snapshotName2>

Tips

+ 表示目录或文件被创建

- 表示目录或文件被删除

M 表示目录或文件被修改

R 表示目录或文件被重命名

删除快照目录

hdfs dfs -rm -r -f <snapshotDir>

Tips

拥有快照文件的目录不允许被删除!

4. 话外内容

关于 hdfs dfs -count -q 统计命令

在 HDFS 中,使用 hdfs dfs -count -q 命令统计文件数和大小时,会包括快照(snapshots)中的文件和文件大小

具体来说,hdfs dfs -count -q 命令用于递归地统计指定目录中的文件数、目录数和空间配额使用情况。它的输出结果包括:

  • 目录数(DIR_COUNT)
  • 文件数(FILE_COUNT)
  • 磁盘空间大小(SPACE_CONSUMED)
  • 配额(QUOTA)
  • 空间配额(SPACE_QUOTA)

由于 HDFS 的快照机制允许用户保存目录及其内容在特定时间点的状态,快照中的文件被视为原始文件的只读副本。因此,当你在一个包含快照的目录上运行 hdfs dfs -count -q 命令时,快照中的文件和其占用的空间会计入统计结果中。

具体输出说明

## 执行的命令
hdfs dfs -count -q /user/data

## 输出的结果
QUOTA  REM_QUOTA  DIR_COUNT  FILE_COUNT  CONTENT_SIZE  SPACE_QUOTA  REM_SPACE_QUOTA  SPACE_CONSUMED  NAME
none   inf        10         100         5000000       none         inf              5000000         /user/data
  • DIR_COUNT 是目录数量,包括原始目录和快照中包含的目录。
  • FILE_COUNT 是文件数量,包括原始文件和快照中包含的文件。
  • SPACE_CONSUMED 是目录及其快照中的文件所消耗的总空间。

Tips

目前,HDFS 本身没有提供直接排出快照的统计命令,如果需要排出快照的干扰:

1、避免在父目录上创建快照

2、通过 hdfs dfs -ls -R -h​ 命令列出所有文件大小后手动计算,或者使用脚本计算

关于 hdfs dfs -du -h 统计 .snapshot 目录

HDFS 的快照只记录文件的元数据,包括块列表和文件大小,而不是实际的数据块。因此,当你使用 hdfs dfs -du -h <snapshot路径> 命令查看快照目录下的文件大小时,展示的文件大小指的是快照中记录的原始文件的大小。

详细说明

  1. 快照的机制

    • HDFS 快照是目录级的。创建快照时,HDFS 不会复制数据块,而是保存目录结构和文件元数据(包括文件的块列表、大小等)。
    • 快照的创建是非常高效的,因为它只是记录当前的元数据状态,数据块本身没有变化。
  2. hdfs dfs -du -h 命令

    • hdfs dfs -du -h <path> 显示指定路径下每个文件和目录的实际磁盘使用情况。
    • 当路径是一个快照目录(如 <snapshot_path>),它会显示快照目录下每个文件和目录的大小。
  3. 快照目录中的文件大小展示

    • 在快照目录下看到的文件大小,其实是原始文件在快照创建时的大小。
    • 因为快照只是记录元数据,当你查看快照目录时,显示的大小是快照创建时文件的逻辑大小,而不是实际占用的存储空间。

示例

假设你在 /user/hive/warehouse 目录上创建了一个快照 snapshot1

hdfs dfs -createSnapshot /user/hive/warehouse snapshot1

如果你查看快照目录的大小:

hdfs dfs -du -h /user/hive/warehouse/.snapshot/snapshot1

输出可能类似这样:

4.0 K  /user/hive/warehouse/.snapshot/snapshot1/mtdata.db
16.0 M  /user/hive/warehouse/.snapshot/snapshot1/mtdata.db/mytable

这里的 16.0 M 表示的是快照中记录的 /user/hive/warehouse/mtdata.db/mytable 在快照创建时的大小,而不是快照本身占用的额外空间。

结论

hdfs dfs -du -h <snapshot路径> 命令展示的是快照中各文件和目录的大小,这些大小是基于快照创建时文件的元数据记录的大小。这表示原始文件的逻辑大小,而不是快照本身实际占用的存储空间。快照的实际存储开销通常较小,只包括元数据的额外开销,而不是数据块的复制。