如何手动启动Hadoop


2009-11-20 11:06


From地址为:http://hi.baidu.com/woodyzhou/blog/item/3cab4139cfa7072497ddd8c1.html

 


Hadoop Cluster的启动可以说十分简单,最简单的一种方法就是运行$HADOOP_HOME/bin/start-all.sh,我也相信绝大多数的人都是这么启动的。但是这个脚本里面到底做了些什么呢?让我们来抽丝剥茧的看一看:



注:不失一般性,我们这里以dfs的启动为例子,mapred的启动道理是一样的。
Dfs 的启动脚本实际上是$HADOOP_HOME/bin/start-dfs.sh,start-all.sh也正是通过调用这个脚本来达到启动整个 HDFS的目的。start-dfs.sh会按顺序启动namenode, datanode(s)和secondnamenode,我在这里将一一说明:

1. 启动NameNode
【start- dfs.sh】:对于start-dfs.sh来说启动NameNode仅仅就是调用hadoop-daemon.sh [...] start namenode [...]。([]内为省略的参数。)start表示启动namenode,同理stop表示关闭namenode。namenode告诉hadoop- daemon.sh他将启动的是那种类型的节点。
【hadoop-daemon.sh】:hadoop-daemon.sh的工作相对 start-dfs.sh复杂一点。他虽然接受两个参数,但实际关心的仅仅只是start/stop这一个。他会更具start或stop采取不同的措 施。我们此处仅关心start的过程。在hadoop- daemon.sh发现动作参数是start以后,它会调用hadoop [...] namenode [...]同时把该脚本的output内容导向一个日志文件(位于$HADOOP_HOME/logs下的文件就是这么来的)。
【hadoop】:hadoop 脚本是真正办事情的人,就是它启动了namenode。实际上所有的Hadoop的做事的节 点:namenode,datanode,secondnamenode,jobtracker,tasttracker都是hadoop脚本启动的—— 这是后话。hadoop脚本会根据namenode决定相应的java main class(org.apache.hadoop.hdfs.server.namenode.NameNode)然后初始化classpath,最后调 用java命令启动namenode。
【最终的java命令】: java -Xmx1000m -Dhadoop.log.dir=[$HADOOP_HOME]/logs -Dhadoop.home.dir=[$HADOOP_HOME] -classpath [$HADOOP_HOME/conf+$HADOOP_HOME/hadoop-*-core.jar+$HADOOP_HOME/lib下的所有 jar] org.apache.hadoop.hdfs.server.namenode.NameNode

2.启动DataNode(s)
【start- dfs.sh】:start-dfs.sh启动datanode的时候调用的是hadoop-daemons.sh [...] start datanode [...]。被调用的脚本名字变成的复数,奇迹上它做的事情也是hadoop-daemon.sh的n次(n由datanode的个数决定)。
【hadoop-daemons.sh】:这个脚本只是把请求传递给slaves.sh,当然同时传递一组命令,这组命令的具体用途在slaves.sh中说明。
【slaves.sh】:slaves.sh脚本会根据 $HADOOP_HOME/conf/slaves的文件的内容,通过ssh向每个slave发送 hadoop-daemons.sh传入的命令。命令很简单:1.cd到 $HADOOP_HOME;2.调用 hadoop-daemon.sh start datanode,现在一切又都和启动namenode的时候相同了。
【hadoop-daemon.sh】:调用hadoop [...] datanode [...]
【hadoop】:找到java main class(org.apache.hadoop.hdfs.server.datanode.DataNode)运行java命令
【最终的java命令】: java -Xmx1000m -Dhadoop.log.dir=[$HADOOP_HOME]/logs -Dhadoop.home.dir=[$HADOOP_HOME] -classpath [$HADOOP_HOME/conf+$HADOOP_HOME/hadoop-*-core.jar+$HADOOP_HOME/lib下的所有 jar] org.apache.hadoop.hdfs.server.datanode.DataNode

3.启动SecondNameNode
SecondNameNode没有任何复杂的,类似于启动DataNodes,区别就是脚本将根据 $HADOOP_HOME/conf/masters文件内的地址启动SecondNameNode。
【最终的java命令】: java -Xmx1000m -Dhadoop.log.dir=[$HADOOP_HOME]/logs -Dhadoop.home.dir=[$HADOOP_HOME] -classpath [$HADOOP_HOME/conf+$HADOOP_HOME/hadoop-*-core.jar+$HADOOP_HOME/lib下的所有 jar] org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode

到这里整个start-dfs.sh就分析完了。可以看出最终脚本都是执行了一个java命令,起动了一个java程序。实际上,你完全可以自己到各个节点上手工敲入上面的java命令启动所有节点。最终的结果都是一样的。

其 实这篇文档在大多数人看来也是毫无意义的,脚本能做到的事情为什么要手工做呢?的确如此,绝大多数情况下这么做绝对是多余的。我到现在也没遇到过“真的 ”需要我这么做的情况。为什么“真的”要打上引号呢?因为我曾经企图将Hadoop移植到SUN的Project Caroline上,而后者却是一个只能执行java命令的云环境。所以我才会有上述需求。虽然最后失败了!(其实HDFS的移植算是成功的,但是由于mapred部分必须需要调用系统脚本,所以不得不放弃)