
简介面向大数据技术初学者的实验报告PDF围绕Linux与Hadoop两大基础平台展开通过清晰的实验步骤引导读者掌握环境搭建与核心操作。Linux部分涵盖系统发展历史、常用Shell命令touch创建文件、ls列目录、mkdir建目录、rm删除、cp复制、mv移动、chmod改权限、chown改属主以及用户与用户组管理、目录结构、绝对与相对路径的使用。Hadoop部分包含单机与伪分布式模式安装需要修改core-site.xml和hdfs-site.xml还要完成Java与SSH免密环境配置同时演示HDFS的格式化、启动、数据读写并解释NameNode与DataNode的分工以及MapReduce中Map与Reduce阶段的数据处理流程。实验后的常见问题反思如JDK下载配置、Hadoop编译原理提供了实用的排错参考能帮助读者缩短理论学习与实践操作之间的差距。资源包仅含1个PDF文件大小1.92MB报告结构完整含实验目的、步骤、结果与分析适合课程作业参考或课后自学已有115人浏览学习。1. 从一份实验报告看大数据入门Linux 与 Hadoop 到底在练什么拿到这份《大数据技术原理与应用》课程实验报告时我第一反应是又是一份学生作业翻完之后改观了——它把大数据入门最容易被卡住的三件事全踩了一遍Linux 基本操作、Hadoop 伪分布环境搭建、HDFS 与 MapReduce 的读写和计算。报告是实验楼 Xfce 终端 CentOS 6.6 64 位虚拟机环境单核 1G 内存这个配置放到今天依然能跑通全套实验只是会有点吃力。适合谁刚接触大数据、被装环境劝退的初学者以及想系统复现一遍 Hadoop 1.x/2.x 基础操作的从业者。这份资源能解决的是从零把 Linux 命令、用户权限、Hadoop 安装配置、HDFS 读写、MapReduce 编程串成一条完整链路而不是零散地看教程。2. Hadoop 伪分布环境搭建从 JDK、SSH 到 core-site.xml 的参数细节2.1 三种安装模式怎么选为什么先练伪分布而不是直接上集群Hadoop 的安装模式分三种单机模式、伪分布模式、全分布模式。单机模式所有进程跑在一个 Java 进程里不启动 HDFS也不走网络适合跑本地调试伪分布模式是在一台机器上分别启动 NameNode、DataNode、SecondaryNameNode 等独立进程每个进程一个 JVM网络协议、文件读写路径跟真实集群完全一致只是所有角色挤在一台机器上全分布才是我们说的集群至少三台机器。实验报告里选的路径就是单机起步、伪分布做主力、最后再往 2.X 全分布迁移。这个顺序很合理——伪分布模式能暴露几乎所有真实集群会遇到的配置问题比如端口冲突、ssh 免密失效、格式化不一致但排查时只需要盯一台机器。我的建议是不要跳过伪分布直接搭集群。你在伪分布模式下踩过的坑在全分布模式下会以更复杂的形式再出现一遍比如节点间免密登录失败、DataNode 之间副本摆放异常。报告里提到与 Hadoop1.X 类似部署 Hadoop2.X这里要提醒一句1.X 和 2.X 的配置文件名字不一样1.X 是 hadoop-site.xml 拆成 core-site.xml、hdfs-site.xml、mapred-site.xml2.X 还多了 yarn-site.xml。报告的实验内容里两个版本混着用实际动手时认准一个版本我建议用 2.x 系列教程多、社区踩坑记录全。2.2 环境准备JDK、openssh-server 与 rsync 的安装顺序实验报告第一步是添加用户及用户组添加 sudo 权限。这是很关键的一步因为 Hadoop 官方文档明确要求不能用 root 跑否则很多目录权限检查会绕过去到集群模式下会因为权限不一致翻车。先创建一个专门用户sudo useradd -m hadoop sudo passwd hadoop sudo usermod -aG sudo hadoop-m参数会自动创建 home 目录-aG把用户追加到 sudo 组而不是覆盖原有组。创建完用户后用 hadoop 用户重新登录再安装依赖。报告里列的依赖是 openssh-server、java、rsync顺序不能乱先装 ssh 是为了后面做免密登录java 是 Hadoop 运行环境rsync 是在集群模式下同步分发文件用的。sudo apt-get update sudo apt-get install -y openssh-server rsync java -version # 确认 JDK 已装1.7 或 1.8 均可实验报告里写不知道该如何下载 java jdk这是初学者最常见的卡点。不建议用 yum 装 OpenJDK 以外的版本直接apt-get install openjdk-8-jdk或者去 Oracle 官网下 tar 包解压到/usr/local/java然后配环境变量。注意 Hadoop 2.x 用 JDK 1.7 即可Hadoop 3.x 要求 JDK 8选版本要对上。2.3 ssh 免密登录伪分布模式最容易被忽视的一步伪分布模式虽然只有一台机器但 Hadoop 启动脚本仍然会通过 ssh 去连接 localhost 启动远端进程所以免密登录不做后面 start-dfs.sh 会卡在输密码的地方而且每次启动都要输好几遍相当折磨。配置过程如下ssh-keygen -t rsa -P -f ~/.ssh/id_rsa cat ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys ssh localhost-P 表示私钥不设口令后面 ssh 连接时不需要交互输密码chmod 700和chmod 600是 ssh 的硬性要求权限太宽松会导致 ssh 直接忽略这个文件。执行完最后一行ssh localhost如果不需要输密码直接返回说明免密配置成功。实验报告里提到配置 ssh 免密码登录没展开实际有相当多的人卡在这一步——不是 key 生成的问题而是.ssh目录权限不对。另外还要设置 hosts 映射。报告实验步骤第 9 条写了设置 Host 映射文件把主机名映射到 IP避免 Hadoop 进程之间通过主机名解析失败。编辑/etc/hosts把127.0.0.1 localhost这行保留再加一行主机名映射127.0.0.1 localhost 192.168.1.100 hadoop-node如果你在同一台机器跑伪分布映射到 127.0.0.1 就行如果后面迁移到多节点每台机器都要把其他节点的主机名和 IP 写进 hosts。2.4 core-site.xml 与 hdfs-site.xml五个关键参数的作用实验报告的实验步骤第 5 条只写了修改 core-site.xml没写具体改了哪些。这是整个搭建过程信息量最大的地方。伪分布模式下core-site.xml 至少要配两个属性一个是默认文件系统地址一个是临时目录configuration property namefs.defaultFS/name valuehdfs://localhost:9000/value /property property namehadoop.tmp.dir/name value/home/hadoop/hadoopdata/value /property /configurationfs.defaultFS决定了 HDFS 的访问入口9000 是 NameNode 的 RPC 端口客户端和 DataNode 都通过这个端口跟 NameNode 通信。hadoop.tmp.dir是 Hadoop 存储临时文件和数据块的根目录必须改成非默认路径——默认值在/tmp下系统重启会清空导致 NameNode 元数据丢失启动报错。hdfs-site.xml 里最常改的参数是副本数和 NameNode 元数据路径configuration property namedfs.replication/name value1/value /property property namedfs.namenode.name.dir/name valuefile:/home/hadoop/hadoopdata/namenode/value /property property namedfs.datanode.data.dir/name valuefile:/home/hadoop/hadoopdata/datanode/value /property /configuration伪分布模式只有一台机器dfs.replication必须设为 1否则默认 3 份副本会全部尝试落在同一个 DataNode 上虽然不会报错但会反复写三遍浪费磁盘。dfs.namenode.name.dir和dfs.datanode.data.dir分别指定元数据和数据块的存储目录最好拆开避免混在同一个目录下导致互相覆盖。2.5 格式化、启动与验证jps 命令能看到的五个进程配置改完下一步是格式化 HDFS 文件系统。这一步只执行一次重复执行会把 NameNode 的元数据清空导致 DataNode 的集群 ID 对不上。格式化命令hdfs namenode -format格式化成功会输出Storage directory ... has been successfully formatted。接着启动 Hadoop 进程1.X 用start-all.sh2.X 推荐分开启动start-dfs.sh jpsjps是 JDK 自带的 Java 进程查看工具能看到当前用户启动的 Java 进程。伪分布模式正常情况应该看到五个进程NameNode、DataNode、SecondaryNameNode、ResourceManager2.X、NodeManager2.X。如果只看到三四个说明某个角色启动失败后面避坑章节会展开讲。验证 HDFS 是否可用最直接的方式是用命令行上传一个文件再读回来echo hello hadoop test.txt hdfs dfs -mkdir -p /input hdfs dfs -put test.txt /input/ hdfs dfs -cat /input/test.txt3. HDFS 读写原理与实操NameNode、DataNode 角色和命令行验证3.1 HDFS 架构为什么是 Master/Slave 而不是对等结构实验报告用了谷歌 GFS 山寨版本这个词形容 HDFS虽然直白但很准确。HDFS 是典型的 Master/Slave 架构三个角色分工明确NameNode 管元数据DataNode 管数据块SecondaryNameNode 定期合并 NameNode 的编辑日志。报告里说得很清楚NameNode 维护文件系统的目录树和文件到数据块的映射DataNode 实际存储数据块。之所以用这种主从结构是因为大数据的场景是一次写入、多次读取对数据一致性的要求远高于对并发写的需求集中式元数据管理能大幅降低维护多个节点间元数据同步的复杂度。读取文件时客户端直接跟 NameNode 要数据块位置然后去 DataNode 拉数据NameNode 只负责指路不参与实际数据传输写入时客户端先问 NameNode 要数据块分配信息再流水线式地把数据推给多个 DataNode。这种设计把元数据流量和数据流量分开避免 NameNode 成为瓶颈。3.2 读操作open() 背后的元数据查询与就近读取报告里只提了一句客户端通过调用 FileSystem 对象的 open() 方法打开文件实际流程比这句复杂得多。客户端调用 open() 后DistributedFileSystem 会向 NameNode 发起 RPC 请求拿到该文件所有数据块的位置列表然后根据网络拓扑挑选离客户端最近的 DataNode 建立连接读取数据。读取过程中如果某个 DataNode 挂了客户端会跳过它向 NameNode 重新申请位置换一个 DataNode 继续读。这里要注意的是HDFS 读取的最小单位是数据块而不是字节。一个文件可能横跨多个数据块客户端读取时需要按块逐个读取块与块之间通过偏移量定位。实验报告里 HDFS 读操作的命令测试例子其实是用 Java 代码实现的后续实验步骤里使用编译代码读取 HDFS 文件就是这个意思。3.3 写操作create() 与流水线副本复制写操作的流程在报告里也只有一句通过 create() 方法创建新文件这里值得展开。客户端调用 create() 后NameNode 会检查文件是否已存在、客户端是否有写权限然后创建一条新的数据写入管道。客户端把数据按块切分写入第一个 DataNode第一个 DataNode 写入完成后把数据块转发给第二个 DataNode以此类推形成一条复制流水线。伪分布模式下只有一个 DataNode所以这条流水线只有一跳dfs.replication设为 1 时不需要等待副本确认写入速度会快得多。但要注意如果副本数大于 DataNode 数量数据块会一直处于 Under-Replicated 状态NameNode 会持续尝试复制副本日志里会不断出现ReplicationMonitor相关的告警。3.4 命令行实测上传、查看、下载一个文件实验报告的测试例子是把本地文件上传到 HDFS再通过程序读取。命令行方式更直观先创建目录再上传文件然后查看和下载一套走完就理解了 HDFS 的文件组织方式hdfs dfs -mkdir -p /user/hadoop/input hdfs dfs -put test.txt /user/hadoop/input/ hdfs dfs -ls /user/hadoop/input hdfs dfs -cat /user/hadoop/input/test.txt hdfs dfs -get /user/hadoop/input/test.txt ./-mkdir -p和 Linux 的mkdir -p语义一致自动创建父目录-put是本地文件上传到 HDFS-get是反向下载-ls和-cat跟 Linux 同名命令行为类似。命令执行完后可以再用hdfs dfs -stat查看文件块大小和副本数确认配置生效。4. MapReduce 从原理到跑通环形缓冲区、shuffle 参数与气象数据案例4.1 MapReduce 运行模型一个作业怎么被拆开执行报告里把 MapReduce 拆成两个阶段来描述Map 阶段把计算作业拆分成若干个 Map 任务分配到不同节点执行产出中间文件Reduce 阶段把 Map 输出的中间文件汇总并输出。这个模型的核心思想是计算向数据移动——不需要把海量数据传到计算节点而是把计算逻辑分发到数据所在的节点上执行。一个 MapReduce 作业从提交到完成要经过 JobTracker1.X或 ResourceManager2.X的调度。Map 任务读取输入分片逐个调用 map() 函数处理键值对输出写入环形缓冲区缓冲区溢出后写入本地磁盘形成中间文件Reduce 任务从各个 Map 任务拉取属于自己分区的数据排序合并后调用 reduce() 函数。报告里特别提到每个 map 传来的数据都是有序的这是 Map 端本地排序和分区的结果Reduce 端拿到的是多个有序数据流做归并排序时效率很高。4.2 Map 端细节分片大小、环形缓冲区与溢写比例实验报告给了两个具体参数输入分片默认 64MHDFS 块大小环形缓冲区默认 100M由io.sort.mb控制缓冲区溢写阈值是 80%由io.sort.spill.percent控制。1.X 的块大小是 64M2.X 起默认改成 128M分片默认跟随块大小处理超大文件时可以通过mapred.min.split.size调大分片减少任务数。这里有个很多人忽略的细节当缓冲区达到 80% 时会有一个后台线程开始溢写但如果溢写速度跟不上 Map 输出速度缓冲区会继续增长到 100%Map 任务会被阻塞。所以调io.sort.mb不是越大越好要考虑 JVM 堆内存和 GC 压力。我的习惯是伪分布实验保持默认值不动先跑通再说到了需要调优的阶段优先观察日志里的Spilling to disk频率如果溢出文件太多说明缓冲区可能偏小。4.3 Reduce 端细节shuffle、合并与内存比例Reduce 端报告的参数有两个mapred.job.shuffle.input.buffer.percent控制 shuffle 阶段用作存储 map 输出的堆内存百分比mapred.job.shuffle.merge.percent控制内存数据达到该比例后合并溢写。这里的核心逻辑是Reduce 任务启动后先启动一个 ShuffleConsumerPlugin从每个 Map 任务所在节点拉取属于自己分区的数据边拉边合并排序最终形成有序的输入流喂给 reduce() 函数。实际运行中最容易出问题的是拉取失败或超时表现为 Reduce 卡在Shuffle阶段很久不动。常见原因是 Map 任务输出文件所在节点网络延迟或者 Reduce 任务数设置太少、单个 Reduce 要拉取的数据量过大。实验报告里温度统计的例子由于数据量小基本不会有这类问题但如果换到真实生产数据Reduce 端参数就得按数据量重新调。4.4 气象数据实验从编写代码到查看结果报告里 MapReduce 的测试例子是气象数据温度统计这是 Hadoop 官方教程的经典案例。过程分六步编写代码、编译、打包、解压气象数据并上传到 HDFS、运行程序、查看结果。伪分布模式下用 Hadoop Streaming 跑 Python 脚本的方式更轻但实验报告用的是 Java 代码这里给出一个最小可运行的 Java 温度统计实现public class MaxTemperature { public static class Map extends MapperObject, Text, Text, IntWritable { public void map(Object key, Text value, Context context) throws IOException { String line value.toString(); // 气象数据固定格式年份在第 15-19 位气温在第 87-91 位 String year line.substring(15, 19); int temp Integer.parseInt(line.substring(87, 91)); context.write(new Text(year), new IntWritable(temp)); } } public static class Reduce extends ReducerText, IntWritable, Text, IntWritable { public void reduce(Text key, IterableIntWritable values, Context context) throws IOException { int max Integer.MIN_VALUE; for (IntWritable v : values) { max Math.max(max, v.get()); } context.write(new Key, new IntWritable(max)); } } }这段代码里最关键的是substring(15, 19)和substring(87, 91)这两个位置参数它们依赖气象数据 NCDC 格式的固定字段位置数据文件格式变了就要同步调整。Map 阶段输出的是年份和气温的键值对Reduce 阶段对同一年的所有气温值取最大值最终输出结果就是每年的最高气温。编译打包用javac和jar命令或者用 Maven 打 jar 包然后通过hadoop jar提交作业。运行命令和查看结果hadoop jar max-temp.jar MaxTemperature /input/weather /output/weather hdfs dfs -cat /output/weather/part-r-000005. 避坑专场Hadoop 起不来、连不上、跑不完的五个常见问题5.1 NameNode 进程反复退出格式化与目录冲突现象执行start-dfs.sh后jps看不到 NameNode查看日志发现NameNode启动失败报错信息里出现storage directory already exists或者NameNode is not formatted。原因两种典型情况。第一种是没格式化就启动NameNode 找不到元数据存储目录第二种是格式化了多次DataNode 和 NameNode 的集群 ID 不一致。伪分布实验里很多人会在反复修改配置后重跑hdfs namenode -format导致 NameNode 的元数据被重置但 DataNode 的数据块目录还保留着旧 ID两个进程之间互相不认。解决先停掉所有 Hadoop 进程把dfs.namenode.name.dir和dfs.datanode.data.dir指向的目录整个删掉再重新执行hdfs namenode -format然后启动。注意只在第一次搭建或确认数据可以丢弃时才这样做生产环境严禁删目录重来。从那以后我每次改完配置都先看日志再考虑重格式化而不是无脑删目录。5.2 ssh localhost 仍要密码权限太宽松或 key 追加位置不对现象执行ssh localhost后仍然提示输入密码但ssh-keygen和cat追加公钥的操作都执行过。原因.ssh目录或authorized_keys文件的权限不对。ssh 有严格的权限检查.ssh目录权限必须是 700authorized_keys必须是 600权限过宽会直接跳过这个文件另外公钥必须追加到~/.ssh/authorized_keys而不是放在其他位置。解决chmod 700 ~/.ssh和chmod 600 ~/.ssh/authorized_keys然后重新ssh localhost验证。如果还是不行用ssh -vvv localhost看调试输出定位到具体哪一步拒绝。5.3 SecondaryNameNode 端口冲突默认端口被占用现象启动时 NameNode 和 DataNode 都起来了但 SecondaryNameNode 起不来日志报BindException: Address already in use。原因SecondaryNameNode 默认用 50090 端口如果之前实验残留了进程没杀干净或者有其他服务占用了端口就会绑定失败。解决先jps看是否有残留的 Hadoop 进程有的话kill -9干掉再用netstat -tlnp | grep 50090查占用进程也可以直接改配置文件里dfs.secondary.http.address换一个端口比如 50091。5.4 DataNode 连不上 NameNodeIPv6 与 hosts 解析现象NameNode 正常DataNode 反复启动失败日志里报java.net.UnknownHostException或者Connection refused但 ping localhost 又是通的。原因CentOS 6 默认开启了 IPv6localhost解析到::1而 Hadoop 进程监听的是 IPv4 地址导致连接失败。这是伪分布环境最容易忽略的问题。解决在/etc/hosts里把127.0.0.1 localhost放在::1 localhost前面或者在$HADOOP_HOME/etc/hadoop/hadoop-env.sh里加一行export HADOOP_OPTS-Djava.net.preferIPv4Stacktrue强制走 IPv4。5.5 温度统计跑到 100% 报错内存与 JVM 参数现象MapReduce 作业起跑后Map 任务完成Reduce 阶段直接报错退出日志里有java.lang.OutOfMemoryError: Java heap space。原因实验报告的环境是虚拟机 1G 内存。伪分布模式下 NameNode、DataNode、SecondaryNameNode、ResourceManager、NodeManager 五个进程共享这 1G 内存再加上 MapReduce 的 JVM 默认堆内存设置偏大很容易 OOM。尤其是温度统计这种需要把所有年份数据加载进内存的作业小内存环境扛不住。解决调小每个进程的内存配置。在mapred-site.xml里设置mapreduce.map.memory.mb和mapreduce.reduce.memory.mb比如都设 512或者给 Map 和 Reduce 任务的 JVM 加-Xmx256m参数。如果只是做实验也可以关掉 ResourceManager 和 NodeManager只跑 HDFS把内存留给计算任务。6. 进阶验证技巧从伪分布到全分布的迁移清单与日常巡检命令6.1 从伪分布走向真分布式三台机器的迁移清单伪分布跑通之后往三台机器迁移时核心工作是把单机配置拆成多机配置。我的习惯是固定一台 master 和两台 slave先做好三台机器的 hosts 映射然后生成免密登录时把 master 的公钥分发到所有机器上包括 master 自己。配置文件的迁移要点是把core-site.xml里fs.defaultFS的localhost改成 master 的主机名hdfs-site.xml里dfs.replication从 1 改成 2三台机器存两份副本yarn-site.xml里指向 master 的 ResourceManager 地址然后编辑slaves文件写入两台 slave 的主机名。启动顺序有讲究先在 master 格式化 HDFS启动 NameNode 和 ResourceManager再逐台启动 DataNode 和 NodeManager。经常有人直接在 master 上执行start-all.sh期望脚本自动把所有节点拉起来——脚本确实会尝试通过 ssh 去 slave 上启动进程所以前面免密登录没做扎实这里就会失败。6.2 每天动手前先做的三件事jps、日志、磁盘从实验报告里能看到几乎所有问题都集中在启动失败、连接失败、资源不足三类。我养成的习惯是每天动手前先执行一遍检查和日志轮询的命令jps hdfs dfsadmin -report df -h /home/hadoop/hadoopdata tail -20 $HADOOP_HOME/logs/hadoop-hadoop-namenode-*.logjps看五个进程在不在hdfs dfsadmin -report看 DataNode 是否存活、副本数是否正常df -h看数据目录所在磁盘空间——伪分布环境最容易出现磁盘写满导致 DataNode 退出的情况日志文件用tail看最后 20 行能在启动失败时第一时间定位错误。这套操作花不了两分钟却能把大半启动问题扼杀在动手之前。实验报告里的踩坑记录其实很有价值——不知道如何下载 JDK、不会在目录下创建文件、不理解 Hadoop 环境配置原理和编译原理这些都不是笨而是缺少一条完整的链路把零散知识串起来。希望这篇拆解能帮你把这条链路走通。本文还有配套的精品资源点击获取