你的第一个 Hadoop 实验

大数据Beginner
立即练习

介绍

你正在帮助一家零售商回答一个简单的问题:门店的每日记录中,哪些商品出现得最频繁? 在开始计数之前,你需要收集文件,并确认文件内容可用且正确。本实验就是这段学习旅程的第一步。

从日常数据到大数据

一家门店可能把每日记录保存在一个小文件中,用笔记本电脑就能打开。现在想象一下,成千上万家门店每天都在发送记录,同时还不断产生网站活动和仓库更新数据。需要保存的数据更多了,新数据持续到来,文件的结构也可能各不相同。

大数据指的是这样一类数据工作负载:由于规模、到达速度或复杂程度,现有工具和资源很难应对。不存在一个通用的行数门槛,超过它,文件就成了大数据。真正需要考虑的是:能否存下这些数据,在规定时间内处理完,以及在设备故障时继续工作?

对于一个小型销售文件,电子表格、数据库或 Python 脚本可能就足够了。随着工作负载增长,一种做法是让多台互联的计算机共同承担存储和处理工作。这样协同工作的一组计算机称为集群(cluster);把工作分担给它们的方式称为分布式(distributed)计算。

Hadoop 的定位

Apache Hadoop 是一组开源工具,用于在集群中存储和处理数据。先认识其中两个部分,就能建立基本印象:

组成部分 负责什么 对应零售商的哪个问题
HDFS——Hadoop 分布式文件系统(Hadoop Distributed File System) 跨机器存储文件,并在相应配置下保留数据副本 每天的输入文件可以存放在哪里?
MapReduce——批处理框架 把处理作业划分为较小的任务,再汇总结果 怎样统计这些文件中的商品标签?

批次(batch)是一起处理的一组有明确范围的数据,例如昨天收到的文件。后面的实验会带你运行一个现成的计数程序。本实验先使用负责存储的 HDFS:计算只有读到了正确的数据,结果才有意义。

Hadoop 只是数据工具生态的一部分。后续课程还会介绍用 SQL 查询文件数据的 Hive、支持编程式数据处理的 Spark,以及持续传递事件的 Kafka。开始本实验不需要使用这些工具,现在也不必记住它们的名字。

工作流程的第一步

零售商的简化工作流程如下:

收集商品文件 → 存入 HDFS → 处理一个批次 → 查看计数结果
               从这里开始

你的任务是上传一个文件,把它读回来,并检查内容有没有变化。这就像做菜之前先检查食材:先确保数据正确存储,后续计算才值得信赖。

本实验在一台机器上提供 Hadoop,你无需安装集群,就能学习真实的 HDFS 命令。在这个环境中,本地文件与 HDFS 文件仍然使用独立的路径和访问命令。这里不会演示跨多台机器的存储或整台机器故障后的恢复;继续探索 HDFS 时,你会逐步理解这些概念。

完成本实验后,你将能够:

  • 区分本地文件和存储在 HDFS 中的文件。
  • 创建 HDFS 目录并上传文件。
  • 读取 HDFS 文件,并与本地原件比较。
  • 使用不同的目标文件名上传同一份数据。

整个实验都在 Terminal(终端)标签页中完成。只需要基本的终端操作,不要求 Java 或 Python 编程。如果你还不熟悉路径和终端命令,可以先学习 Linux 学习路径。

将第一个文件上传到 HDFS

在这一步中,你将查看一个本地文件,创建自己的 HDFS 目录,然后把文件上传进去。

终端是输入请求的地方。hdfs 命令是一个客户端:它把请求发送给正在运行的 HDFS 服务,由服务管理存储的文件。下面既有本地 Linux 命令,也有 HDFS 命令;可以根据命令判断正在访问哪种存储。

实验已经启动了 HDFS 服务,并准备好一个小型输入文件。点击终端,依次运行下面的命令,每次都等提示符重新出现后再继续。只复制命令,不要复制提示符。

使用 cd 将当前 Shell 切换到本地项目目录:

cd /home/labex/project

这个路径以 / 开头,因此是绝对路径。本地输入文件位于这个目录下的 data 目录中。普通 Linux 命令 cat 用来显示本地文件的内容:

cat /home/labex/project/data/products.txt

预期内容如下:

notebook pen notebook
folder pen
notebook folder

在这个简化样本中,每个单词都是一个商品标签,每次出现代表记录中的一件商品。你现在就能手动数出 notebook 和 pen 合计出现了五次:三次 notebook(笔记本)和两次 pen(笔)。当数据分散在大量大文件中时,批处理程序可以帮你完成计数。

现在先记住这个问题,重点是原样存储文本。这里只用三行容易阅读的数据,便于你立即判断结果是否正确;这个样本本身并不需要 Hadoop 来处理。

HDFS 有自己的目录树。在本环境中,hdfs dfs 会把文件系统命令发送给 HDFS。用 Linux 的 mkdir 创建本地目录,并不会创建 HDFS 目录。

在 HDFS 主目录 /user/labex 下创建一个目录。-mkdir 操作用来创建目录;-p 还会创建缺失的父目录,并允许目标目录已经存在:

hdfs dfs -mkdir -p /user/labex/your-first-hadoop-lab

成功时通常没有输出,操作完成后会重新出现提示符。尽管路径也使用斜杠表示,这个目录属于 HDFS。

-put 操作把本地源文件复制到 HDFS 目标位置。下面第一个路径是本地路径,第二个是 HDFS 路径:

hdfs dfs -put /home/labex/project/data/products.txt /user/labex/your-first-hadoop-lab/products.txt

上传成功时通常没有输出,本地原件仍会保留。如果成功上传后重复运行这条命令,HDFS 会提示目标已存在。此时继续查看文件即可,无需删除或覆盖它。

使用 -ls 列出 HDFS 目录内容:

hdfs dfs -ls /user/labex/your-first-hadoop-lab

你应该看到 Found 1 items,以及一个以如下路径结尾的文件条目:

/user/labex/your-first-hadoop-lab/products.txt

条目中还包括权限、所有者、所属组、大小和修改时间,后续会逐步学习这些信息。当前步骤只需根据目标路径确认文件已出现在 HDFS 中。下一步检查它的内容。

读回文件并核对内容

在这一步中,你将读取 HDFS 文件,将其内容保存到本地,并与原件比较。

零售商最终要统计存储文件中的标签。如果上传了错误的文件,或遗漏了一行,即使后续程序运行成功,计数也可能出错。目录列表只能证明文件存在,不能证明内容正确。

读回之前,先预测一下:上传文件会改变商品标签或删除行吗?HDFS 的 -cat 操作会读取 HDFS 文件,并在终端显示其内容:

hdfs dfs -cat /user/labex/your-first-hadoop-lab/products.txt

预期内容如下:

notebook pen notebook
folder pen
notebook folder

与第 1 步查看的本地文件比较,单词和换行都应该一致。注意命令的区别:cat 读取本地文件,而本环境中的 hdfs dfs -cat 读取 HDFS 文件。

要在本地保留读回结果,可以使用 Shell 的 > 运算符。它把命令输出重定向到一个本地文件:文件不存在时创建,已经存在时替换原有内容。预先准备好的 output 目录用于存放你的结果:

hdfs dfs -cat /user/labex/your-first-hadoop-lab/products.txt > /home/labex/project/output/products-readback.txt

这次终端不会显示商品文本,因为输出已写入本地文件。HDFS 源文件没有变化。使用本地 cat 命令查看保存的结果:

cat /home/labex/project/output/products-readback.txt

应该显示相同的三行。现在,你有一份本地原件、一份 HDFS 文件和一份读回到本地的文件。

使用 diff 比较原件与保存的结果。两个文件完全相同时,diff 不输出任何内容,并成功返回:

diff /home/labex/project/data/products.txt /home/labex/project/output/products-readback.txt

没有差异输出,且提示符重新出现,说明读回内容与原件一致。如果出现差异,按照上面的完整 HDFS 源路径和本地输出路径重新读回,再比较一次。

练习使用新的目标文件名

在这一步中,你将修改上传命令的一部分,检查文件内容会不会随之改变。

运行下一条命令之前,先预测结果:保持本地源文件不变,只修改 HDFS 目标文件名,商品标签会改变吗?第一个 HDFS 文件还会存在吗?

再次上传本地原件,这次将目标文件命名为 products-copy.txt:

hdfs dfs -put /home/labex/project/data/products.txt /user/labex/your-first-hadoop-lab/products-copy.txt

与之前一样,成功上传时通常没有输出。如果已经完成过这次上传,目标已存在的提示意味着应直接检查文件,不必再次上传。

列出 HDFS 目录内容,检查你的预测:

hdfs dfs -ls /user/labex/your-first-hadoop-lab

现在应该看到 Found 2 items,以及分别以以下路径结尾的条目:

/user/labex/your-first-hadoop-lab/products-copy.txt
/user/labex/your-first-hadoop-lab/products.txt

两个文件都还存在,因为 -put 把本地源文件复制到了指定目标位置,并没有重命名先前的 HDFS 文件。第二个文件是同一批记录的练习副本,不是新一天的销售数据。学习准备批次输入时,你会谨慎选择文件,避免把重复副本统计两遍。

读取新的 HDFS 文件:

hdfs dfs -cat /user/labex/your-first-hadoop-lab/products-copy.txt

输出应该仍是相同的三行商品标签。修改文件名不会改变文件内容。

使用相同的读回方法,将新文件保存到本地:

hdfs dfs -cat /user/labex/your-first-hadoop-lab/products-copy.txt > /home/labex/project/output/products-copy-readback.txt

将保存的结果与原件比较:

diff /home/labex/project/data/products.txt /home/labex/project/output/products-copy-readback.txt

应该没有差异输出。你已经验证了预测的两个部分:第一个 HDFS 文件仍在,第二个文件包含相同的数据。

继续学习前,先分辨一下哪些命令读取本地文件,哪些读取 HDFS 文件。下一个实验会带你检查 Hadoop 命令通过哪些配置找到要连接的 HDFS 服务。

总结

你从零售商收集和统计商品记录的需求出发,了解了为什么增长的数据工作负载可能需要分布式存储与处理,以及 Hadoop 的定位:HDFS 存储文件,MapReduce 可以处理一个批次。

你完成了工作流程中的存储部分:将本地零售文本文件上传到 HDFS,读回文件,并使用 diff 确认内容完整保留。随后,你预测并验证了只改变 HDFS 目标文件名会产生什么影响。

你练习了 hdfs dfs -mkdir -p、-put、-ls 和 -cat,并区分了这些 HDFS 操作与本地 cat、Shell 输出重定向。接下来,你将探索 Hadoop 客户端如何找到 HDFS,以及存储和计算如何协作。