`
twtbgn
  • 浏览: 44076 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

hadoop dfs 启动过程

阅读更多

今天来看下hadoop dfs 的启动过程都做了些什么。

启动hdfs的时候,一般都是使用命令./start-dfs.sh,那就从这个sh文件入手:

"$bin"/hadoop-daemon.sh --config $HADOOP_CONF_DIR start namenode $nameStartOpt
"$bin"/hadoop-daemons.sh --config $HADOOP_CONF_DIR start datanode $dataStartOpt
"$bin"/hadoop-daemons.sh --config $HADOOP_CONF_DIR --hosts masters start secondarynamenode

 在脚本的最后调用了这3命令,分别是启动namenode,datanode和secondarynamenode。

接着看hadoop-daemon.sh脚本:

case $startStop in
  (start)
    mkdir -p "$HADOOP_PID_DIR"
    if [ -f $pid ]; then
      if kill -0 `cat $pid` > /dev/null 2>&1; then
        echo $command running as process `cat $pid`.  Stop it first.
        exit 1
      fi
    fi

    if [ "$HADOOP_MASTER" != "" ]; then
      echo rsync from $HADOOP_MASTER
      rsync -a -e ssh --delete --exclude=.svn --exclude='logs/*' --exclude='contrib/hod/logs/*' $HADOOP_MASTER/ "$HADOOP_HOME"
    fi

    hadoop_rotate_log $log
    echo starting $command, logging to $log
    cd "$HADOOP_PREFIX"
    //关键的在这里,又去调用hadoop这个脚本	
    nohup nice -n $HADOOP_NICENESS "$HADOOP_PREFIX"/bin/hadoop --config $HADOOP_CONF_DIR $command "$@" > "$log" 2>&1 < /dev/null &
    echo $! > $pid
    sleep 1; head "$log"
    ;;

 看到上面的代码,发现这里有执行了hadoop这个脚本,执行了命令hadoop --config configfile namenode,接着看hadoop的脚本吧:

elif [ "$COMMAND" = "namenode" ] ; then
  CLASS='org.apache.hadoop.hdfs.server.namenode.NameNode'
  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_NAMENODE_OPTS"

 终于找到了启动namenode所调用的类了,同样的流程,也可以找到datanode,secondarynamenode的启动类。

接着看NameNode类:

在注释中看到:

 * The NameNode controls two critical tables:
 *   1)  filename->blocksequence (namespace)
 *   2)  block->machinelist ("inodes")

namenode维护了2个关键表,一个是文件和块序列的对应关系,一个是块和datanode对象关系,就是保存了一个文件对应了哪些块,一个块存储在哪些机器上。

首先通过main方法

public static void main(String argv[]) throws Exception {
    try {
      StringUtils.startupShutdownMessage(NameNode.class, argv, LOG);
      NameNode namenode = createNameNode(argv, null);
      if (namenode != null)
        namenode.join();
    } catch (Throwable e) {
      LOG.error(StringUtils.stringifyException(e));
      System.exit(-1);
    }
  }

 调用createNameNode方法创建namenode,该方法中通过NameNode namenode = new NameNode(conf)来创建,再看看构造方法中调用了 initialize(conf),截取initialize方法中一些主要的内容:

.............
this.namesystem = new FSNamesystem(this, conf);
.............

 FSNamesystem才是用来保存有节点信息的,包括:

   1)  valid fsname --> blocklist  (kept on disk, logged)
 * 2)  Set of all valid blocks (inverted #1)
 * 3)  block --> machinelist (kept in memory, rebuilt dynamically from reports)
 * 4)  machine --> blocklist (inverted #2)
 * 5)  LRU cache of updated-heartbeat machines

 

加载fsimge,edits,启动监听进程接收datanode的信息,启动rpc底层通信服务,namenode的启动主要就是做的这些事情,可以看到主要工作在加载fsimage,和接收datanode的信息。如果fsimage比较大的话,那么启动过程会较慢,同样,如果集群比较大,那么接收datanode的block信息同样也是非常耗时的地方。

关于加载fsimge和datanode的rpc通信下一次在分析吧。

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics