简介:这是Apache Hadoop 2.6.5的Linux安装包,面向需要搭建分布式计算实验环境的大数据初学者、运维及开发工程师,解决Hadoop环境准备与基础集群部署问题。压缩包共900个文件,约175.09MB,包含477个jar依赖库、129个class类文件、51个xml配置模板、50个shell启动脚本以及日志、文档、Web界面资源等,目录结构完整,解压后即可获得官方标准发行版。已有1266人学习,常被用于HDFS、MapReduce、YARN的入门实践与排错参考。通过安装并配置core-site.xml、hdfs-site.xml、mapred-site.xml、yarn-site.xml等文件,可快速搭建单机或集群环境;包内自带的示例程序、命令脚本和默认配置,也能帮助读者理解分布式存储机制、资源调度流程及常见安全认证设置,为后续接入Hive、Spark等生态组件打下基础。 我从一个实际问题说起:很多人在网上下载了hadoop-2.6.5.tar.gz,解压完就卡住了。网上教程铺天盖地,但大多只告诉你"改这几个文件、跑这几条命令",至于为什么这么改、报错之后从哪查起,基本没人讲。这篇文章是我自己从零开始装 Hadoop 2.6.5 的完整记录,包含每一步的配置说明、启动验证、以及我在这个过程中踩过的真实坑。无论你是课程设计、面试准备,还是在维护老项目,照着走一遍应该能少花很多冤枉时间。
需要先说明的是,2.6.5 是 2.x 时代比较稳定的版本,很多学校的课程、旧项目、以及秋招面试题都还围绕着这一代 Hadoop 展开。虽然它确实老了,但 Hadoop 的核心思想——HDFS 的块存储、NameNode/DataNode 架构、YARN 的资源调度——到今天都没变。把这个版本吃透,再去看 3.x 无非是端口和部分参数变了,学习成本会低很多。
1. 版本选择与前置环境:为什么 2.6.5 还值得装
很多人会问,现在都 Hadoop 3.x 了,为什么还要折腾 2.6.5?我在实际使用中发现,这个版本在教学、课程设计和老项目维护场景里的出现频率非常高。尤其是学校的实验课,很多教材和实验手册还是基于 2.x 写的,配套的 Hive、Spark 版本也对齐的是 2.x 生态。直接上 3.x 反而会碰到不少兼容性问题。
2.6.5 对 JDK 的要求是 JDK 7 或者 JDK 8。我用的是 JDK 8,因为现在 JDK 7 的下载渠道不太好找,而且 JDK 8 在语法层面兼容 JDK 7,跑 Hadoop 2.6.5 完全没问题。需要注意两点:一是不要用太高版本的 JDK(比如 JDK 11 或 17),Hadoop 2.6.5 没有适配过,启动时会报一些奇怪的类加载错误;二是确认JAVA_HOME环境变量已经配置好,java -version能正常输出。
操作系统方面,我推荐 CentOS 7 或者 Ubuntu 16.04/18.04 这类老一点但还在维护期的系统。如果你用的是更新的 Ubuntu 版本,比如 22.04,可能需要在编译本地库时额外处理一些依赖问题。生产环境里用得最多的还是 CentOS 7,所以我后面的操作步骤以 CentOS 7 为准。
安装前还有一个容易忽略的点:需要确认/etc/hostname和/etc/hosts的配置。Hadoop 集群内部是靠主机名互相通信的,如果主机名解析有问题,启动时会出现节点之间连不上的情况。我在单机伪分布式模式下就遇到过,因为/etc/hosts里没配本机的主机名映射,DataNode 一直起不来。配置方式很简单,在/etc/hosts里加一行:
127.0.0.1 hadoop-node然后把/etc/hostname改成对应的名字。改完记得reboot或者执行hostnamectl set-hostname hadoop-node让配置生效。
处理完这些之后,就可以解压 Hadoop 了。我习惯把安装目录统一放在/usr/local下面:
tar -zxf hadoop-2.6.5.tar.gz -C /usr/local/ cd /usr/local/ ln -s hadoop-2.6.5 hadoop做软链接是为了后续升级方便,以后装了新版本,改一下链接指向就行,环境变量不用动。
2. 四个核心配置文件的逐项说明:看懂参数才能真正会配
Hadoop 2.6.5 的配置集中在$HADOOP_HOME/etc/hadoop/目录下。初始化配置只要关注四个文件:core-site.xml、hdfs-site.xml、yarn-site.xml、mapred-site.xml。我在第一次配置时犯过一个错:照着网上的模板直接复制粘贴,结果连fs.defaultFS都不理解是什么意思,后来遇到问题完全无从下手。这里把每个文件的关键参数讲透。
2.1 core-site.xml:全局入口配置
core-site.xml是整个 Hadoop 的核心配置,最关键的参数是fs.defaultFS,它决定了 HDFS 的访问入口地址。伪分布式模式下,这个地址指向本机的 NameNode:
<configuration> <property> <name>fs.defaultFS</name> <value>hdfs://localhost:9000</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/usr/local/hadoop/tmp</value> </property> </configuration>第二个参数hadoop.tmp.dir很容易被忽略,但非常重要。NameNode 的元数据、DataNode 的数据块都默认存放在这个目录下。如果不手动指定,会使用系统默认的/tmp目录,而/tmp在系统重启时可能被自动清理,导致数据丢失。我在后来的集群部署中吃过这个亏,重启服务器之后整个 HDFS 的数据都没了,只能重新格式化。所以这里一定要指定到一个持久化目录。
2.2 hdfs-site.xml:副本与元数据策略
hdfs-site.xml控制 HDFS 的行为。伪分布式模式有一个关键点:默认副本数是 3,但在单节点上只有 1 个 DataNode,所以必须把副本数改成 1,否则会一直报块不足的警告:
<configuration> <property> <name>dfs.replication</name> <value>1</value> </property> <property> <name>dfs.namenode.name.dir</name> <value>/usr/local/hadoop/tmp/dfs/name</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>/usr/local/hadoop/tmp/dfs/data</value> </property> </configuration>dfs.namenode.name.dir和dfs.datanode.data.dir分别指定 NameNode 元数据目录和 DataNode 数据块目录。这里我建议显式指定,而不是依赖默认值。原因和hadoop.tmp.dir一样,都是为了数据安全和后续排查问题方便。面试的时候经常问"NameNode 挂了怎么恢复",答案的关键就是在dfs.namenode.name.dir下保留的fsimage和edits文件,理解这个参数就懂了。
2.3 mapred-site.xml 与 yarn-site.xml:计算框架的接入
Hadoop 2.x 最大的变化就是引入了 YARN,MapReduce 从"一个独立的计算系统"变成了"跑在 YARN 上的应用"。所以mapred-site.xml需要指定 MapReduce 的运行框架为 YARN。
需要注意,这个文件在解压后默认叫mapred-site.xml.template,要手动复制一份出来:
cp /usr/local/hadoop/etc/hadoop/mapred-site.xml.template /usr/local/hadoop/etc/hadoop/mapred-site.xml内容如下:
<configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> </configuration>yarn-site.xml里需要配置 ResourceManager 的地址和 NodeManager 的辅助服务。辅助服务是 NodeManager 启动的、用于处理特定任务的容器,MapReduce 的ShuffleHandler就是通过这个机制运行的。如果不配置,提交 MapReduce 作业时会一直卡住:
<configuration> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <name>yarn.nodemanager.aux-services.mapreduce_shuffle.class</name> <value>org.apache.hadoop.mapred.ShuffleHandler</value> </property> </configuration>这里用了一个隐含的键名规则:yarn.nodemanager.aux-services.mapreduce_shuffle.class,即"辅助服务名 + .class"。知道这个规则之后,以后加别的辅助服务也能自动类推。
2.4 环境变量配置:hadoop-env.sh 的关键一行
最后一个必须改的配置文件是hadoop-env.sh,在里面指定 JAVA_HOME:
export JAVA_HOME=/usr/local/jdk1.8.0_202我在初学阶段没有改这个文件,结果start-dfs.sh启动时报找不到 JAVA_HOME 的错误。原因很简单:Hadoop 的启动脚本要通过hadoop-env.sh找到 Java 环境,虽然系统里已经配了JAVA_HOME环境变量,但 Hadoop 脚本在解析时存在变量优先级问题,直接硬编码进去最省事。
配置好这四个文件加一个环境变量后,可以执行hadoop version验证基础环境是否正常。
3. 格式化、启动与初始化验证:首次启动全流程
3.1 NameNode 格式化:只有第一次需要
启动 HDFS 之前,必须先格式化 NameNode。这个操作会初始化 HDFS 的文件系统元数据,生成dfs.namenode.name.dir目录下的fsimage文件:
hdfs namenode -format格式化过程中,终端会打印大量日志,最后出现successfully formatted字样就说明成功了。这里有一个经典面试题:为什么格式化之后不能再随便格式化,否则会丢失数据?因为格式化会生成一个新的空元数据状态,如果旧 DataNode 上已经存了数据块,而 NameNode 却以为文件系统是空的,数据块就变成"孤儿块"了,只能手动清理或等待系统自行处理。
3.2 启动 HDFS 和 YARN
格式化完成后,分别启动 HDFS 和 YARN:
sbin/start-dfs.sh sbin/start-yarn.sh启动过程中如果配置正确,会提示启动 NameNode、DataNode、SecondaryNameNode、ResourceManager、NodeManager 五个进程。启动完一定要用jps命令检查进程状态:
jps正常的输出应该类似这样:
12345 NameNode 12346 DataNode 12347 SecondaryNameNode 12348 ResourceManager 12349 NodeManager只要缺一个进程,就说明对应的节点没有被正确启动。我遇到的最常见的情况是 DataNode 缺失,大概率是因为/etc/hosts里没有配置主机名映射,或者是dfs.datanode.data.dir目录的权限不对,导致 DataNode 启动后直接退出。
启动成功后,可以通过 Web 界面访问 HDFS 和 YARN 的状态。2.6.5 版本中,NameNode 的 Web 端口是50070,ResourceManager 的 Web 端口是8088:
- HDFS 管理界面:
http://localhost:50070 - YARN 资源管理界面:
http://localhost:8088
如果本机访问没问题,但在其他机器上无法访问,记得检查防火墙是否放行了这两个端口。
3.3 用 HDFS 命令做冒烟测试
进程全部起来后,不要急着跑 MapReduce,先在 HDFS 上做一轮基本的文件操作,验证 HDFS 读写链路是否正常:
hdfs dfs -mkdir -p /user/test hdfs dfs -put /etc/hosts /user/test/ hdfs dfs -ls /user/test/ hdfs dfs -cat /user/test/hosts如果上传下载都正常,说明 NameNode、DataNode 之间的通信没有问题。这时候再去跑 WordCount 才有意义。
4. 伪分布式跑通之后的真实踩坑记录
4.1 "jar does not exist or is not a normal file" 的排查链路
这个报错是我在写启动脚本时遇到的,完整信息类似:
jar does not exist or is not a normal file: /usr/local/hadoop/share/hadoop/m乍一看似乎是 Hadoop 安装包本身不完整,或者路径写错了。但我的share/hadoop目录下明明有mapreduce子目录。后来我仔细比对发现,问题出在一个很隐蔽的地方:环境变量里有尾随字符。
我当时的HADOOP_HOME配置是这样写的:
export HADOOP_HOME=/usr/local/hadoop本身没问题。但在另一个脚本里,我拼接了$HADOOP_HOME/share/hadoop/mapreduce,由于变量展开时末尾多了个不可见字符,最终路径就变成了/usr/local/hadoop/share/hadoop/m,后半部分被截掉了。排查的方法是打印出最终拼接的路径:
echo $HADOOP_HOME/share/hadoop/mapreduce结果发现路径末尾有个^M字符——这是 Windows 编辑文件后留下的 DOS 换行符。用dos2unix工具批量转换所有脚本文件后,问题解决:
yum install -y dos2unix dos2unix /usr/local/hadoop/etc/hadoop/*.sh dos2unix /usr/local/hadoop/sbin/*.sh这里顺便提醒:写 Hadoop 相关配置文件和脚本时,尽量用vi或 VSCode 的 LF 换行模式,不要用 Windows 记事本编辑。
4.2 50070 端口访问不了,进程却在跑
还有一种情况是jps显示 NameNode 进程在,但浏览器无法访问50070端口。我用netstat -tunlp | grep 50070查看端口监听,发现端口根本没有监听。于是去查看 NameNode 日志:$HADOOP_HOME/logs/hadoop-hadoop-namenode-*.log,日志里会记录启动失败的原因。我自己遇到的是dfs.namenode.name.dir配置的目录没有创建成功,导致元数据写入失败。解决办法是先手动创建目录:
mkdir -p /usr/local/hadoop/tmp/dfs/name mkdir -p /usr/local/hadoop/tmp/dfs/data然后重新格式化、重启进程。很多启动失败的问题,归根结底是忘记手动创建目录、目录权限不对、或者/etc/hosts没配好,这三个原因占了 80% 以上。
4.3 伪分布式模式下内存配置
2.6.5 默认会为每个 Java 进程分配较大内存。我的开发机只有 8G 内存,跑start-dfs.sh和start-yarn.sh五个进程后系统明显变卡。可以在hadoop-env.sh里调整:
export HADOOP_HEAPSIZE=512 export HADOOP_NAMENODE_OPTS="-Xmx512m $HADOOP_NAMENODE_OPTS" export HADOOP_DATANODE_OPTS="-Xmx512m $HADOOP_DATANODE_OPTS" export YARN_RESOURCEMANAGER_OPTS="-Xmx512m $YARN_RESOURCEMANAGER_OPTS" export YARN_NODEMANAGER_OPTS="-Xmx512m $YARN_NODEMANAGER_OPTS"这样改完之后,内存占用会小很多。生产环境不建议这么调,但学习环境完全够用。
5. 从单机到集群:完全分布式扩展与 Zookeeper 整合思路
伪分布式跑通只是第一步,实际工作或面试中更常遇到的是完全分布式集群,以及 Hadoop 和 Zookeeper 的整合。2.6.5 的集群搭建可以复用前面大部分配置,区别主要在主从节点的角色划分上。
5.1 完全分布式的最少改动方案
假设有三台机器:hadoop01、hadoop02、hadoop03。其中hadoop01作为 NameNode 和 ResourceManager,三台机器都作为 DataNode 和 NodeManager。
需要修改的地方有三个:
一是core-site.xml中的fs.defaultFS改为:
<property> <name>fs.defaultFS</name> <value>hdfs://hadoop01:9000</value> </property>二是hdfs-site.xml中的副本数改为 3(如果只有 3 个节点,副本数不要超过节点数):
<property> <name>dfs.replication</name> <value>3</value> </property>如果集群里有 5 个节点,但配置副本数为 3,实际只会存 3 份,这是正常现象。
三是yarn-site.xml中指定 ResourceManager 所在的主机:
<property> <name>yarn.resourcemanager.hostname</name> <value>hadoop01</value> </property>然后通过rsync把整个 Hadoop 目录分发到其他节点:
rsync -av /usr/local/hadoop/ hadoop02:/usr/local/hadoop/ rsync -av /usr/local/hadoop/ hadoop03:/usr/local/hadoop/最后在hadoop01上执行格式化,然后启动 HDFS 和 YARN。DataNode 和 NodeManager 都会通过 SSH 免密自动启动。
这里提醒一点:3.x 的hdfs-site.xml里还需要配置dfs.namenode.http-address之类的参数,但 2.6.5 有默认值,不配也能跑,所以看起来比 3.x 简单一些。
5.2 与 Zookeeper 整合:为什么要引入 ZK
Hadoop 2.x 里引入 Zookeeper,最核心的场景是 NameNode 高可用(HA)。单 NameNode 架构有单点故障问题:NameNode 进程挂了,整个 HDFS 就不可写了。HA 模式下,Active NameNode 和 Standby NameNode 之间通过 JournalNode 同步元数据,Zookeeper 负责自动故障切换。
在我做过的整合实践中,Zookeeper 起到的作用是"选主"。当 Active NameNode 异常时,Zookeeper 的临时节点会超时释放,触发 Standby NameNode 切换为 Active。配置hdfs-site.xml时,需要增加:
<property> <name>dfs.nameservices</name> <value>mycluster</value> </property> <property> <name>dfs.ha.namenodes.mycluster</name> <value>nn1,nn2</value> </property> <property> <name>dfs.namenode.rpc-address.mycluster.nn1</name> <value>hadoop01:9000</value> </property> <property> <name>dfs.namenode.rpc-address.mycluster.nn2</name> <value>hadoop02:9000</value> </property>同时需要在core-site.xml里把fs.defaultFS指向 nameservice 名称:
<property> <name>fs.defaultFS</name> <value>hdfs://mycluster</value> </property>Zookeeper 集群我一般部署 3 台,因为奇数台才能形成多数派投票。2.6.5 的 HA 配置链比较长,如果只是做课程设计,不建议一上来就上 HA;先把伪分布式和完全分布式的 HDFS 读写、YARN 作业跑通,再逐步加 HA 更稳妥。
5.3 集群扩容与 Hive 接人的大致路径
集群跑了一段时间,发现磁盘不够用,需要新增 DataNode 节点。这个操作其实比想象中简单:新机器上装好 Hadoop、配好hdfs-site.xml和yarn-site.xml,然后只启动 DataNode 和 NodeManager:
sbin/hadoop-daemon.sh start datanode sbin/yarn-daemon.sh start nodemanagerNameNode 会自动识别新加入的 DataNode,不需要重启整个集群。通过 50070 界面就能看到新增节点的容量信息。
Hive 的安装则是另一条线。Hive 本身只是 MapReduce 的 SQL 翻译层,需要先有 Hadoop、MySQL(存放元数据)、以及对应的 Hive 安装包。Hive 与 Hadoop 2.6.5 配套的是 Hive 1.2.1 或 2.x。安装后修改hive-site.xml,把元数据库连接信息指向 MySQL,就能通过beeline或hive-cli写 SQL 操作 HDFS 上的数据。很多 Python 的 SQL 脚本,本质上也是通过 HiveServer2 的 JDBC 端口(默认 10000)访问 HDFS 数据,理解了 Hive 在中间扮演的角色,就不会困惑"Python 怎么访问 HDFS 数据"了。
6. 基于 2.6.5 的学习与面试复习策略
装好 Hadoop 2.6.5 之后,怎么利用这个环境最大化学习效果?我的建议是不要止步于"能启动、能跑 WordCount",而是要主动去制造故障、观察现象、排查原因。这个过程最有利于真正理解 Hadoop 的运行机制,也能在面试时对答如流。
第一个值得做的小实验:手动杀掉 NameNode 进程,观察 HDFS 是否还能读写。你会发现,客户端命令会一直等待,直到超时。这背后体现的是 NameNode 单点故障的影响。此时再去看 HA 方案,就会理解为什么要引入 Zookeeper。
第二个值得做的是:手动向一个文件追加多次数据,观察 NameNode 的edits文件变化。HDFS 的原理是"小文件合并成大块",比如文件默认块大小是 128MB(2.6.5 默认是 128MB),写小文件也会占用一个块。用hdfs fsck /user/test -files -blocks查看块信息,能直观感受到小文件对 NameNode 内存的压力,这也是面试题"为什么 HDFS 不适合存大量小文件"的答案来源。
第三个实验是:配置mapred-site.xml中的mapreduce.job.reduces,跑一个测试作业,观察 Map 和 Reduce 的并行度变化。2.6.5 的 MapReduce 日志非常详细,在logs/userlogs目录下能看到每个 task 的完整输出。面试时被问"Map 数量和什么有关",你的回答如果包含实际观察的案例,说服力会完全不同。
我自己带新人时反复强调一句话:分布式系统的问题,绝大多数不是代码问题,而是配置问题和网络问题。配置文件改错一个键,或者/etc/hosts写错一行,有时候比代码 Debug 难得多。所以学习阶段不要怕折腾环境,多装几遍、多踩几个坑,积累的经验会比单纯看文档更有价值。
如果你正准备面试,建议重点准备这几个方向:HDFS 读写流程(客户端与 NameNode/DataNode 的交互过程)、YARN 的 ResourceManager 调度机制(Capacity Scheduler 和 Fair Scheduler 的差异)、MapReduce Shuffle 的细节、以及 HA 模式下 Zookeeper 的角色。这些内容在网上能找到大量资料,但真正理解它们还是要回到自己的环境里跑一遍、看一遍日志,概念才能变成常识。
另外,很多人问要不要直接用 Docker 镜像部署 Hadoop。我的看法是:如果目标是快速跑通业务逻辑、验证数据流程,用 Docker 镜像确实省事;但如果目标是学习 Hadoop 本身,强烈建议自己在虚拟机或物理机上手装一遍,把每一步配置文件、启动脚本、端口的作用搞清楚。因为真正到生产环境排查问题的时候,你面对的是一个没有图形化界面、没有一键脚本的裸系统,那时候只能靠基本功。
本文还有配套的精品资源,点击获取