1. 项目概述:为什么今天还要亲手搭一个Hadoop 2.7.7集群?
你点开这个标题,大概率不是为了怀旧——Hadoop 2.7.7发布于2018年,距今已六年有余,社区早已转向3.x主线甚至拥抱云原生数据湖架构。但现实是:某高校大数据实验课仍在用它做MapReduce编程实训;某地市级政务云平台的离线数仓模块,底层YARN资源调度器至今跑着打了定制补丁的2.7.7;还有大量中小企业的ETL脚本、日志分析Pipeline,依然依赖这个版本的HDFS高可用机制和稳定的JobHistoryServer。它不是过时,而是“稳在关键处”。
我带过三届学生做分布式系统课程设计,也帮两家传统制造企业做过数据平台迁移评估。发现一个反直觉的事实:越是在生产环境里长期服役的老版本,越需要被真正理解透。因为没人敢随便升级——上游业务系统调用的是特定API签名,下游监控脚本解析的是固定格式的日志字段,连NameNode的fsimage元数据结构都可能被定制化工具深度依赖。这时候,照着官网文档敲一遍start-dfs.sh,远不如亲手从Java环境变量校验开始,一层层拆解hadoop-env.sh里那17个JVM参数的取舍逻辑来得实在。
这个“超详细版”不讲概念复述,不堆砌命令截图,而是还原一个真实场景:你在一台CentOS 7.6物理机上,要为某模拟项目X搭建3节点Hadoop集群(1主2从),所有操作必须可回溯、可审计、可复现。你会遇到OpenSSL版本冲突导致SSH免密失败,会卡在/etc/hosts里一个空格引发的DataNode注册超时,会在yarn-site.xml中为yarn.nodemanager.resource.memory-mb填错数值导致Container被Kill——这些都不是文档里的“注意事项”,而是凌晨两点盯着tail -f hadoop-hadoop-datanode-xxx.log时,用grep -A5 -B5 "OutOfMemory"一行行翻出来的血泪。
核心关键词已经锚定:Linux、Hadoop 2.7.7、集群部署、配置细节、实操避坑。接下来的内容,每一行配置、每一个端口、每一次scp传输,都对应着真实环境里某个具体故障的根因。你可以把它当检查清单用,也可以当排错手册查——毕竟,真正的集群运维,从来不是按部就班执行脚本,而是在混沌中识别信号。
2. 整体架构设计与方案选型逻辑
2.1 为什么坚持用2.7.7而非更新版本?
这不是技术保守主义,而是成本权衡后的理性选择。Hadoop 2.7.7是2.x系列最后一个稳定长周期支持版本(LTS),其核心组件组合经过大规模生产验证:
- HDFS:支持Quorum Journal Manager(QJM)高可用,避免单点NameNode故障;Block大小默认128MB,对TB级日志文件切分效率优于早期版本。
- YARN:ResourceManager HA通过ZooKeeper实现自动故障转移,比3.x的嵌入式ZK服务更轻量,适合资源受限的测试环境。
- MapReduce:Shuffle阶段的
mapreduce.shuffle.port可显式绑定IP,解决多网卡服务器上Shuffle连接拒绝问题——这点在2.8+版本中被移除,需额外配置yarn.nodemanager.address。
更重要的是生态兼容性。某实验室使用的自研数据质量校验工具,其MR Job提交接口硬编码了org.apache.hadoop.mapred.JobConf类路径,而Hadoop 3.x已全面迁移到org.apache.hadoop.mapreduce.Job。强行升级会导致整个质检流程中断。因此,我们的部署目标很明确:不是追求最新,而是构建一个与现有业务链路零摩擦的确定性环境。
2.2 集群规模与节点角色分配策略
本次部署采用经典3节点模型,但角色分配并非简单“1主2从”:
| 节点主机名 | IP地址 | 角色分配 | 关键考量 |
|---|---|---|---|
| master | 192.168.10.10 | NameNode, ResourceManager, JobHistoryServer | 主控节点需承载元数据服务与资源调度,内存预留≥4GB,磁盘需独立挂载/data目录 |
| slave1 | 192.168.10.11 | DataNode, NodeManager | 作为计算节点,关闭swap分区防止YARN Container被OOM Killer误杀 |
| slave2 | 192.168.10.12 | DataNode, NodeManager, SecondaryNameNode | SecondaryNameNode需与NameNode网络延迟<5ms,故部署在同一局域网段 |
这里有个易被忽略的细节:SecondaryNameNode不能与NameNode共存于同一台机器。虽然Hadoop允许这种部署,但当NameNode执行checkpoint时,SecondaryNameNode会发起大量HTTP请求拉取edits日志,导致NameNode响应延迟飙升,进而触发ZooKeeper Session超时。我们在某次压测中观察到,共存时NameNode的RpcQueueTimeAvgTime指标峰值达1200ms,而分离部署后稳定在8ms以内。
2.3 网络与安全基线设定
Linux环境下的Hadoop集群,本质是TCP/IP协议栈上的精密仪器。我们强制要求以下基线:
- 主机名解析:
/etc/hosts必须同时包含IPv4和IPv6条目(即使禁用IPv6),因为Hadoop某些组件(如ZKFC)会尝试双栈解析,缺失IPv6条目将导致java.net.UnknownHostException。 - 防火墙策略:仅开放必要端口,拒绝全端口放行。例如:
- NameNode RPC端口:
8020(非9000,后者是旧版配置) - DataNode数据传输端口:
50010 - YARN ResourceManager Web UI:
8088 - 历史服务器Web UI:
19888
- NameNode RPC端口:
- SELinux状态:必须设为
permissive而非disabled。直接禁用SELinux会导致/var/log/hadoop目录上下文丢失,后续启动时log4j无法写入日志,报错Permission denied却无明确提示。
这些设定看似琐碎,实则是集群稳定性的隐形基石。某次客户环境故障,根源竟是iptables规则中一条-A INPUT -j REJECT放在了Hadoop端口规则之前,导致DataNode心跳包被静默丢弃——而jps进程显示正常,netstat -tuln也看到端口监听,排查耗时6小时。
3. 核心环境准备与依赖安装
3.1 Java环境:版本锁定与JVM参数精调
Hadoop 2.7.7官方声明支持Java 7u67+或Java 8u40+,但实际生产中必须规避两个致命陷阱:
- OpenJDK vs Oracle JDK:Oracle JDK 8u161之后版本引入了
-XX:+UseG1GC作为默认GC,而Hadoop 2.7.7的hadoop-env.sh中HADOOP_HEAPSIZE参数未适配G1的Region大小计算逻辑,会导致NameNode频繁Full GC。我们坚持使用OpenJDK 8u292(最后支持Parallel GC的稳定版)。 - JAVA_HOME路径陷阱:
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.292.b10-1.el7_9.x86_64这类RPM安装路径含空格和特殊字符,Hadoop脚本中的$JAVA_HOME/bin/java会被shell错误解析。必须创建软链接:ln -s /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.292.b10-1.el7_9.x86_64 /opt/java8,并在hadoop-env.sh中指定export JAVA_HOME=/opt/java8。
JVM参数配置是性能分水岭。以NameNode为例,其堆内存分配需满足公式:HADOOP_HEAPSIZE = 1024 + (总DataNode数量 × 128)
这是为每个DataNode注册维护约128MB元数据缓存的硬性需求。3节点集群即1024 + 2×128 = 1280MB。但若直接设置export HADOOP_HEAPSIZE=1280,JVM会将新生代(Young Gen)默认设为堆的1/3(约426MB),而NameNode的Eden区对象存活率极高,导致Minor GC频发。因此必须显式指定:
export HADOOP_OPTS="-Xmx1280m -Xms1280m -XX:NewSize=640m -XX:MaxNewSize=640m -XX:+UseParallelGC"其中NewSize=MaxNewSize锁定新生代大小,UseParallelGC确保低延迟GC。
提示:
hadoop-env.sh中所有export语句必须顶格书写,行尾不可有空格。曾有学员因export HADOOP_HEAPSIZE=1280(末尾空格)导致变量未生效,NameNode启动后内存溢出崩溃,日志中却只显示java.lang.OutOfMemoryError: Java heap space,无任何变量加载提示。
3.2 SSH免密登录:密钥生成与权限加固
Hadoop集群启动依赖SSH无密码执行远程命令,但标准教程常忽略两个安全细节:
- 密钥类型选择:
ssh-keygen -t rsa -b 4096生成RSA密钥,而非默认的2048位。因为Hadoop 2.7.7的start-dfs.sh脚本在调用ssh时未指定-o HostKeyAlgorithms=+ssh-rsa,而新版OpenSSH 8.8+默认禁用RSA-SHA1签名算法。使用4096位密钥可兼容旧算法协商。 - authorized_keys权限:
~/.ssh/authorized_keys文件权限必须为600,且.ssh目录权限为700。若权限过宽(如644),SSH服务会拒绝读取密钥,报错Authentication refused: bad ownership or modes for directory /home/hadoop/.ssh。这个错误在ssh -v hadoop@slave1调试时会明确提示,但start-dfs.sh静默失败。
实操步骤需严格遵循顺序:
- 在master节点执行
ssh-keygen -t rsa -b 4096 -N "" -f ~/.ssh/id_rsa(空密码) - 将公钥分发至所有节点:
ssh-copy-id -i ~/.ssh/id_rsa.pub hadoop@slave1(注意:ssh-copy-id会自动修复权限,比手动scp更可靠) - 验证连通性:
for node in master slave1 slave2; do ssh $node "hostname && java -version"; done
注意:
ssh-copy-id命令在CentOS 7默认未安装,需先执行yum install -y openssh-clients。若跳过此步直接运行start-dfs.sh,脚本会在slave1节点启动失败后立即退出,不会尝试slave2,导致你以为只有单节点故障。
3.3 Hadoop二进制包校验与解压规范
从Apache官网下载的hadoop-2.7.7.tar.gz需进行双重校验:
- SHA-256校验:下载同目录下的
hadoop-2.7.7.tar.gz.sha256文件,执行sha256sum -c hadoop-2.7.7.tar.gz.sha256。曾有镜像站因同步延迟提供旧版哈希值,导致校验通过但实际文件损坏。 - GPG签名验证:导入Apache Hadoop Release Signing Key(ID:
E9D0B7F0),执行gpg --verify hadoop-2.7.7.tar.gz.asc hadoop-2.7.7.tar.gz。这能防范中间人篡改。
解压时必须使用tar -zxvf而非tar -xvf,因为部分压缩包在gzip流中存在冗余字节,-z参数可正确处理。解压后立即执行:
chown -R hadoop:hadoop /opt/hadoop-2.7.7 chmod -R 755 /opt/hadoop-2.7.7特别注意/opt/hadoop-2.7.7/share/hadoop/common/lib/native目录下的libhadoop.so文件——这是Hadoop调用本地C库的入口。若权限为644,hadoop checknative -a命令会报告Native library checking:全部为false,导致Snappy压缩失效,MapReduce作业I/O性能下降40%以上。
4. 核心配置文件逐行解析与参数调优
4.1core-site.xml:全局配置中枢
该文件定义Hadoop集群的统一命名空间和基础行为,关键参数必须精准匹配网络拓扑:
<configuration> <!-- 指定HDFS的默认文件系统URI --> <property> <name>fs.defaultFS</name> <value>hdfs://master:8020</value> <description>集群入口地址,必须与NameNode绑定IP一致</description> </property> <!-- Hadoop临时目录,需独立挂载SSD --> <property> <name>hadoop.tmp.dir</name> <value>/data/hadoop/tmp</value> <description>所有组件的临时文件根目录,避免写入系统盘</description> </property> <!-- 启用短路本地读取,绕过DataNode进程直接读磁盘 --> <property> <name>dfs.client.read.shortcircuit</name> <value>true</value> </property> <property> <name>dfs.domain.socket.path</name> <value>/var/run/hadoop-hdfs/dn_socket</value> </property> </configuration>dfs.client.read.shortcircuit是性能加速器。当Client与DataNode在同一物理机时(如YARN Container读取本地HDFS Block),启用后可减少一次TCP网络栈开销,实测吞吐提升22%。但需确保/var/run/hadoop-hdfs目录存在且属主为hadoop用户:mkdir -p /var/run/hadoop-hdfs && chown hadoop:hadoop /var/run/hadoop-hdfs。
实操心得:
fs.defaultFS的master必须能在所有节点的/etc/hosts中解析。若使用DNS而非hosts文件,需确认/etc/resolv.conf中search域配置正确,否则hadoop fs -ls /会报错Call From slave1/192.168.10.11 to master:8020 failed on connection exception。
4.2hdfs-site.xml:HDFS高可用核心
此文件决定NameNode的生死存亡,QJM高可用配置是重中之重:
<configuration> <!-- NameNode持久化元数据到QJM --> <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>master:8020</value> </property> <property> <name>dfs.namenode.http-address.mycluster.nn1</name> <value>master:50070</value> </property> <!-- nn2配置省略,实际需补充slave1节点信息 --> <!-- QJM JournalNode集群地址 --> <property> <name>dfs.namenode.shared.edits.dir</name> <value>qjournal://master:8485;slave1:8485;slave2:8485/mycluster</value> </property> <!-- 自动故障转移开关 --> <property> <name>dfs.ha.automatic-failover.enabled</name> <value>true</value> </property> </configuration>关键点在于dfs.namenode.shared.edits.dir的URL格式:qjournal://host1:port;host2:port;host3:port/nameserviceId。分号;分隔JournalNode地址,不可用逗号。若误写为qjournal://master:8485,slave1:8485...,NameNode启动时会抛出java.net.UnknownHostException: master,slave1——因为逗号被解析为hostname的一部分。
JournalNode端口8485需在所有节点开放。我们曾在一个封闭网络环境中,因安全组策略仅放行8020/50010,导致hdfs zkfc -formatZK命令卡死在Connecting to ZooKeeper,日志无任何错误,最终通过tcpdump -i any port 8485抓包才定位到连接被拒。
4.3yarn-site.xml:资源调度引擎配置
YARN的稳定性取决于Container内存管理的精确控制:
<configuration> <!-- ResourceManager高可用 --> <property> <name>yarn.resourcemanager.ha.enabled</name> <value>true</value> </property> <property> <name>yarn.resourcemanager.cluster-id</name> <value>yarn-cluster</value> </property> <property> <name>yarn.resourcemanager.ha.rm-ids</name> <value>rm1,rm2</value> </property> <property> <name>yarn.resourcemanager.hostname.rm1</name> <value>master</value> </property> <!-- NodeManager内存资源上限 --> <property> <name>yarn.nodemanager.resource.memory-mb</name> <value>8192</value> </property> <property> <name>yarn.nodemanager.resource.cpu-vcores</name> <value>4</value> </property> <!-- Container最小内存单位 --> <property> <name>yarn.scheduler.minimum-allocation-mb</name> <value>1024</value> </property> <property> <name>yarn.scheduler.maximum-allocation-mb</name> <value>8192</value> </property> </configuration>yarn.nodemanager.resource.memory-mb必须小于物理内存的80%。若节点有16GB内存,设为16384会导致系统OOM Killer随机杀死进程。我们按物理内存 × 0.75计算:16×0.75=12GB,再减去NameNode等守护进程占用的2GB,最终设为8192MB。
yarn.scheduler.minimum-allocation-mb与maximum-allocation-mb的比值影响资源碎片率。若设为512/16384,小作业申请512MB会浪费大量内存;设为1024/8192则平衡性最佳。实测表明,当比值为1:8时,集群平均内存利用率稳定在72%-78%,低于1:4则碎片率超35%。
4.4mapred-site.xml:MapReduce计算框架
此文件定义MR作业的执行环境,重点在于历史服务器集成:
<configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> <!-- JobHistoryServer地址 --> <property> <name>mapreduce.jobhistory.address</name> <value>master:10020</value> </property> <property> <name>mapreduce.jobhistory.webapp.address</name> <value>master:19888</value> </property> <!-- Map任务JVM堆内存 --> <property> <name>mapreduce.map.java.opts</name> <value>-Xmx1024m</value> </property> <property> <name>mapreduce.map.memory.mb</name> <value>1024</value> </property> </configuration>mapreduce.map.java.opts与mapreduce.map.memory.mb必须严格匹配:前者是JVM堆上限,后者是YARN为Container分配的物理内存。若map.memory.mb=2048而map.java.opts=-Xmx1024m,YARN会认为Container内存充足,但JVM实际只能使用1GB,剩余1GB被浪费;反之若map.java.opts=-Xmx2048m而map.memory.mb=1024,YARN会因Container超限将其Kill。
常见问题:
mapreduce.jobhistory.webapp.address端口19888被占用时,JobHistoryServer启动失败但无明确日志。需检查/var/log/hadoop/hadoop-hadoop-historyserver-master.log,搜索BindException。解决方案:修改端口并重启服务,或lsof -i :19888查杀冲突进程。
5. 集群初始化与启动全流程
5.1 格式化NameNode与JournalNode
这是集群的“心脏起搏”步骤,顺序不可颠倒:
格式化JournalNode存储目录(所有节点执行):
hdfs journalnode
等待日志输出Started JournalNode后,执行:hdfs namenode -format -clusterId mycluster -nonInteractive注意:
-clusterId必须与hdfs-site.xml中dfs.nameservices值一致,-nonInteractive避免交互式确认。启动JournalNode服务(所有节点):
hadoop-daemon.sh start journalnode
验证:jps应显示JournalNode进程,netstat -tuln | grep 8485应监听。格式化NameNode(仅master节点):
hdfs namenode -format -clusterId mycluster
此命令会生成/data/hadoop/dfs/name/current/VERSION文件,其中clusterId字段必须与JournalNode中的一致,否则DataNode无法注册。启动NameNode(master):
hadoop-daemon.sh start namenode
首次启动后,访问http://master:50070应看到"Safe mode is ON",表示等待DataNode上报块信息。
5.2 启动DataNode与ZKFC
DataNode启动前需确保网络通畅:
- 在slave1/slave2节点执行:
hadoop-daemon.sh start datanode
若启动失败,检查/var/log/hadoop/hadoop-hadoop-datanode-slave1.log,常见错误:java.io.IOException: Failed to replace a bad datanode...:因/etc/hosts中master解析失败,需ping master验证。org.apache.hadoop.util.DiskChecker$DiskErrorException:/data/hadoop/dfs/data目录权限非hadoop:hadoop,执行chown -R hadoop:hadoop /data/hadoop/dfs/data。
ZKFC(ZooKeeper Failover Controller)是HA大脑,必须在NameNode启动后执行:
hadoop-daemon.sh start zkfc(master节点)hdfs zkfc -formatZK(首次运行,初始化ZooKeeper节点)
验证ZKFC状态:echo stat | nc localhost 2181 | grep "Mode",输出Mode: follower表示正常。若为standalone,说明ZKFC未连接到ZooKeeper集群。
5.3 YARN与历史服务器启动
YARN启动依赖HDFS可用,因此必须在HDFS健康后操作:
启动ResourceManager(master):
yarn-daemon.sh start resourcemanager
访问http://master:8088应显示"Cluster Metrics"页面。启动NodeManager(slave1/slave2):
yarn-daemon.sh start nodemanager
检查/var/log/hadoop/yarn-hadoop-nodemanager-slave1.log,确认Registered with ResourceManager as ...。启动JobHistoryServer(master):
mr-jobhistory-daemon.sh start historyserver
访问http://master:19888应显示"JobHistory Server"首页。
实操技巧:所有守护进程启动后,执行
hadoop dfsadmin -report查看DataNode状态。正常输出应包含:Configured Capacity: 1234567890123 (1.12 TB)DFS Used: 0 (0 KB)Live datanodes (2):
若显示Dead datanodes (2):,说明DataNode未注册成功,需按前述步骤排查网络与配置。
6. 集群验证与典型故障排查
6.1 基础功能验证清单
完成启动后,按优先级执行以下验证:
| 验证项 | 命令 | 预期结果 | 失败原因定位 |
|---|---|---|---|
| HDFS读写 | hadoop fs -mkdir /test && hadoop fs -put /etc/hosts /test/ | 无报错,hadoop fs -ls /test显示文件 | 检查core-site.xml中fs.defaultFS及/etc/hosts解析 |
| YARN资源 | yarn node -list | 输出2个RUNNING状态Node | 查看yarn.nodemanager.resource.memory-mb是否超限 |
| MR作业 | hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.7.jar pi 10 1000000 | 输出Pi is及数值 | 检查mapred-site.xml中mapreduce.framework.name=yarn |
| HA切换 | kill -9 $(cat $HADOOP_PID_DIR/hadoop-hadoop-namenode.pid) | hadoop haadmin -getServiceState nn1返回standby | 确认ZKFC进程运行且ZooKeeper健康 |
特别注意MR作业验证:pi示例会生成大量Mapper,若yarn.scheduler.maximum-allocation-mb设置过小(如2048),会导致Requested container allocation failed。此时需调整参数并重启ResourceManager。
6.2 高频故障速查表
我们整理了过去三年中客户环境最常遇到的12类故障,按发生频率排序:
| 故障现象 | 根本原因 | 解决方案 | 预防措施 |
|---|---|---|---|
Connection refusedon port 8020 | /etc/hosts中master指向127.0.0.1而非真实IP | 修改/etc/hosts,master行IP改为192.168.10.10 | 部署前执行getent hosts master验证 |
DataNode未出现在hdfs dfsadmin -report | dfs.datanode.data.dir路径不存在或权限错误 | mkdir -p /data/hadoop/dfs/data && chown hadoop:hadoop /data/hadoop/dfs/data | 初始化脚本中加入mkdir -p检查 |
| ResourceManager Web UI空白 | yarn.resourcemanager.webapp.address端口被占用 | lsof -i :8088查杀进程,或修改yarn-site.xml端口 | 启动前执行netstat -tuln | grep :8088 |
java.lang.NoClassDefFoundError: org/apache/hadoop/fs/FileSystem | HADOOP_CLASSPATH未包含Hadoop JAR包 | 在hadoop-env.sh中添加export HADOOP_CLASSPATH=$HADOOP_HOME/share/hadoop/common/*:$HADOOP_HOME/share/hadoop/common/lib/* | 使用hadoop classpath命令验证 |
Failed to connect to ZooKeeper | ZKFC未启动或ZooKeeper服务未运行 | hadoop-daemon.sh start zkfc,检查/var/log/hadoop/hadoop-hadoop-zkfc-master.log | HA部署必须先启动ZooKeeper集群 |
独家避坑技巧:当
hadoop fs -ls /报错Operation category READ is not supported in state standby时,说明客户端连接到了Standby NameNode。这不是配置错误,而是fs.defaultFS指向了mycluster(逻辑名),而ZKFC尚未完成选举。此时执行hadoop haadmin -getServiceState nn1确认Active节点,然后临时修改core-site.xml中fs.defaultFS为hdfs://master:8020(Active节点物理地址),验证通过后再改回逻辑名。
6.3 性能基线测试与调优验证
部署完成后,必须建立性能基线。我们使用标准TeraSort测试:
# 生成10GB测试数据 hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.7.jar teragen 100000000 /tera/input # 执行排序 hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.7.jar terasort /tera/input /tera/output # 验证结果 hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.7.jar teravalidate /tera/output /tera/validate关键指标阈值:
- TeraGen耗时:3节点集群应≤8分钟(CPU 4核/16GB内存)
- TeraSort耗时:应≤15分钟,且
Map input records与Reduce output records相等 - Validate结果:
Number of errors: 0
若TeraSort耗时超30分钟,检查yarn.nodemanager.resource.cpu-vcores是否过低——实测表明,当vcores=2时,Shuffle阶段Reduce端Merge速度下降60%,因CPU成为瓶颈。
7. 运维监控与日常管理要点
7.1 日志体系结构与关键日志定位
Hadoop日志分散在多个目录,需建立快速定位路径:
- NameNode日志:
/var/log/hadoop/hadoop-hadoop-namenode-master.log
关键搜索词:Safemode,Block report,Edit log - DataNode日志:
/var/log/hadoop/hadoop-hadoop-datanode-slave1.log
关键搜索词:Received block,Sending block,Volume failure - ResourceManager日志:
/var/log/hadoop/yarn-hadoop-resourcemanager-master.log
关键搜索词:Application added,Container launched,Resource request - NodeManager日志:
/var/log/hadoop/yarn-hadoop-nodemanager-slave1.log
关键搜索词:Container started,Container killed,Localizer failed
实操心得:日志轮转由
log4j.properties控制,但默认配置hadoop.root.logger=INFO,RFA中的RFA(RollingFileAppender)未设置MaxFileSize,导致单个日志文件超GB。建议在$HADOOP_HOME/etc/hadoop/log4j.properties中添加:log4j.appender.RFA.MaxFileSize=256MBlog4j.appender.RFA.MaxBackupIndex=20
避免磁盘被日志占满。
7.2 健康检查自动化脚本
手动检查效率低下,我们编写了hadoop-health-check.sh脚本:
#!/bin/bash # 检查HDFS状态 echo "=== HDFS Status ===" hdfs dfsadmin -report 2>/dev/null | grep -E "(Live|Dead|Decommissioning)" # 检查YARN节点 echo -e "\n=== YARN Nodes ===" yarn node -list 2>/dev/null | grep -E "(RUNNING|UNHEALTHY)" # 检查关键进程 echo -e "\n=== Critical Processes ===" jps | grep -E "(NameNode|DataNode|ResourceManager|NodeManager|JournalNode|ZKFC)" # 检查端口监听 echo -e "\n=== Port Listening ===" netstat -tuln | grep -E ":8020|:50070|:8088|:19888|:8485"将此脚本加入crontab每5分钟执行:*/5 * * * * /opt/hadoop-2.7.7/bin/hadoop-health-check.sh >> /var/log/hadoop/health.log 2>&1。当日志中连续出现Dead datanodes (2)时,立即触发告警。
7.3 安全加固与权限管理实践
生产环境必须实施最小权限原则:
- HDFS权限:禁用
dfs.permissions.enabled=false,启用POSIX风格权限。创建业务用户:hadoop fs -mkdir -p /user/bizuser && hadoop fs -chown bizuser:hadoop /user/bizuser - Web UI安全:
hadoop-http-auth-signature-secret文件必须设为600权限,内容为32位随机字符串:openssl rand -hex 16 > $HADOOP_CONF_DIR/hadoop-http-auth-signature-secret - RPC加密:在
core-site.xml中添加:
` hadoop.rpc.protection privacy </property