介绍
零售商收到了一份商品文件。一位同事需要审核副本,另一位需要归档版本,而你需要下载审核后的文件进行检查。如果这些操作意外替换或删除了原件,团队就会失去可信的输入。
文件的生命周期是它经历的一系列操作:接收、使用、归档、导出,直至最终删除。HDFS 为各项操作提供了命令,但它们的作用不同。上传和下载在文件系统之间复制数据;HDFS 内的复制和移动则始终在 HDFS 内完成。
你将分别建立 raw、archive 和 scratch 目录,保留原始文件,导出归档,并只删除可丢弃的副本。你已了解 HDFS 路径和上传、读取命令;本实验将进一步学习谨慎地管理文件。环境和数据独立于之前的实验。全程使用终端完成操作。
保留原始输入
在这一步中,你将把零售商的输入上传到专门保存原始文件的目录。
raw(原始)文件是以原样保留的输入。独立的 scratch(临时工作)目录保存临时内容,archive(归档)目录则保存需要保留的副本。目录名称不会自动强制实施这些规则,但能清楚表达用途。
先进入本地工作目录:
cd /home/labex/project
存储输入之前,先读取它:
cat /home/labex/project/data/products.txt
内容如下:
notebook pen notebook
folder pen
notebook folder
为 -mkdir -p 提供三个目录路径。HDFS 会创建每个指定目录,以及所有缺失的父目录:
hdfs dfs -mkdir -p /user/labex/file-lifecycle/raw /user/labex/file-lifecycle/archive /user/labex/file-lifecycle/scratch
将本地输入上传到 raw 目录:
hdfs dfs -put /home/labex/project/data/products.txt /user/labex/file-lifecycle/raw/products.txt
上传成功时通常没有输出。如果重复上传,目标已存在的错误会保护已存储的文件,避免意外覆盖。此时应检查存储的输入,而不是为了消除错误而删除它:
hdfs dfs -cat /user/labex/file-lifecycle/raw/products.txt
文本应该与本地原件相同。本地文件系统中的原件也仍然存在:-put 复制本地源文件,并不移动它。后续将使用副本进行操作,让这份原始输入保持完整。
在 HDFS 内复制和归档
在这一步中,你将创建审核副本,再将该副本移动到归档目录,同时保留原始输入的位置。
-cp 操作将 HDFS 源文件复制到 HDFS 目标位置。与 -put 不同,下面的两个路径都属于 HDFS:
hdfs dfs -cp /user/labex/file-lifecycle/raw/products.txt /user/labex/file-lifecycle/scratch/review.txt
查看审核副本:
hdfs dfs -cat /user/labex/file-lifecycle/scratch/review.txt
你应该看到相同的商品标签。不同的文件名仍代表同一份数据,并不是新的销售批次。
审核副本准备好保留后,使用 -mv 移动它。在同一个文件系统内移动会改变路径,原来的源路径将不再存在。运行命令之前,预测哪个文件会消失,哪个会保留:
hdfs dfs -mv /user/labex/file-lifecycle/scratch/review.txt /user/labex/file-lifecycle/archive/products-reviewed.txt
同时列出 scratch 和 archive 目录。-ls 可以接受多个路径:
hdfs dfs -ls /user/labex/file-lifecycle/scratch /user/labex/file-lifecycle/archive
归档条目应以 /archive/products-reviewed.txt 结尾;scratch 中不应再有 review.txt 条目。确认原始文件未受影响:
hdfs dfs -cat /user/labex/file-lifecycle/raw/products.txt
它的三行内容应该仍然相同。如果完成后又回到这一步,请检查现有归档,不要重新执行这组复制和移动命令:-mv 已经移走了 scratch 中的源文件,也不应随意覆盖已有归档。
导出并统计文件
在这一步中,你将下载归档文件,并查看文件数量和存储用量。
-get 操作将 HDFS 源文件复制到本地目标位置。下面第一个路径属于 HDFS,第二个属于本地:
hdfs dfs -get /user/labex/file-lifecycle/archive/products-reviewed.txt /home/labex/project/output/products-exported.txt
命令应不输出内容,直接返回提示符。如果已经完成下载,请查看本地目标文件;再次下载到已有文件时,可能会提示文件已存在。与第一个实验一样,使用本地 diff 检查内容:
diff /home/labex/project/data/products.txt /home/labex/project/output/products-exported.txt
应该没有差异输出。这是一份导出的副本:HDFS 归档和本地原件都仍然存在。
要统计目录内容,可以使用 -count。它依次输出目录数、文件数、以字节为单位的内容大小和路径。目录数包含指定目录本身:
hdfs dfs -count /user/labex/file-lifecycle/raw /user/labex/file-lifecycle/archive
每行都应表示一个目录,其中包含一个文件。两行的内容大小应该相同,因为归档的字节与原始文件相同。保存实际输出的行:
hdfs dfs -count /user/labex/file-lifecycle/raw /user/labex/file-lifecycle/archive > /home/labex/project/output/file-counts.txt
-du 操作汇总文件大小。-h 会在合适时使用便于阅读的单位:
hdfs dfs -du -h /user/labex/file-lifecycle/raw
各列分别显示内容大小、计入副本后的占用空间和路径。本环境的副本数为 1,因此该文件的两个大小列应该一致。后续实验将介绍块和副本;在其他环境中,第二列更大,并不一定意味着多出了业务记录。
继续之前,试着解释各项操作的边界:-cp 始终在 HDFS 内操作,-mv 改变 HDFS 路径,-get 则创建本地副本。
只删除可丢弃的副本
在这一步中,你将检查删除策略,并删除一个已知的临时文件,同时保留输入和归档。
删除是一种不同的操作:文件不再需要时,可以移除其路径。HDFS 可以设置 Trash(回收站)保留策略,但使用 HDFS 并不意味着删除后一定能恢复。先读取已配置的回收站保留间隔,单位为分钟:
hdfs getconf -confKey fs.trash.interval
预配置环境使用 0,表示未启用回收站保留。请将这里的删除视为立即移除。在其他环境中,正数会启用相应保留间隔,但仍不能替代妥善保留可信输入。
创建一个仅用于练习删除的副本:
hdfs dfs -cp /user/labex/file-lifecycle/raw/products.txt /user/labex/file-lifecycle/scratch/disposable.txt
删除之前,先列出确切的目标:
hdfs dfs -ls /user/labex/file-lifecycle/scratch/disposable.txt
检查路径是否以 scratch/disposable.txt 结尾,而不是 raw/products.txt 或归档路径。-rm 操作删除指定文件。这里不需要递归删除,也不需要通配符:
hdfs dfs -rm /user/labex/file-lifecycle/scratch/disposable.txt
命令会报告指定文件已被删除。重复执行会报告文件不存在;这时应检查当前状态,不要扩大删除目标。列出 scratch,确认没有剩余临时文件:
hdfs dfs -ls /user/labex/file-lifecycle/scratch
空目录不会产生文件条目。最后,查看必须保留的两个文件:
hdfs dfs -ls /user/labex/file-lifecycle/raw/products.txt /user/labex/file-lifecycle/archive/products-reviewed.txt
两个路径都应该列出。你在完整保留原件的情况下完成了文件生命周期操作:上传、复制、归档、导出、统计,并只删除临时工作文件。
总结
你在保持原始数据完整的同时,创建了审核副本,将该副本移动到归档目录,再导出到本地文件系统。你还解读了文件数量和存储大小,检查了回收站设置,并只删除了明确指定的可丢弃文件。
接下来,你将把这些习惯应用到包含多个文件的每日批次中。知道哪些文件属于某个批次,与知道如何上传它们同样重要。



