ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Hadoop环境搭建全攻略:从伪分布式到完全分布式实战

Hadoop环境搭建全攻略:从伪分布式到完全分布式实战 很多准备入行大数据、正在准备课程设计或者面试的朋友第一次接触 Hadoop 环境搭建都会被它繁琐的配置步骤劝退。其实 Hadoop 本身并不复杂绝大多数卡壳都发生在几个固定的环节版本不匹配、SSH 免密没配好、配置文件写错、格式化只做一次还是两次没搞清楚。这篇把从零搭建的完整链路、每一步背后的原因以及我实际排障时遇到的各种坑一次性讲透。1. 动手之前的前置功课版本、JDK 和模式选择1.1 Hadoop 的三种运行模式你到底需要哪一种Hadoop 有本地模式、伪分布式、完全分布式三种模式很多人一上来就直接搜Hadoop 集群搭建结果被一堆配置淹没其实大可不必。本地模式就是单机跑 MapReduce不需要启动任何守护进程主要是用来测试代码逻辑的跑 WordCount 之类的程序足够了。这种模式环境变量配好就能直接用基本不涉及搭建这个概念。伪分布式模式是学习阶段最推荐的。在同一台机器上NameNode、DataNode、ResourceManager、NodeManager 这些进程全部启动通过配置文件把它们模拟成一个小集群。它能完整走通 HDFS 读写、YARN 任务提交、Web UI 查看这套流程是理解 Hadoop 工作原理性价比最高的方式。面试考的那些概念伪分布式环境里都能实际验证一遍。完全分布式才是生产环境的形态至少需要三台机器每台分配不同角色。这个模式适合集群规划学习、课程设计演示或者认真做集群管理但前提是你对伪分布式的启动流程和配置文件已经熟悉了。我见过不少新手一上来直接搞三台虚拟机完全分布式结果 NameNode 都起不来配置文件改得面目全非排查起来非常痛苦。建议路径是本地模式验证环境 → 伪分布式跑通 HDFS 和 MapReduce → 再上多节点集群。1.2 JDK 和 Hadoop 版本的对应关系版本问题是最容易埋雷的而且这个雷往往是十天半个月之后才炸。Hadoop 3.3.x 系列用 JDK 8 最稳官方文档明确说支持 JDK 8 和 JDK 11但实际上绝大多数教程、生产环境脚本、第三方组件适配都是基于 JDK 8 的。Hadoop 3.4 及以上版本开始支持 JDK 17但如果你用的是最新版 Hadoop配套的生态组件版本也要往上拉很容易踩兼容性坑。推荐的稳妥组合Hadoop 3.3.6 JDK 1.8最保守教程资源最多Hadoop 3.3.6 JDK 11也可以但部分老脚本可能有问题不要用 JDK 8 以下版本Hadoop 3.x 最低要求是 Java 8JDK 安装完成后记得确认java -version能正常输出版本。我遇到过一个情况系统自带 OpenJDK 和手动安装的 Oracle JDK 路径冲突which java指向了旧版本结果 Hadoop 启动脚本报了一堆乱七八糟的错。建议把 JAVA_HOME 写到 Hadoop 的etc/hadoop/hadoop-env.sh里而不是只依赖系统 PATH。1.3 用什么系统来跑Windows 还是 Linux 还是 Mac生产环境清一色 Linux但学习阶段用什么取决于你的实际条件。如果你已经有 Linux 服务器或者装了虚拟机那最好。如果是 Windows 上的 WSL现在也非常成熟Ubuntu 2204 上装 Hadoop 3.3.x 完全没问题。Mac 的话要注意一点Hadoop 3.3 在 M1/M2 芯片上可能有原生库兼容问题但只跑伪分布式基本不碰那些本地库问题不大。Windows 原生环境我强烈不建议。Hadoop 在 Windows 下要额外装 winutils.exe配置一堆路径权限还经常在启动时莫名其妙崩对学习毫无帮助。真要演示给同学看直接 WSL 比想办法把 Windows 跑通划算得多。2. 单机伪分布式实操从创建用户到跑通 WordCount2.1 环境准备主机名、专用用户和 SSH 免密这部分是最朴素但最关键的前置工作。建议创建一个专用用户来跑 Hadoop不要用 root。原因是 Hadoop 很多脚本会做用户权限检查而且 root 运行的进程在排查问题时很容易因为权限问题掩盖真实错误。useradd -m hadoop passwd hadoop然后给主机改名。Hadoop 集群里主机名就是节点的身份标识后续所有配置文件里都要用主机名而不是 IP。这个习惯从伪分布式就要培养起来不然到完全分布式阶段你会因为主机名混乱而崩溃。hostnamectl set-hostname hadoop-master echo 192.168.1.100 hadoop-master /etc/hostsSSH 免密是 Hadoop 启动过程中绕不开的环节。无论伪分布式还是完全分布式Hadoop 的启动脚本都会通过 SSH 去目标机器上启动 DataNode、NodeManager 这些进程。伪分布式虽然没有跨机器但脚本内部还是要通过 SSH 连到自己主机所以必须配好。ssh-keygen -t rsa -P -f ~/.ssh/id_rsa cat ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys ssh hadoop-master如果ssh hadoop-master能直接登录不需要密码这项就完成了。2.2 下载解压和四个配置文件的改动去 Apache 官网下载 Hadoop 二进制包放到/usr/local/下解压建立软链接方便后续升级wget https://archive.apache.org/dist/hadoop/common/hadoop-3.3.6/hadoop-3.3.6.tar.gz tar -zxvf hadoop-3.3.6.tar.gz -C /usr/local/ ln -s /usr/local/hadoop-3.3.6 /usr/local/hadoop chown -R hadoop:hadoop /usr/local/hadoop然后是环境变量建议写到~/.bashrc里export HADOOP_HOME/usr/local/hadoop export PATH$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin export JAVA_HOME/usr/local/jdk1.8.0_202接下来是 Hadoop 目录下etc/hadoop/里的几个文件。注意很多新手会试着去改 Hadoop 安装目录下别的配置文件你只需要碰core-site.xml、hdfs-site.xml、mapred-site.xml、yarn-site.xml和hadoop-env.sh这五个就够了。core-site.xml指定 NameNode 的地址和临时目录configuration property namefs.defaultFS/name valuehdfs://hadoop-master:9000/value /property property namehadoop.tmp.dir/name value/usr/local/hadoop/tmp/value /property /configurationhdfs-site.xml设置副本数和 NameNode/DataNode 的数据存储路径configuration property namedfs.replication/name value1/value /property property namedfs.namenode.name.dir/name value/usr/local/hadoop/namenode/value /property property namedfs.datanode.data.dir/name value/usr/local/hadoop/datanode/value /property /configuration伪分布式副本数只能是 1因为数据节点只有一台。如果设置成 3DataNode 虽然只有一台也照样跑但会把副本数不够的错误写在日志里容易误导排查方向。mapred-site.xml指定 MapReduce 用 YARN 调度configuration property namemapreduce.framework.name/name valueyarn/value /property /configurationyarn-site.xml配置 YARN 的资源管理和 Shuffle 服务configuration property nameyarn.nodemanager.aux-services/name valuemapreduce_shuffle/value /property /configurationyarn.nodemanager.aux-services这个参数新手经常漏掉。没有它MapReduce 任务提交后 Shuffle 阶段会直接失败而且报错并不直观需要去 NodeManager 日志里翻半天。2.3 初始化、启动和验证流程启动前先格式化 NameNode。很多人对这一步有误解格式化相当于给 HDFS 创建新的存储目录和元数据是初始化动作不是启动动作hdfs namenode -format注意格式化只能在第一次启动前执行一次。之后如果总是反复格式化会清空元数据导致已有数据目录的集群无法启动。生产环境上切记。启动start-dfs.sh start-yarn.sh用jps验证进程状态NameNodeDataNodeSecondaryNameNodeResourceManagerNodeManager看到这五个进程就说明伪分布式起来了。然后访问 Web UIHDFS 管理界面http://hadoop-master:9870/Hadoop 3.xYARN 资源管理界面http://hadoop-master:8088/验证 HDFS 基本读写hdfs dfs -mkdir /test hdfs dfs -put /etc/hosts /test/ hdfs dfs -ls /test跑一个标准测试任务确认 YARN 完全可用hadoop jar /usr/local/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.6.jar pi 2 1000pi 是 Hadoop 自带的 Monte Carlo 算圆周率例子如果 task 能跑完并输出了Estimated value of Pi相关结果说明 MapReduce 链路是通的。2.4 伪分布式为什么叫伪因为它的 datanode 只在一台机器上。你在dfs.replication1下能正常读写但如果你在 HDFS Web UI 里看到Live Nodes只有 1 个这个就是要练的脑中对集群的实际拓扑有一个清晰认识。伪分布式很多异常行为到了真实集群会完全不一样比如 SecondaryNameNode 合并 fsimage 的时机、block 摆放策略、节点下线时的数据迁移这些在单机上都观察不到明显效果。但是伪分布式足以帮助你理解 HDFS 的目录结构、文件读写流程、日志排查方法、YARN 的 Application 生命周期。这些基础打牢了后面学 HA、学调优都不会太痛苦。3. 从伪分布式到完全分布式集群改造到底改了哪些东西伪分布式跑通之后很多课程设计或者面试准备要求理解完全分布式。这一步不需要引入特别多的新知识更多是把伪分布式的配置分布式化。3.1 集群规划角色分配先写在一张表里如果做三节点的完全分布式集群常见规划是三台机器一台主节点跑 NameNode ResourceManager外加 SecondaryNameNode两台从节点跑 DataNode NodeManager。建议先画一张表主机名IP角色hadoop-master192.168.1.10NameNode、ResourceManager、SecondaryNameNodehadoop-node1192.168.1.11DataNode、NodeManagerhadoop-node2192.168.1.12DataNode、NodeManager这个规划不是死的生产环境大数据集群的 NameNode 和 ResourceManager 都会拆分到不同物理机避免单点故障和资源竞争。学习阶段先合并跑通再说。3.2 集群版配置文件的核心差异和伪分布式相比集群版主要改这几项core-site.xml的fs.defaultFS不变还是指向主节点的主机名。dfs.replication改成 2 或者 3。如果三节点实际数据只有一份副本时副本数设成 2 比较合理因为目标是有冗余而设 3 会触发第三副本拷贝但又只有两台 DataNode 能放会报错或者警告。hdfs-site.xml里dfs.namenode.name.dir和dfs.datanode.data.dir还是原来的路径设置但要注意 DataNode 的目录在每台从节点上都要存在而且权限属于 hadoop 用户。yarn-site.xml增加 ResourceManager 的地址property nameyarn.resourcemanager.hostname/name valuehadoop-master/value /propertyetc/hadoop/workersHadoop 3.x 版本2.x 叫 slaves文件里把从节点主机名写进去每个一行hadoop-node1 hadoop-node2这就是 Hadoop 3.x 和 2.x 一个容易踩的差异点文件名变了启动脚本读取的逻辑也变了。如果照老教程去改 slavesHadoop 3.x 根本不认DataNode 不会在从节点启动。3.3 从自己免自己到主节点免密到从节点伪分布式只要ssh localhost免密即可完全分布式则要求主节点能以 hadoop 用户免密 SSH 登录到所有从节点。这个非常关键因为start-dfs.sh脚本会在你运行它的机器上通过 SSH 发指令去从节点启动进程。ssh-copy-id hadoophadoop-node1 ssh-copy-id hadoophadoop-node2然后验证ssh hadoop-node1 jps ssh hadoop-node2 jps注意主节点到主节点自己也要免密如果初始安装时没有配start-dfs.sh同样会因为要连本机而卡住。这个顺序大部分人不会搞错但偶尔有同学配了从节点没配自己排障时容易忽略。完全分布式启动流程和伪分布式一样先格式化 NameNode 再start-dfs.shstart-yarn.sh但格式化只需要在主节点执行DataNode 不需要格式化存储目录。如果从节点/usr/local/hadoop/tmp目录已经存在旧数据启动时可能会有版本冲突报错稳妥做法是在每台机器上把 Hadoop 目录下的 tmp 清掉再统一启动。4. 排障实录那些我在 Hadoop 环境搭建中踩过的坑4.1 DataNode 进程起不来默认从 Web UI 之外的日志找线索DataNode 进程起不来的问题在大部分初学环境里出现的频率最高。当你执行start-dfs.sh后jps一看主节点只有 NameNode 和 SecondaryNameNodeDataNode 没起来。直接看日志日志位置在/usr/local/hadoop/logs/下文件名形如hadoop-hadoop-datanode-hadoop-master.log。很多教程喜欢让你去看hadoop-hadoop-datanode-*.log里的报错但真正有效的信息通常在.log最底部几行而且常见错误就那么几类。最常见原因dfs.datanode.data.dir指向的目录不存在或者目录属主不是 hadoop 用户。格式化 NameNode 时只会初始化 NameNode 的存储目录DataNode 的数据目录必须自己手动创建并授权mkdir -p /usr/local/hadoop/datanode chown -R hadoop:hadoop /usr/local/hadoop第二个常见原因多次格式化 NameNode 导致VERSION文件中的 namespaceID 不一致。DataNode 启动时会校验自己存储目录里的 namespaceID 和 NameNode 报告的是否一致不一致就会拒绝连接。解决办法清空所有机器的 tmp、namenode、datanode 目录然后只格式化一次 NameNode 再启动。还有一类比较隐蔽Core-site 里hadoop.tmp.dir配置了自定义路径但这个路径不存在或者属主不对也会导致 NameNode 启动报错。建议把 tmp 目录、namenode 目录、datanode 目录统一放在 Hadoop 安装目录下排障时路径清晰很多。4.2 端口被占和 JVM 堆内存不足两个容易被误判的报错Hadoop 的各个守护进程都绑定固定端口其中 9000RPC和 9870HTTP被占是最常见的。比如你之前启动过一次集群但没有正常 stop或者用了别的服务占用 9870。排查方式ss -tlnp | grep 9000 ss -tlnp | grep 9870如果确实是上一个 Hadoop 进程没死干净用jps看进程 ID直接kill。如果反复出现这种问题可以查一下是否start-dfs.sh执行不完整导致 NameNode 僵死。JVM 堆内存不足的报错也经常被误判为配置文件写错。默认情况下 NameNode 会分配 1GB 堆DataNode 和 ResourceManager 各自有默认值在一台内存只有 2GB 的虚拟机里三四个 Hadoop 守护进程一起启动可能直接 OOM。解决办法一是加大虚拟机内存到 4GB 以上二是修改hadoop-env.sh里面的HADOOP_NAMENODE_OPTS等参数把 Xmx 调低一点适配机器export HADOOP_NAMENODE_OPTS-Xmx512m $HADOOP_NAMENODE_OPTS export HADOOP_DATANODE_OPTS-Xmx256m $HADOOP_DATANODE_OPTS调优的原则是宁可小也要能跑先用最小内存把流程跑通等需要压测再逐步加大。4.3 distcp 参数用错导致拷贝任务一直失败有一个比基础排障更进阶的场景集群之间的数据拷贝。这个操作在课程设计里经常遇到面试也可能被提问。hadoop distcp是 Hadoop 自带的跨集群数据复制工具它在底层的实现是启动一个 MapReduce 作业逐个目录去 copy listing。我遇到过用 distcp 拷贝大目录时 yarn 的 Application 一直停留在 RUNNING最后超时的情况。原因一个是 ResourceManager 能分配的内存太小Map 任务分片太多另一个是源目标和目标集群的 HDFS 版本不兼容。版本不一致时-update、-delete这些增量同步参数就不能乱用要先单独拷贝一个小目录验证。常用参数组合hadoop distcp -update -delete -m 10 hdfs://cluster1:9000/data hdfs://cluster2:9000/backup-m指定 map 数默认是 20小集群上用 10 或者更少比较稳。-update只拷贝新变更的文件-delete删除目标端多余文件。这个命令是面试里关于 Hadoop 运维热点中的热点值得把参数过一遍。4.4 格式化两次后集群数据不见了这个问题每天都在发生格式化两次的问题在课程答辩前毁掉过很多人的演示现场。你以为格式化是初始化所以每次都执行结果发现之前往 HDFS 里传的数据全没了。原因很简单format 操作会清空 NameNode 的元数据也就意味着旧数据全部失联。如果 datanode 目录里还有之前的 block 文件新启动时 namespaceID 对不上DataNode 会拒绝工作。所以我的建议是把格式化从你的操作习惯里拿掉。只有两种情况允许格式化——第一次初始化集群或者你完全不在意旧数据要重建集群。日常改配置、重启集群只需要stop-all.sh再start-all.sh完全不需要格式化。如果要在实验环境反复调试可以把整个/usr/local/hadoop下的 tmp、logs、namenode、datanode 目录一起删掉重新建相当于一次干净的重建比反复格式化逻辑更清晰。5. 进阶Hadoop HA 高可用搭建和 ZooKeeper 整合实战要点5.1 从单 NameNode 到 HA为什么不能没有 ZooKeeper单 NameNode 是典型单点故障这点在面试里一定会被问到。如果 NameNode 挂了整个 HDFS 就不可用因为所有文件的元数据索引都在它这里。生产环境通过 HA 机制解决两台 NameNode一台 Active一台 StandbyActive 负责处理客户端请求Standby 随时准备接管。ZooKeeper 在这里面的角色是裁判。它负责监控 Active NameNode 的心跳状态一旦检测到 Active 挂掉就通知 Standby 切换成 Active。同时通过 ZKFCZooKeeper Failover Controller来执行故障转移两个 ZKFC 进程分别和本机的 NameNode 绑定定期向 ZooKeeper 写入心跳信息。如果你只想跑通 HA 而不深入原理最省力的方式是直接部署 ZooKeeper 3.7.x 或 3.8.x然后启动三个 ZooKeeper 节点组成一个 ensemble。注意 ZooKeeper 本身奇数台集群才能保证选举 quorum通常 3 台最小化部署。5.2 基于 QJM 的 HA 最小配置清单HA 的共享存储方案有 QJMQuorum Journal Manager和 NFS 两种QJM 是现在的主流。QJM 本质是让 Active NameNode 把 edits log 写入一组 JournalNode通常是 3 台只要多数派写入成功就算成功Standby NameNode 从 JournalNode 读取 edits log 保持元数据同步。HDFS 层面的 HA 最小配置大致包括property namedfs.nameservices/name valuemycluster/value /property property namedfs.ha.namenodes.mycluster/name valuenn1,nn2/value /property property namedfs.namenode.rpc-address.mycluster.nn1/name valuehadoop-master1:9000/value /property property namedfs.namenode.rpc-address.mycluster.nn2/name valuehadoop-master2:9000/value /property property namedfs.namenode.http-address.mycluster.nn1/name valuehadoop-master1:9870/value /property property namedfs.namenode.http-address.mycluster.nn2/name valuehadoop-master2:9870/value /property property namedfs.namenode.shared.edits.dir/name valueqjournal://hadoop-node1:8485;hadoop-node2:8485;hadoop-node3:8485/mycluster/value /property property namedfs.client.failover.proxy.provider.mycluster/name valueorg.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider/value /property property namedfs.ha.automatic-failover.enabled/name valuetrue/value /property /configuration注意fs.defaultFS要改成hdfs://mycluster这样客户端才知道通过 nameservice 去连接而不是直连某个具体 NameNode。启动顺序也很有讲究先启动 ZooKeeper再启动 JournalNode然后格式化 ZooKeeper 和 NameNode最后启动 ZKFC。5.3 防脑裂fencing 机制其实是保命设计HA 过程中最怕的一个场景叫做双主脑裂。就是网络抖动时旧 Active NameNode 其实还活着但 ZKFC 误以为它挂了于是让新的 Standby 升成 Active。这时候两个 NameNode 同时写 edits log就会把元数据空间搞乱。所以生产配置里一定会做 fencing常见的是sshfence方式当需要切换时先 SSH 到旧 Active 所在机器上执行 fuser 把对应 NameNode 进程杀掉确保它彻底退出然后新主才真正接管。配置项property namedfs.ha.fencing.methods/name valuesshfence/value /property property namedfs.ha.fencing.ssh.connect-timeout/name value30000/value /property没有 fencing 的 HA 是不完整的。如果面试官追问为什么 HA 还要杀进程答案就是防止两个 NameNode 同时写元数据。掌握到这层就不只是会复制配置而是真正理解了 HA 的设计思路。6. 集群健康检查清单启动完不等于万事大吉6.1 HDFS 和 YARN 的双层体检方法启动三个节点的集群后jps看到进程齐了还不算成功。我习惯用一套固定列表做验证第一步查 HDFS 安全模式状态hdfs dfsadmin -safemode get如果显示 Safe mode is ON说明元数据还在加载或者 block 缺失可能是非正常关机导致。正常退出集群要用stop-dfs.sh直接 kill 进程的话重启后常会进入安全模式可以用hdfs dfsadmin -safemode leave但如果每次重启都自动进入安全模式说明集群内部有问题别急着执行 leave先查 block 健康度。第二步用fsck检查文件系统完整性hdfs fsck / -files -blocks如果出现CORRUPT字样说明有 block 副本丢失可能是 DataNode 挂过或者磁盘损坏。学习环境里直接删掉损坏文件即可但了解这个检查链路是正经集群管理的入门。第三步用yarn node -list查看 NodeManager 注册情况如果某台 worker 没出现在列表里说明它和 ResourceManager 的心跳有问题优先检查 yarn-site.xml 配置和网络。6.2 从环境搭建到后续学习路线的自然衔接环境搭好之后很多人就开始迷茫接下来学什么Hadoop 本身的知识点主要就三块HDFS、MapReduce、YARN。建议顺着这个路径走先深入 HDFS 的读写流程。在伪分布式环境里执行hdfs dfs -put然后观察 NameNode 日志和 Web UI 的 block 分布理解记录写入流程。然后试试用 Java API 写一个简单的客户端连接 HDFS 创建目录、上传文件、下载文件这是面试里常考的基础。MapReduce 部分用官方示例跑完 WordCount 和 pi 之后自己写一个简单的 Mapper 和 Reducer跑完整流程重点观察 Shuffle 阶段的日志。YARN 部分可以试着提交一个作业到不同队列观察资源分配。对于准备面大数据的同学环境搭建本身不是重点但它是你验证概念的基础设施。比如别人背HDFS 写入流程有四个步骤你在自己环境上跑一遍、看一下 NameNode 的 RPC 日志记忆会牢固得多。课程设计方面如果学校题目给的是 Hadoop 相关课题不管题目是简单的 word count 还是稍微复杂一点的分布式排序、倒排索引把伪分布式跑通、能够提交 MapReduce 任务基本就能覆盖演示需求。若题目提升了难度涉及资源调度或者高可用再把 HA 配置补上即可。最后我分享一个自己的习惯把整套安装命令、配置文件、启动顺序写成一份纯文本脚本放到项目的 README 或者笔记里。这样无论换机器、重建虚拟机还是写实验报告都能在半个小时内把环境从零恢复到可用状态。这不是偷懒而是把繁琐的环境搭建过程变成可以重复执行的标准操作效率会成倍提高。
返回列表