我在主服务器和从服务器上使用Hadoop 1.2.1,但我将它们安装在不同的目录上。因此,当我在master上调用bin/start-dfs.sh
时,我收到以下错误。
partho@partho-Satellite-L650: starting datanode, logging to /home/partho/hadoop/apache/hadoop-1.2.1/libexec/../logs/hadoop-partho-datanode-partho-Satellite-L650.out
hduser@node2-VirtualBox: bash: line 0: **cd: /home/partho/hadoop/apache/hadoop-1.2.1/libexec/..: No such file or directory**
hduser@node2-VirtualBox: bash: **/home/partho/hadoop/apache/hadoop-1.2.1/bin/hadoop-daemon.sh: No such file or directory**
partho@partho-Satellite-L650: starting secondarynamenode, logging to /home/partho/hadoop/apache/hadoop-1.2.1/libexec/../logs/hadoop-partho-secondarynamenode-partho-Satellite-L650.out
如下所示,守护进程在Master上创建得很好
partho@partho-Satellite-L650:~/hadoop/apache/hadoop-1.2.1$ jps
4850 Jps
4596 DataNode
4441 NameNode
4764 SecondaryNameNode
很明显,Hadoop正在尝试使用主机上的hadoop-daemon.sh
在奴隶上找到libexec
和$HADOOP_HOME
。
如何配置单个数据节点/从属设备,以便在从主服务器启动集群时,检查各个从服务器的Hadoop主目录是否有hadoop-daemon.sh
?
Hadoop通常在名为hadoop-env.sh的文件中的每个节点上设置HADOOP_HOME环境变量。
您可以使用相应节点的路径更新每个节点上的hadoop-env.sh。它应该在/home/partho/hadoop/apache/hadoop-1.2.1/中。可能希望首先停止群集,以便获取更改。
如果已找到已安装的运行,请找到hadoop-env.sh或find / -name“hadoop-env.sh”
对于最佳解决方案,您应该在任何目录中保留hadoop目录,但它们应该相同,例如:
在主路径上:
/opt/hadoop
在奴隶路径上
/opt/hadoop
使用哪个版本无关紧要,但目录名称应该相同
设置集群后,从master启动所有守护程序
bin/hadoop namenode -format(if required)
bin/stop-dfs.sh
bin/start-dfs.sh
bin/start-mapred.sh
为了从master开始所有节点,
- you need to install ssh on each node
- once you install ssh and generate ssh key in each server, try connecting each nodes from master
- make sure slaves file in master node has all Ips of all nodes
所以命令就是
- install ssh(in each node) : apt-get install openssh-server
- once ssh is installed,generate key : ssh-keygen -t rsa -P ""
- Create password less login from namenode to each node:
ssh-copy-id -i $HOME/.ssh/id_rsa.pub user@datanodeIP
user - hadoop user on each machine`enter code here`
- put all nodes ip in slaves(in conf dir) file in namenode
在$HADOOP_HOME/sbin/hadoop-daemons.sh
(不是$HADOOP_HOME/sbin/hadoop-daemon.sh
,文件名中有s
),有一行叫$HADOOP_HOME/sbin/slaves.sh
。在我的版本(Hadoop v2.7.7)中,它显示为:
exec "$bin/slaves.sh" --config $HADOOP_CONF_DIR cd "$HADOOP_PREFIX" \; "$bin/hadoop-daemon.sh" --config $HADOOP_CONF_DIR "$@"
将行更改为以下行以使其尊重从属端环境变量:
exec "$bin/slaves.sh" "source" ".bash_aliases" \; "hadoop-daemon.sh" "$@"
同样,在$HADOOP_HOME/sbin/yarn-daemons.sh
中,更改行:
exec "$bin/slaves.sh" --config $YARN_CONF_DIR cd "$HADOOP_YARN_HOME" \; "$bin/yarn-daemon.sh" --config $YARN_CONF_DIR "$@"
至
exec "$bin/slaves.sh" "source" ".bash_aliases" \; "yarn-daemon.sh" "$@"
将所有与Hadoop相关的环境变量放入$HOME/.bash_aliases
。
要启动HDFS,只需在主端运行start-dfs.sh
。将启动从属侧数据节点,就像从子侧的交互式shell执行hadoop-daemon.sh start datanode
一样。
要停止HDFS,只需运行stop-dfs.sh
。
上述更改已经完成。但对于完美主义者,您可能还想修复sbin/hadoop-daemons.sh
的调用者,以便在转储它们时命令是正确的。在这种情况下,在Hadoop脚本中查找所有出现的hadoop-daemons.sh
,并将--script "$bin"/hdfs
替换为--script hdfs
(并将所有--script "$bin"/something
替换为--script something
)。在我的情况下,所有出现的都是hdfs
,并且由于从属方将在hdfs
相关时重写命令路径,因此无论是否有此修复,该命令都可以正常工作。
以下是sbin/start-secure-dns.sh
中的示例修复。
更改:
"$HADOOP_PREFIX"/sbin/hadoop-daemons.sh --config $HADOOP_CONF_DIR --script "$bin"/hdfs start datanode $dataStartOpt
至
"$HADOOP_PREFIX"/sbin/hadoop-daemons.sh --config $HADOOP_CONF_DIR --script hdfs start datanode $dataStartOpt
在我的版本(Hadoop v2.7.7)中,需要修复以下文件:
sbin/start-secure-dns.sh
(发生1次)sbin/stop-secure-dns.sh
(发生1次)sbin/start-dfs.sh
(5次出现)sbin/stop-dfs.sh
(5次出现)在sbin/slaves.sh
,通过ssh
连接主人和奴隶的线条如下:
ssh $HADOOP_SSH_OPTS $slave $"${@// /\\ }" \
2>&1 | sed "s/^/$slave: /" &
我在它之前添加了3行来转储变量:
printf 'XXX HADOOP_SSH_OPTS: %s\n' "$HADOOP_SSH_OPTS"
printf 'XXX slave: %s\n' "$slave"
printf 'XXX command: %s\n' $"${@// /\\ }"
在sbin/hadoop-daemons.sh
中,调用sbin/slaves.sh
的行读取(我将其拆分为2行以防止滚动):
exec "$bin/slaves.sh" --config $HADOOP_CONF_DIR cd "$HADOOP_PREFIX" \; \
"$bin/hadoop-daemon.sh" --config $HADOOP_CONF_DIR "$@"
sbin/start-dfs.sh
脚本调用sbin/hadoop-daemons.sh
。这是执行sbin/start-dfs.sh
时的结果:
Starting namenodes on [master]
XXX HADOOP_SSH_OPTS:
XXX slave: master
XXX command: cd
XXX command: /home/hduser/hadoop-2.7.7
XXX command: ;
XXX command: /home/hduser/hadoop-2.7.7/sbin/hadoop-daemon.sh
XXX command: --config
XXX command: /home/hduser/hadoop-2.7.7/etc/hadoop
XXX command: --script
XXX command: /home/hduser/hadoop-2.7.7/sbin/hdfs
XXX command: start
XXX command: namenode
master: starting namenode, logging to /home/hduser/hadoop-2.7.7/logs/hadoop-hduser-namenode-akmacbook.out
XXX HADOOP_SSH_OPTS:
XXX slave: slave1
XXX command: cd
XXX command: /home/hduser/hadoop-2.7.7
XXX command: ;
XXX command: /home/hduser/hadoop-2.7.7/sbin/hadoop-daemon.sh
XXX command: --config
XXX command: /home/hduser/hadoop-2.7.7/etc/hadoop
XXX command: --script
XXX command: /home/hduser/hadoop-2.7.7/sbin/hdfs
XXX command: start
XXX command: datanode
slave1: bash: line 0: cd: /home/hduser/hadoop-2.7.7: Permission denied
slave1: bash: /home/hduser/hadoop-2.7.7/sbin/hadoop-daemon.sh: Permission denied
Starting secondary namenodes [master]
XXX HADOOP_SSH_OPTS:
XXX slave: master
XXX command: cd
XXX command: /home/hduser/hadoop-2.7.7
XXX command: ;
XXX command: /home/hduser/hadoop-2.7.7/sbin/hadoop-daemon.sh
XXX command: --config
XXX command: /home/hduser/hadoop-2.7.7/etc/hadoop
XXX command: --script
XXX command: /home/hduser/hadoop-2.7.7/sbin/hdfs
XXX command: start
XXX command: secondarynamenode
master: starting secondarynamenode, logging to /home/hduser/hadoop-2.7.7/logs/hadoop-hduser-secondarynamenode-akmacbook.out
从上面的结果可以看出,脚本不尊重从属方.bashrc
和etc/hadoop/hadoop-env.sh
。
从上面的结果中,我们知道变量$HADOOP_CONF_DIR
在主端解析。如果在从属端解决问题,将解决该问题。但是,由于ssh
创建的shell(附带命令)是非交互式shell,因此未在从属端加载.bashrc
脚本。因此,以下命令不打印任何内容:
ssh slave1 'echo $HADOOP_HOME'
我们可以强制它加载.bashrc
:
ssh slave1 'source .bashrc; echo $HADOOP_HOME'
但是,.bashrc
中的以下块(Ubuntu 18.04中的默认值)保护非交互式shell:
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
此时,您可以从.bashrc
中移除上述块以尝试实现目标,但我认为这不是一个好主意。我没有尝试过,但我认为警卫是有原因的。
在我的平台上(Ubuntu 18.04),当我以交互方式登录时(通过控制台或ssh),.profile
加载.bashrc
,.bashrc
加载.bash_aliases
。因此,我有一个习惯,保持所有.profile
,.bashrc
,.bash_logout
不变,并将任何自定义放入.bash_aliases
。
如果在您的平台上没有加载.bash_aliases
,请将以下代码附加到.bashrc
:
if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi
回到问题所在。因此我们可以加载.bash_aliases
而不是.bashrc
。因此,以下代码完成了工作,并打印了从属端的$HADOOP_HOME
:
ssh slave1 'source .bash_aliases; echo $HADOOP_HOME'
通过将此技术应用于sbin/hadoop-daemons.sh
脚本,结果是上面提到的简答。