ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Hadoop 2.6.5实战指南:伪分布式搭建、HA高可用与distcp迁移

Hadoop 2.6.5实战指南:伪分布式搭建、HA高可用与distcp迁移 简介Hadoop 2.6.5 发行包是一份面向大数据平台搭建者的完整安装资源用于在 Linux 环境下部署分布式存储与计算框架。压缩包共有 900 个文件大小约 175.09MB其中 477 个 jar 文件提供核心库与依赖129 个 class 文件保存编译后的执行类51 个 xml 为配置模板50 个 sh 为管理脚本另含 Web 监控页面所需的 html、css、js 等内容结构清晰易于检索。目前已有 1267 人学习下载常被用于单机伪分布式部署或小型集群实验。解压即可获得完整目录借助自带配置与脚本可以快速启动服务并通过示例程序验证 HDFS 文件存储和 MapReduce 并行计算流程同时也能参照包内组件梳理资源调度与容错机制适合自学、课程设计及生产环境预研阶段使用。整份安装包既有开箱即用的可执行内容也保留了便于二次修改的配置细节能支撑从简单入门到集群调优的完整学习链条。1. 为什么还在下 hadoop-2.6.5.tar.gz老版本的真实价值如果你在 2024 年还要搜 hadoop-2.6.5.tar.gz原因大概率不是追新而是被课程设计、老集群维护或者面试官卡住了。Hadoop 2.6.5 是 2016 年发布的维护版本后面 2.7、2.8 甚至 3.x 都出了很久但国内大量教材、实验手册、企业内部老任务还是指定这个版本很多基于 Hadoop 的课程设计和中间件整合方案也是在这套代码上调通的。对现在的从业者来说它的价值不在于性能多强而在于生态兼容性最稳定Hive、HBase、Spark 的某些老版本配套方案都能对上网上能直接抄的作业也最多。这篇文章我会把它从下载、解压、伪分布式、完全分布式 HA 到 distcp 迁移完整拆一遍适合正在做课程设计、准备 Hadoop 面试、或者维护老集群的人照着复现。2. 下载与前置检查JDK 兼容性、SSH 免密与目录规划2.1 版本选型为什么 2.6.5 而不是 2.7先回答一个老被问的问题既然 2.6.5 是老版本为什么不用 2.7 或者 3.x常见情况是你所在的课程设计任务书或公司内部文档里写死了版本配套的 MapReduce 样例、Hive 安装包、Zookeeper 整合方案都是按这个版本调好的。用高版本会出现适配问题比如 MRv1 时代的 API 在新版里被标记废弃甚至移除老教程里的命令在 3.x 里不少已经改了路径。2.6.5 的另一个优势是它仍然支持hadoop-daemon.sh这种脚本很多教材里教的启动方式还能直接照用新版本把这些内部脚本挪了位置照着老教程敲命令容易翻车。选择 2.6.5 还有个实际原因它配套的 Zookeeper 3.4.x、JDK 8 都是同一时期的产品版本匹配问题少。我见过有人拿 Hadoop 3.3 去配旧版 Zookeeper结果zkfc的 watcher 机制不兼容HA 状态来回切换查了一下午才发现是版本组合的问题。这类玄学问题在老版本组合里反而少很多因为社区踩过的坑都沉淀成教程了。2.2 JDK 版本匹配先确认环境再解压下载完hadoop-2.6.5.tar.gz别急着解压先检查 JDK。这个版本官方推荐的 Java 7实际生产里用 Java 8 最常见也是兼容性最好的选择。千万不要装 JDK 11 以上启动时经常报UnsupportedClassVersionError或者反射相关的异常NameNode 进程起来十几秒就自动消失日志里看不到明确错误排查起来很痛苦。# 先确认 JDK 版本Hadoop 2.6.5 只建议用 JDK 7 或 8 java -version # 如果 JDK 版本没问题再解压到固定目录 tar -zxvf hadoop-2.6.5.tar.gz -C /opt/ mv /opt/hadoop-2.6.5 /opt/hadoop解压后需要把HADOOP_HOME写进环境变量这是网上教程里写烂了但很多人还是漏掉的步骤。漏掉之后的表现是命令行敲hadoop报 command not found或者能跑hdfs但跑不了yarn因为 PATH 没指全。我一般还会顺手把JAVA_HOME也写进去避免后面脚本里找不到java路径。# 编辑 /etc/profile追加以下内容 export JAVA_HOME/usr/lib/jvm/java-8-openjdk-amd64 export HADOOP_HOME/opt/hadoop export PATH$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin# 使环境变量生效并验证 source /etc/profile hadoop versionhadoop version正常输出 “Hadoop 2.6.5” 才说明基础环境没问题。这一步我建议当成强制检查项很多教程跳过了导致后边配置全对也起不来服务。另外提醒一下不要把解压目录放在/root下或者权限为 777 的共享目录里Hadoop 对目录权限敏感dfs.datanode.data.dir指向的路径如果父目录权限过宽DataNode 启动时会报权限相关的安全错误。2.3 用户、SSH 免密与目录规划装之前最容易被忽略的三件事第一件事是创建专用用户。虽然单机伪分布式可以用 root 跑但生产集群和多节点环境里 root 会引发一堆权限和隔离问题比如 HDFS 写文件时 owner 全是 root后续普通用户提交作业会报权限不足。我一般会建一个hadoop用户所有操作都在这个用户下执行。# 创建 hadoop 用户并设置密码 useradd hadoop passwd hadoop # 把 /opt/hadoop 属主改成 hadoop chown -R hadoop:hadoop /opt/hadoop第二件事是配置 SSH 免密。Hadoop 集群启动脚本会通过 SSH 到每台机器上拉起进程如果在虚拟机上做多节点实验这一步不做的话start-dfs.sh会在每台机器上停下来等着输密码非常浪费时间。单机伪分布式建议也配好后面加节点时不用返工。# 切换到 hadoop 用户执行 ssh-keygen -t rsa -P -f ~/.ssh/id_rsa # 单机模式直接把公钥加入 authorized_keys cat ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys # 验证免密是否生效 ssh localhost echo ok第三步是规划目录。Hadoop 运行时要写三块数据NameNode 元数据、DataNode 数据块、临时文件。默认情况下它们都落在/tmp下但/tmp会被系统定时清理重启一次机器集群就“失忆”了。我习惯统一建目录mkdir -p /opt/hadoop/data/namenode mkdir -p /opt/hadoop/data/datanode mkdir -p /opt/hadoop/data/journalnode mkdir -p /opt/hadoop/tmp这三块路径在后面配置文件里要反复用到先在命令行里建好能少踩一个“目录不存在导致格式化失败”的坑。如果是虚拟机里装 Hadoop还要注意/etc/hosts的配置不要只写localhost要把主机名和 IP 一一对应写清楚否则后面的 HA 配置里节点之间互相找不到对方。3. hadoop 伪分布式搭建单机跑通 WordCount 的完整流程3.1 四份配置文件的参数逐项说明伪分布式是入门 Hadoop 的第一道坎也是课程设计里最常见的部署形式。核心就是改四份 XML 配置文件。注意$HADOOP_HOME/etc/hadoop/下默认没有mapred-site.xml只有mapred-site.xml.template很多人在这里卡住直接复制模板改名就行。先看core-site.xml它决定 HDFS 的访问地址和临时目录configuration property namefs.defaultFS/name valuehdfs://localhost:9000/value /property property namehadoop.tmp.dir/name value/opt/hadoop/tmp/value /property /configurationfs.defaultFS是文件系统的默认入口地址9000 是 NameNode 的 RPC 通信端口。伪分布式所以写localhost完全分布式时要改成逻辑名字服务名比如hdfs://mycluster。hadoop.tmp.dir是 NameNode 和 DataNode 存放元数据与数据块的根目录默认值是/tmp/hadoop-${user}前面说过会被系统清理必须改掉。接着是hdfs-site.xml这里主要设置数据副本数和目录位置configuration property namedfs.replication/name value1/value /property property namedfs.namenode.name.dir/name valuefile:///opt/hadoop/data/namenode/value /property property namedfs.datanode.data.dir/name valuefile:///opt/hadoop/data/datanode/value /property /configurationdfs.replication在伪分布式下必须设为 1因为只有一台 DataNode默认值 3 会导致数据块写入时报NotEnoughReplicasException。dfs.namenode.name.dir和dfs.datanode.data.dir分别指定元数据和数据块的落盘路径指向 2.3 节建好的目录。这里要提醒的是用file:///前缀不是hdfs://。然后是yarn-site.xml负责资源调度和任务执行configuration property nameyarn.nodemanager.aux-service/name valuemapreduce_shuffle/value /property property nameyarn.nodemanager.resource.memory-mb/name value2048/value /property /configurationyarn.nodemanager.aux-service是 NodeManager 给 MapReduce 提供的辅助服务值固定写mapreduce_shuffle这是网上最容易抄错的一项少一个字符整个作业都跑不起来。resource.memory-mb是单台机器可分配给容器的内存上限虚拟机里如果机器总内存只有 2G这里就不要调大否则 NodeManager 直接挂掉。最后是mapred-site.xml指定计算框架为 YARNconfiguration property namemapreduce.framework.name/name valueyarn/value /property /configuration这里的逻辑是Hadoop 1.x 用自带的 JobTracker 跑作业2.x 之后统一走 YARN这一步不写的话作业会跑在本地模式虽然不报错但日志里完全看不到 MapReduce 的进度新手容易误以为任务卡死了。3.2 格式化、启动与 jps 验证配置写完后第一次启动 HDFS 之前必须先格式化 NameNode这相当于给文件系统建立初始的元数据目录结构。不格式化直接启动的话NameNode 根本起不来。格式化命令如下# 在 hadoop 用户下执行 hdfs namenode -format看到输出里有SHUTDOWN_MSG并且没有Exception就算成功。格式化成功后会生成/opt/hadoop/data/namenode/current/VERSION文件里面有clusterID这个 ID 后面排错要用先留着别删。格式化完成后依次启动 HDFS 和 YARN# 启动 HDFS 守护进程 start-dfs.sh # 启动 YARN 守护进程 start-yarn.sh启动过程中会输出每个节点的进程启动日志看有没有报错回显。启动完用jps检查进程状态jps伪分布式正常应该看到五个进程NameNode、DataNode、SecondaryNameNode、ResourceManager、NodeManager。少任何一个都说明启动有问题。最常见的遗漏是 SecondaryNameNode 没有原因是core-site.xml里没配dfs.namenode.secondary.http-address但这个在 2.6.5 下有默认值所以正常启动都会带。启动完还可以在浏览器里确认一下访问http://localhost:50070能看到 NameNode 的界面DataNode 节点列表里应该有且只有一个节点状态为 Live。如果页面打不开优先检查防火墙很多虚拟机镜像默认开着防火墙50070 端口被挡在外面。3.3 用 hadoop-mapreduce-examples 跑第一个 WordCount进程都起来之后跑一个内置的 WordCount 来验证整个链路。这一步是课程设计最常要求的验收项也是后面所有 MapReduce 作业的模板。先建输入目录并上传测试文件# 在 HDFS 上创建 input 目录 hdfs dfs -mkdir -p /user/hadoop/input # 把本地的配置文件上传为输入数据 hdfs dfs -put /opt/hadoop/etc/hadoop/core-site.xml /user/hadoop/input/ # 查看确认文件已上传 hdfs dfs -ls /user/hadoop/input上传完成后提交 WordCount 作业hadoop jar /opt/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.5.jar \ wordcount /user/hadoop/input /user/hadoop/output这条命令的构成是hadoop jar指定要跑的 jar 包文件名里的2.6.5要和你的版本对上wordcount是 jar 包里的主类名后面两个路径分别是输入目录和输出目录。注意输出目录必须不存在如果已经是第二次跑了得先把旧的输出删掉否则报FileAlreadyExistsException。作业跑完会说Successfully completed然后查看结果hdfs dfs -cat /user/hadoop/output/part-r-00000能看到类似hadoop 4这样的词频统计结果说明整个 Hadoop 从存储到计算的链路都通了。这一步别只跑通就算完可以把core-site.xml换成一篇自己的长文本看一看不同大小的输入跟运行时长之间的关系对理解 MapReduce 的拆解逻辑很有帮助面试也常问这个。3.4 伪分布式到完全分布式的差别同样是 2.6.5配置思路完全两样伪分布式跑通后很多人直接把这几份配置复制到三台机器上就以为能组成集群结果 DataNode 全起不来或者起来了但互相不认。差别在于伪分布式依赖本地文件系统做元数据存储而完全分布式需要配置名字服务、HA 共享存储和 Zookeeper 协调是另一套配置维度。第 4 章会完整展开。有个血泪提醒伪分布式阶段不要在配置里预先开启 HA 相关参数比如dfs.ha.automatic-failover.enabled。有些教程为了少改一次配置从一开始就把 HA 的项写进去结果单机环境下 ZKFC 找不到 ZookeeperNameNode 反复重启。伪分布式和 HA 是两套模式先单机验证完再切换别一步到位。4. 集群搭建与 Zookeeper 整合NameNode HA 自动故障转移实战4.1 HA 为什么需要 ZookeeperQJM 共享存储和 fence 原理2.6.5 的 NameNode HA 用的是 QJMQuorum Journal Manager方案两个 NameNode 节点通过一组 JournalNode 共享编辑日志Active 节点把元数据操作写入 JournalNodeStandby 节点读取并持续同步保证内存中的元数据始终跟得上。如果只有一台 NameNode元数据全在本地磁盘机器挂了数据就断了有了 QJMActive 挂了之后 Standby 可以直接接管。那 Zookeeper 在这里扮演什么角色它管的是自动故障转移。ZKFCZookeeper Failover Controller进程会在 Zookeeper 里创建临时节点Active 的 NameNode 持有锁Standby 的监听锁的状态。Active 节点挂掉后临时节点超时消失ZKFC 收到通知触发切换。这个机制叫自动故障转移没有它就只能手动执行hdfs haadmin -failover生产环境里半夜出故障根本等不到人手动切。这里常被面试官追问的是脑裂问题如果 Active 节点没有真正死掉只是网络分区了Standby 会以为自己可以接管结果集群里出现两个 Active。Hadoop 的解法是 fencing隔离在切换前用配置好的dfs.ha.fencing.methods把老 Active 强制杀掉或 SSH 进去执行kill -9。这也是为什么在 4.3 节配置里要指定sshfence和对应的私钥fence 不成功ZKFC 会拒绝切换。4.2 节点规划与端口分配三台虚拟机怎么摆活我这里按最常见的三节点方案来规划这也是课程设计和中小团队用的标准布局。三台机器分别叫n01、n02、n03每台都装 Zookeeper 和 JournalNode两个 NameNode 分布在不同的机器上三个 DataNode 每台一个。具体分配如下表节点NameNodeDataNodeJournalNodeZookeeperZKFCn01Active是是是是n02Standby是是是是n03无是是是无端口规划也建议先列出来写进文档里排查问题时对照着防火墙策略检查。NameNode 的 RPC 端口配 9000HTTP 界面端口 50070JournalNode 的 RPC 端口固定 8485Zookeeper 的客户端端口默认 2181。每个节点之间都要能互相访问这些端口虚拟机环境下我习惯先把三台机器的防火墙全关掉或者精确放行然后统一改/etc/hosts192.168.56.101 n01 192.168.56.102 n02 192.168.56.103 n03这个 hosts 文件三台机器要完全一致顺序不要乱。很多人主机名用了带横线的名字或者大写字母导致解析出来的 hostname 和/etc/hosts对不上DataNode 注册不到 NameNode 上网页上看节点数始终为 0这种问题最难查因为日志里没有明显报错只是进程在但集群不健康。4.3 hdfs-site.xml 的 HA 相关配置完整拆解完全分布式模式下hdfs-site.xml的配置量和伪分布式完全不同。建议直接逐项替换成下面这份花十分钟把每个参数看懂再动手这里放的是我自己用的最小可用配置configuration 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 valuen01:9000/value /property property namedfs.namenode.rpc-address.mycluster.nn2/name valuen02:9000/value /property property namedfs.namenode.http-address.mycluster.nn1/name valuen01:50070/value /property property namedfs.namenode.http-address.mycluster.nn2/name valuen02:50070/value /property property namedfs.namenode.shared.edits.dir/name valueqjournal://n01:8485;n02:8485;n03: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 property namedfs.ha.fencing.methods/name valuesshfence/value /property property namedfs.ha.fencing.ssh.private-key-files/name value/home/hadoop/.ssh/id_rsa/value /property property namedfs.journalnode.edits.dir/name value/opt/hadoop/data/journalnode/value /property property namedfs.replication/name value2/value /property /configurationdfs.nameservices是这个 HA 集群的逻辑名字后面所有跟集群相关的配置都以它为前缀三台机器上这个名字必须一致。dfs.ha.namenodes.mycluster给两个 NameNode 起了别名nn1和nn2下面的 RPC 和 HTTP 地址都挂在它们下面。dfs.namenode.shared.edits.dir指定三个 JournalNode 的地址这个值的格式是qjournal://host1:8485;host2:8485;host3:8485/集群名分号隔开最后一个mycluster是 namespace 名称跟dfs.nameservices对应。dfs.client.failover.proxy.provider的作用是让客户端拿到 Active NameNode 的地址否则作业提交后不知道该找哪台机器。dfs.ha.fencing.methods配sshfence表示用 SSH 方式隔离旧的 Active 节点私钥路径必须能被启动 hadoop 的用户读取。配合这份配置core-site.xml也要调整文件名解析不再指向localhost而是指向逻辑集群configuration property namefs.defaultFS/name valuehdfs://mycluster/value /property property nameha.zookeeper.quorum/name valuen01:2181,n02:2181,n03:2181/value /property property namehadoop.tmp.dir/name value/opt/hadoop/tmp/value /property /configurationha.zookeeper.quorum是 Zookeeper 集群的地址列表ZKFC 和 NameNode 都要靠它来做分布式协调。这里建议用 Zookeeper 3.4.x 系列我用的 3.4.14 和 2.6.5 配合得很稳定3.5 及以上版本的配置格式有变化旧版 ZKFC 读起来偶尔会出兼容性问题。4.4 ZKFC 启动顺序与 Active/Standby 状态验证HA 集群的启动顺序和伪分布式完全不同顺序乱了会报各种莫名其妙的错误。很多人在这一步翻车原因是直接在 n01 上执行start-dfs.sh结果 JournalNode 没起NameNode 找不到共享目录直接挂掉。我总结的可靠顺序如下。第一步先在三台机器上启动 Zookeeper确认在三台上执行zkServer.sh status能看到两个 follower 和一个 leader# 每台机器分别执行 zkServer.sh start zkServer.sh status第二步三台机器都启动 JournalNodehadoop-daemon.sh start journalnode检查方式是用jps看进程三台上都应该有JournalNode。确认都起来之后再格式化。格式化必须在 n01 上做并且dfs.namenode.name.dir指向的目录必须是空的否则会提示目录已存在并拒绝执行。接着把元数据同步到 n02# 在 n01 上执行格式化 hdfs namenode -format # 在 n02 上执行让它从 n01 拉取元数据 hdfs namenode -bootstrapStandbybootstrapStandby的作用是把 n01 的 NameNode 元数据复制到 n02 的本地目录让两个 NameNode 从相同的状态开始工作。这个命令只会在第一次搭建时执行之后 n02 会通过 JournalNode 持续同步。第三步初始化 ZKFC 的元数据。在任意一台机器上执行hdfs zkfc -formatZK这条命令会在 Zookeeper 里创建与 HA 相关的 znode相当于给自动故障转移搭好舞台。执行完后可以到 Zookeeper 里确认一下ls /hadoop-ha/mycluster是否有内容。第四步回到 n01 上正常拉起整个 HDFSstart-dfs.sh这时jps观察理想状态是三台机器各有一个JournalNode和一个ZKFCn01 和 n02 各有NameNode三台都有DataNode。然后查两个 NameNode 的状态hdfs haadmin -getAllServiceState正常输出是n01:active和n02:standby说明 HA 已经就绪。这个验证建议做两次第一次查状态第二次直接模拟故障。# 在 n01 上找到 NameNode 的 PID然后杀掉 jps kill -9 NameNode进程PID # 等 20 秒让 Zookeeper 检测到超时 hdfs haadmin -getAllServiceState20 秒后 n02 会从 standby 变成 active这就完成了一次真实的故障转移。注意kill -9模拟的是进程突然死亡的场景能验证自动转移如果只是手动停掉服务ZKFC 会认为这是正常下线不会触发切换。这项操作也可以作为课程设计的验收演示比单纯截图配置页面有说服力得多。5. 常见问题排查2.6.5 启动失败的高频原因与解决5.1 格式化后 DataNode 起不来clusterID 不一致现象是start-dfs.sh执行完jps显示 DataNode 进程存在但 HDFS 网页上 Datanodes 列表为空日志里反复出现Incompatible clusterIDs或者datanode with the same address already exists。原因是 NameNode 格式化时生成了一个clusterID而 DataNode 的current/VERSION文件里保存的是旧 ID。常见场景是hdfs namenode -format执行了两次或者把别的机器的数据目录拷了过来。解决方法是把 DataNode 数据目录里的current目录删掉再重启# 停掉 HDFS 后执行 rm -rf /opt/hadoop/data/datanode/current # 然后重新启动 hdfs datanode -format start-dfs.sh这是我踩得最多的坑格式化命令本身没有任何提示风险但反复格式化就会让元数据和数据块版本错位。现在的习惯是每次namenode -format之前都顺手把所有 data 目录清空一遍保证集群里的节点拿的是同一套 ID。5.2 JDK 版本过高导致 NameNode 直接退出现象是start-dfs.sh执行时 NameNode 日志打出UnsupportedClassVersionError或IllegalArgumentException然后进程消失。有些环境里报错更隐蔽只是jps里根本没有 NameNode。原因是 Hadoop 2.6.5 的hadoop-daemon.sh会调用java命令如果JAVA_HOME指向 JDK 9 以上字节码版本对不上。解决方式是把JAVA_HOME明确指向 JDK 8并且检查系统默认的java和javac版本一致# 在 /etc/profile 里强制指定 export JAVA_HOME/usr/lib/jvm/java-8-openjdk-amd64 export PATH$JAVA_HOME/bin:$PATH检查的时候有个细节java -version输出的可能是 JRE 版本但 Hadoop 的补丁工具比如hdfs命令需要 JDK所以一定要确认javac -version也是 1.8。如果系统里装了多个 JDK可以用update-alternatives --config java切到 8。这类环境问题最磨人日志里错误信息经常不完整我一般先把环境变量输出一遍确认无误再谈别的。5.3 SSH 免密没生效start-dfs.sh 卡在密码输入现象是执行start-dfs.sh时所有输出组件名之后就不动了光标停在提示符前像是在等输入或者提示Permission denied (publickey,gssapi-keyexch,password)。原因是ssh localhost都需要密码Hadoop 脚本没有能力自动输密码只能卡住。解决方式是对集群里每个主机名都验证一遍免密效果ssh n01 date ssh n02 date ssh n03 date如果其中某个节点提示输入密码说明authorized_keys没配置好。常见的原因是权限不对.ssh目录权限应为 700authorized_keys权限应为 600权限给宽了 SSH 直接忽略这个文件。这属于安全限制不是 Hadoop 的问题改掉权限即可。配好之后重新执行一遍三台机器的 ssh 测试确保所有主机名都能秒过。5.4 YARN 容器内存设置过大导致 NodeManager 挂掉现象是start-yarn.sh执行完jps里能看到 NodeManager但过几十秒进程消失日志里有OutOfMemoryError或者Container [pid...] is running beyond virtual memory limits。原因是默认的yarn.nodemanager.resource.memory-mb在某些教程模板里被改得很大比如在 2G 内存的虚拟机里配了 8GNodeManager 自身分配内存失败直接退出。解决方法是把内存相关的参数调到物理机实际可用内存的 60% 左右property nameyarn.nodemanager.resource.memory-mb/name value2048/value /property property nameyarn.scheduler.maximum-allocation-mb/name value2048/value /property property nameyarn.nodemanager.vmem-pmem-ratio/name value2.1/value /propertyvmem-pmem-ratio是虚拟内存与物理内存的比值上限MapReduce 作业默认会申请虚拟内存不调这个参数时物理内存只剩 1G 的机器上作业经常报Container killed on request. Exit code is 143。这个参数在课程设计的机器上尤其重要很多人的虚拟机只有 2G 内存不改vmem-pmem-ratio就是作业跑不动。5.5 防火墙与 /etc/hosts 没同步节点间通信失败现象是集群里的 DataNode 全部显示 Live但跨节点的 NameNode 之间连不上或者hdfs haadmin命令返回连接超时日志里全是ConnectException。原因一般有二防火墙拦截了 8020、8485、2181 等端口或者各机器的/etc/hosts内容不一致n01 解析n02时拿到的 IP 是错的。解决方式是先互 ping 验证网络再检查端口# 三台机器互 ping 主机名 ping n02 # 检查端口是否能通 telnet n02 8485 telnet n02 2181如果不通先放行端口或直接关防火墙。虚拟机实验环境我建议直接关闭防火墙减少干扰项systemctl stop firewalld systemctl disable firewalld这类网络排查最怕的是只盯着一台机器看正确做法是在三台机器上分别执行telnet验证双向连通性。我见过一个案例n01 能连 n02但 n02 连不上 n01最后发现是 n02 上 hosts 写错了一个 IP这种问题不逐台验证很难定位。6. distcp 参数说明与集群间迁移一次实战的边界6.1 distcp 常用参数速查distcp 是 Hadoop 自带的跨集群复制工具全称是 distributed copy。你可能会问它和hdfs dfs -cp有什么区别区别在于 distcp 会启动 MapReduce 作业并发复制几十 GB 的数据几百个 map 同时跑速度完全不在一个量级。下面是 2.6.5 版本里我实际用过的参数先看表格参数作用使用建议-update只复制源端有而目标端没有或版本更新的文件增量复制首选-overwrite无条件覆盖目标端同名文件源端变更少时配合-update-delete删除目标端多余的路径做镜像同步时配合-update-skipCrC跳过 CRC 校验减少读写开销目标端能接受校验精度损失时用-m设置最大 map 数不要超过集群可用容器数-bandwidth限制单 map 的传输带宽MB/s避免挤占业务带宽-p保留权限、属主、时间戳等属性跨集群迁移时强烈建议加-i单个文件失败时忽略错误继续大目录复制时推荐加这组参数里最容易用错的是-update和-overwrite的关系。很多人以为-update会覆盖本地已有文件官方其实解释了-update只根据文件大小和修改时间判断是否重新复制若两边文件大小相同即使内容有差异-update也会跳过。这时想要强制刷新得用-overwrite。我自己的习惯是基准同步用-update全量替换用-overwrite不要同时盲目叠加。6.2 实战跨集群搬迁 HDFS 目录从一个 Hadoop 集群向另一个集群迁移目录我一般是这样执行的。假设源集群的 active NameNode 是n01:9000目标集群是n02:9000要复制/user/hadoop/weblogs到对方的同样路径hadoop distcp \ -update \ -skipCrC \ -m 20 \ -bandwidth 10 \ -i \ hdfs://n01:9000/user/hadoop/weblogs \ hdfs://n02:9000/user/hadoop/weblogs先说明参数-update增量复制避免重复拷贝-skipCrC跳过 CRC 校验拷贝大目录时性能提升明显-m 20表示最多跑 20 个 map 任务-bandwidth 10限制每个 map 的带宽为 10MB/s避免把源集群网络占满-i单个文件失败时继续跑不至于因为一个坏文件导致整个任务废弃。源和目标路径都用完整的hdfs://host:port/path格式特别是目标端如果不在同一个集群必须写全 RPC 地址。作业执行后屏幕上会弹出一个 MapReduce job 的进度窗口。注意观察每个 map 的完成情况和失败次数如果出现大面积失败先停掉作业检查网络。作业结束后到目标集群验证样本文件hdfs dfs -ls hdfs://n02:9000/user/hadoop/weblogs/ | head # 抽查某个文件的大小是否与源端一致 hdfs dfs -ls hdfs://n01:9000/user/hadoop/weblogs/如果-skipCrC开着文件块大小对不上但复制仍显示成功这时用hdfs fsck对目标目录做一次完整性检查更稳妥。生产环境里我一般不开-skipCrC做首次全量只有做增量时才配合-update使用。6.3 别踩的坑实时性、块大小、权限distcp 看起来就是一个hadoop distcp命令但实践中它有不少边界条件。第一个边界是它不是实时同步工具支持的是“一次性批量复制”。源端如果一直在产生新文件distcp 只会复制启动瞬间已经存在的文件之后进入的文件完全不管。想要持续同步要么定时调度 distcp要么上真正的复制工具不要把 distcp 当成同步软件用。第二个边界是跨版本迁移时块大小不匹配的问题。源集群的 block size 是 128MB目标集群是 64MBdistcp 在目标端会按新集群的块大小重新切分这不影响数据内容但会导致目标端文件占用的 block 数量不同。有人拿hdfs dfs -du对比源和目标发现字节数对不上就以为复制出错了其实是 block 粒度导致的统计差异文件内容是对的。第三个边界是权限保留。跨集群迁移时如果目标集群的用户体系跟源集群不一样不加-p会导致所有文件属主变成执行 distcp 的用户。反过来加了-p但当前用户没有目标路径的写权限复制会直接失败。建议在目标集群先创建好对应的用户和父目录hdfs dfs -mkdir -p /user/hadoop/weblogs hdfs dfs -chown hdfs:hadoop /user/hadoop/weblogs我的习惯是先拿一个小目录试跑一遍观察参数组合的效果再上全量。具体做法是先复制一个只有几十 MB 的测试目录查看结果文件的权限、时间戳、大小是否和预期一致确认没问题后再把-m和-bandwidth去掉跑正式全量。从那以后我每次用 distcp 都强制走一遍小目录验证这个习惯帮我避免了好几次因为参数理解偏差导致的大范围覆盖事故。希望帮到你。本文还有配套的精品资源点击获取
返回列表