1. 按照下面脚本 启动 hdfs集群
for i in {1..3};do
ssh ruozedata00$i "/home/hadoop/app/zookeeper/bin/zkServer.sh start"
done
sleep 5s
start-dfs.sh
sleep 5s
start-yarn.sh
sleep 5s
ssh ruozedata002 "/home/hadoop/app/hadoop/sbin/yarn-daemon.sh start resourcemanager"
mr-jobhistory-daemon.sh start historyserver
启动之后, jps 查看, 发现 zk并没有启动
ps 查看, 没有zk 进程
看下配置文件, 找log目录
cat zoo.cfg
只有这一个 Dir的配置, 找不到log 目录
cat log4j.properties
发现如上配置, 表示 log 目录在当前目录, 文件名为 zookeeper.log
但是当前目录没有发现这个文件, 通过find / -name "zookeeper.log" 查看
并没有找到
看来要到源头去找问题了, 源头在哪? 启动脚本
2. 查看启动脚本 zkServer.sh
看下 启动部分
nohup "$JAVA" "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" \
-cp "$CLASSPATH" $JVMFLAGS $ZOOMAIN "$ZOOCFG" > "$_ZOO_DAEMON_OUT" 2>&1 < /dev/null &
可以看到 zk的日志目录为 ${ZOO_LOG_DIR}
找到了 日志文件
查看 zkEnv.sh 把 ZOO_LOG_DIR 改为 /home/hadoop/app/zookeeper/logs
cd /home/hadoop/app/zookeeper/
mkdir logs
再次启动 zk
看到了这个log文件
查看内容
nohup: failed to run command ‘java’: No such file or directory
提示java 命令运行不了
确实运行不了
3. 回头看下启动脚本
nohup "$JAVA" "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" \
$JAVA 在 zkEnv.sh 中的定义
可以看到, 如果 $JAVA_HOME 不为空, JAVA=$JAVA_HOME/bin/java
否则 JAVA=java
加入
echo "----------------------java: "
echo $JAVA_HOME
echo $JAVA
看打印输出
发现打印为空, 课件 $JAVA= "", 执行 的是 else JAVA=java
而通过 ssh 执行 java 会报错
所以可以看出启动失败是因为:
ssh 执行 java 不成功
为什么会不成功?
4. 理解 linux 的ssh
预备知识: bash的四种模式,bash会依据这四种模式而选择加载不同的配置文件,而且加载的顺序也有所不同,
ssh user@remote command 属于
non-interactive + non-login shell 模式, 即会创建一个shell,执行完脚本之后便退出,不再需要与用户交互。
其加载 环境变量是只从用户的家目录的 .bashrc加载
5. 解决问题方法
5.1) 将 zkEnv.sh 中的 java写成绝对路径
if [ "$JAVA_HOME" != "" ]; then
JAVA="$JAVA_HOME/bin/java"
else
JAVA=java 改为JAVA=/usr/java/jdk1.8.0_45/bin/java
fi
5.2) 将 JAVA 的环境变量配置在 /home/haoop/.bashrc中
vim /home/haoop/.bashrc
export JAVA_HOME=/usr/java/jdk1.8.0_45
export PATH=$JAVA_HOME/bin:$PATH
6. 启动测试
将 ruozedata001 的 /home/haoop/.bashrc 拷贝到 ruozedata00{2,3} 中
scp ~/.bashrc ruozedata002:/home/hadoop/
scp ~/.bashrc ruozedata003:/home/hadoop/
启动 集群, 正常