`
逸情公子
  • 浏览: 899511 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

Hadoop的shell脚本分析

 
阅读更多

                                                                     Hadoop的shell脚本分析
前记:
这些天一直学习hadoop,学习中也遇到了许多的问题,主要是对hadoop的shell脚本和hadoop的源码概念不够清楚,所以我就对hadoop的bin目录下的shell脚本进行了研究,有一些成果想记录下来,也希望大家前来批评指正。

分析原因:

很多hadoop的初学者对hadoop的脚本不是很清楚,不知道为什么可以在命令行中启动hadoop,也不知道为什么有时在命令行中运行hadoop命令时会出现java的错误。等等这些问题,究其原因我认为是大家对shell脚本不太了解。我曾学过一些shell编程的知识,可是对hadoop的shell程序细节还不是全部了解,我想从宏观上分析一下hadoop脚本的运行流程。

脚本分析:

start-all.sh:

# Start all hadoop daemons.  Run this on master node.

bin=`dirname "$0"`
bin=`cd "$bin"; pwd`

. "$bin"/hadoop-config.sh

# start dfs daemons
"$bin"/start-dfs.sh --config $HADOOP_CONF_DIR

# start mapred daemons
"$bin"/start-mapred.sh --config $HADOOP_CONF_DIR

 

分析:
正如注释的一样,这个脚本是在master上运行的,即我们运行namenode和jobtracker的主机。它首先启动了hadoop-config.sh脚本,查看hadoop-config.sh,我们可以知道它的作用是对一些变量进行赋值,这些变量有HADOOP_HOME(hadoop的安装目录),HADOOP_CONF_DIR(hadoop的配置文件目录),HADOOP_SLAVES(--hosts指定的文件的地址),为了让大家更好地理解,下面贴出hadoop-config.sh的部分代码

 

#check to see it is specified whether to use the slaves or the
# masters file
if [ $# -gt 1 ]
then
    if [ "--hosts" = "$1" ]
    then
        shift
        slavesfile=$1
        shift
        export HADOOP_SLAVES="${HADOOP_CONF_DIR}/$slavesfile"
    fi

 

前面的注释意思是:判断是使用slaves文件,还是master文件,这里为什么要判断呢?那我们带着疑问接着分析下去吧。然后start-all.sh根据hadoop/conf目录下的配置信息启动了start-dfs.sh和start-mapred.sh两个脚本,下面我们去看看这两个脚本又做了些什么吧。

start-dfs.sh:

# Start hadoop dfs daemons.
# Optinally upgrade or rollback dfs state.
# Run this on master node.

usage="Usage: start-dfs.sh [-upgrade|-rollback]"

bin=`dirname "$0"`
bin=`cd "$bin"; pwd`

. "$bin"/hadoop-config.sh

# get arguments
if [ $# -ge 1 ]; then
	nameStartOpt=$1
	shift
	case $nameStartOpt in
	  (-upgrade)
	  	;;
	  (-rollback) 
	  	dataStartOpt=$nameStartOpt
	  	;;
	  (*)
		  echo $usage
		  exit 1
	    ;;
	esac
fi

# start dfs daemons
# start namenode after datanodes, to minimize time namenode is up w/o data
# note: datanodes will log connection errors until namenode starts
"$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

 

分析:
根据前面的注释信息,我们发现这个脚本用于启动集群的DFS,我们知道DFS由namenode,datanode,secondarynamenode组成,所以在脚本的最后它又启动了3个进程,分别根据配置文件启动了namenode,datanode,secondarynamenode。其实这个时候你应该已经知道start-mapred.sh干了什么事了。


start-mapred.sh:

# Start hadoop map reduce daemons.  Run this on master node.

bin=`dirname "$0"`
bin=`cd "$bin"; pwd`

. "$bin"/hadoop-config.sh

# start mapred daemons
# start jobtracker first to minimize connection errors at startup
"$bin"/hadoop-daemon.sh --config $HADOOP_CONF_DIR start jobtracker
"$bin"/hadoop-daemons.sh --config $HADOOP_CONF_DIR start tasktracker

 

分析:
正如你所想,它的作用用于启动mapreduce,所以它的最后同样根据配置文件启动了jobtracker和tasktracker,呵呵,现在发现其实脚本干的事没有想象的那么难了吧。如果你对shell代码看得仔细一点,你会发现hadoop-daemon.sh脚本用于启动namenode和jobtracker,而hadoop-daemons.sh脚本用于启动datanode,secondarynamenode和tasktracker。也就是说hadoop-daemon.sh用于启动master上的进程,而hadoop-daemons.sh用于启动slaves和secondarynamenode主机上的进程(这里考虑的是slaves,secondarynamenode和master配置在了不同主机上的情况)。如果我们分析一下它们俩的代码,你会发现其实它们是有联系的。


hadoop-daemons.sh:

# Run a Hadoop command on all slave hosts.

usage="Usage: hadoop-daemons.sh [--config confdir] [--hosts hostlistfile] [start|stop] command args..."

# if no args specified, show usage
if [ $# -le 1 ]; then
  echo $usage
  exit 1
fi

bin=`dirname "$0"`
bin=`cd "$bin"; pwd`

. $bin/hadoop-config.sh

exec "$bin/slaves.sh" --config $HADOOP_CONF_DIR cd "$HADOOP_HOME" \; "$bin/hadoop-daemon.sh" --config $HADOOP_CONF_DIR "$@"

 

分析:
看到程序倒数第二行开头的那个exec关键字了吗?它执行了slaves.sh和hadoop-daemon.sh两个脚本,并且把hadoop-daemons.sh命令的参数也传入了hadoop-daemon.sh。呵呵,现在你知道这两个脚本的关系了吧,其实hadoop-daemons.sh中调用了hadoop-daemon.sh,但在调用之前它先执行了slaves.sh脚本,现在你想看看slaves.sh干了啥吗?呵呵,我们也来分析一下吧。


slaves.sh:

if [ "$HOSTLIST" = "" ]; then
  if [ "$HADOOP_SLAVES" = "" ]; then
    export HOSTLIST="${HADOOP_CONF_DIR}/slaves"
  else
    export HOSTLIST="${HADOOP_SLAVES}"
  fi
fi

for slave in `cat "$HOSTLIST"|sed  "s/#.*$//;/^$/d"`; do
 ssh $HADOOP_SSH_OPTS $slave $"${@// /\\ }" \
   2>&1 | sed "s/^/$slave: /" &
 if [ "$HADOOP_SLAVE_SLEEP" != "" ]; then
   sleep $HADOOP_SLAVE_SLEEP
 fi
done

 

分析:
由于篇幅问题,以上只贴出了slaves.sh的关键代码,对于启动slaves来说,代码中的HOSTLIST变量是slaves配置文件的地址。再往后看,你会看到非常醒目的一个关键字:ssh,其实这个时候你应该明白了,slave.sh脚本的作用就是通过ssh远程登录到每个在slaves中配置的主机上。所以hadoop-daemons.sh的功能就是先远程登录slaves,在slaves上运行hadoop-daemon.sh脚本。如果你思考的再多一点,那又是怎么启动secondarynamenode的呢?难道也是先远程登录到slaves中配置的主机上吗?答案一定是否定的。而是先远程登录到master中配置的主机上,然后再启动hadoop-daemon.sh脚本,如果你仔细一点,可以看到start-dfs.sh脚本的最后一行命令是启动secondarynamenode,命令传入了“--hosts master”这就指定了按照master中配置的主机来启动secondarynamenode。Hadoop-config.sh负责对“--hosts master”进行解析。

下面你是不是对hadoop-daemon.sh脚本又产生了兴趣了呢?那我们一起来分析吧。


hadoop-daemon.sh:

usage="Usage: hadoop-daemon.sh [--config <conf-dir>] [--hosts hostlistfile] (start|stop) <hadoop-command> <args...>"


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_HOME"
    nohup nice -n $HADOOP_NICENESS "$HADOOP_HOME"/bin/hadoop --config $HADOOP_CONF_DIR $command "$@" > "$log" 2>&1 < /dev/null &
    echo $! > $pid
    sleep 1; head "$log"
    ;;
          
  (stop)

    if [ -f $pid ]; then
      if kill -0 `cat $pid` > /dev/null 2>&1; then
        echo stopping $command
        kill `cat $pid`
      else
        echo no $command to stop
      fi
    else
      echo no $command to stop
    fi
    ;;

  (*)
    echo $usage
    exit 1
    ;;

esac

 

分析:
以上是hadoop-daemon.sh的关键代码,用于判断执行该脚本时是启动(start)一个进程,还是停止(stop)一个进程。执行该脚本的方式可以查看代码上方的usage变量值(注:[]括起来的表示可有可无,|表示或者,<>括起来表示参数)。这里的<command>参数可以是start或者stop。<command>后面的参数你知道可以是哪些吗?呵呵,其实可以是namenode,jobtracker,secondarynamenode,datanode,tasktracker,如果你在master上自己用hadoop-daemon.sh启动datanode和tasktracker就会有问题,因为hadoop-daemon.sh没有远程登录到slaves主机上哦。执行的结果会在master上启动一个datanode或tasktracker进程,而不是按照slaves配置文件在每个slave上启动datanode和tasktracker哦。

分析了以上这些脚本之后,我想还有一些脚本,比如说:start-balancer.sh,start-jobhistoryserver.sh就不需要分析了吧。不过看了这些脚本之后,我们发现脚本都是一个执行另一个脚本,到最后都是执行了hadoop-daemon.sh。以启动(start)为例,那hadoop-daemon.sh脚本又是怎么来启动那么多的进程的呢?我们又要回到hadoop-daemon.sh的代码了,之前我们看到hadoop-daemon.sh的一段关键代码是用于判断“启动”还是“停止”进程的,在shell中停止一个进程很方便,用kill命令就可以了,但是该脚本是怎么启动进程的呢?我们继续分析脚本中(start)后面的代码,如果你仔细一点,可以发现其实有这样一段代码:

 

"$HADOOP_HOME"/bin/hadoop --config $HADOOP_CONF_DIR $command "$@" > "$log" 2>&1 < /dev/null &
 

分析:
现在你明白我想要说明什么问题了吗,呵呵,其实hadoop-daemon.sh启动进程也是执行了其它的脚本,它就是hadoop/bin/hadoop。其实说到这里hadoop脚本的秘密就快浮出水面了。你还记得博客开头我们提出的问题吗?为什么有时在命令行执行hadoop命令时会出现java的错误信息呢,秘密就在这个hadoop/bin/hadoop脚本里。下面我们来看一下hadoop的核心脚本吧


hadoop:

片段一:
cygwin=false
case "`uname`" in
CYGWIN*) cygwin=true;;
esac

片段二:
# for developers, add Hadoop classes to CLASSPATH
if [ -d "$HADOOP_HOME/build/classes" ]; then
  CLASSPATH=${CLASSPATH}:$HADOOP_HOME/build/classes
fi
if [ -d "$HADOOP_HOME/build/webapps" ]; then
  CLASSPATH=${CLASSPATH}:$HADOOP_HOME/build
fi
if [ -d "$HADOOP_HOME/build/test/classes" ]; then
  CLASSPATH=${CLASSPATH}:$HADOOP_HOME/build/test/classes
fi
if [ -d "$HADOOP_HOME/build/tools" ]; then
  CLASSPATH=${CLASSPATH}:$HADOOP_HOME/build/tools
fi


片段三:

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

片段四:
 exec "$JAVA" -Dproc_$COMMAND $JAVA_HEAP_MAX $HADOOP_OPTS -classpath "$CLASSPATH" $CLASS "$@"
 

分析:
由于篇幅原因,我只贴出了hadoop脚本具有代表价值的四段代码。下面我们一个个来分析吧

片段一:
我们知道在window操作系统上可以通过安装cygwin软件来模拟linux系统环境,这段代码就是用于判断我们的hadoop命令是运行在linux环境上,还是模拟的linux环境上,因为两种情况下文件的路径不相同,hadoop脚本为了区分这两种情况,做出了判断。

片段二:
这些操作是将一些目录的路径自动地加到环境变量(CLASSPATH)中。

片段三:
其实这个片段才是精华,它根据COMMAND的值给CLASS指定一个对应的java类,

片段四:
呵呵,根据CLASS的值,脚本执行了该java类哦,如果你看了hadoop的源码,你会发现,这些类里都有main方法。


小结:
分析到这里,hadoop的shell脚本就全部分析完毕了。如果有不同想法的,希望可以一起交流。

3
1
分享到:
评论
6 楼 avatar_2009 2015-01-28  
daemon.sh 和daemons.sh分析错了。。前者启动单节点,后者启动集群
5 楼 逸情公子 2012-06-14  
引用
PS: 用apache上的Hadoop在Cygwin安装简直是悲剧,总是各种问题出现。改完这个,下一个就出现了,所以既然人家都说了Windows下适用于开发环境,Linux下适用于生产环境,还不如自己用VMWare搭建虚拟机跑跑呢。

我是装的Windows和Linux双系统,没有在虚拟机中弄。
4 楼 diyunpeng 2012-06-13  
写的很好,我觉得现在1.X版本第一大家都没怎么碰原因就是碰的人少,遇见问题解决的少。所以采用0.20.X还是不错的。

另外楼主分析的不错,有问题在像您请教。

PS: 用apache上的Hadoop在Cygwin安装简直是悲剧,总是各种问题出现。改完这个,下一个就出现了,所以既然人家都说了Windows下适用于开发环境,Linux下适用于生产环境,还不如自己用VMWare搭建虚拟机跑跑呢。
3 楼 逸情公子 2012-04-25  
引用
为什么还用 hadoop_0.2 的版本,现在已经有hadoop-1.0.2.tar.gz,版本了,lz的文章也是2月份也写的,新版本应该也出了吧。

当时我们主要考虑了两个因素:第一个是0.20.203版本在官方文档上说是比较稳定的版本,第二个原因是:当时在网上看到的相关资料大多是在0.···版本下搞的,因为当时是初学hadoop,所以就没用1.···版本了;不同版本的配置信息可能稍有差别,不过应该差别不是太大吧~
2 楼 逸情公子 2012-04-25  
引用
lz 有没有试过在window 上安装 cygwin

在windows上我也安装了cygwin,它可以模拟linux的环境,当时我想既然要搞hadoop,还是正规地在linux下搞吧,也没想太多,就选择了linux
1 楼 li269015 2012-04-22  
lz 分析的很好哦,最近也在研究这个,它里面有很多类都是带有main方法的。看了lz的另一遍在window 下安装 linux, lz 有没有试过在window 上安装 cygwin ,是一个模拟linux 的环境,最近在网上看了很多,还是没有把hadoop 在cygwin中运行起来,总有一些报错,问下lz, 为什么还用 hadoop_0.2 的版本,现在已经有hadoop-1.0.2.tar.gz,版本了,lz的文章也是2月份也写的,新版本应该也出了吧。

相关推荐

    hadoop 部分 shell 脚本

    在Hadoop生态系统中,Shell脚本扮演着至关重要的角色,特别是在大数据处理和集群管理中。这些脚本通常用于自动化任务,如数据迁移、作业调度、集群监控等。下面我们将深入探讨Hadoop Shell脚本的相关知识点。 一、...

    shell脚本配置Hadoop伪分布式.zip

    在这个"shell脚本配置Hadoop伪分布式.zip"压缩包中,包含了配置Hadoop伪分布式环境所需的所有资源和指南。伪分布式模式是在单个节点上模拟分布式环境,这对于学习和测试Hadoop功能非常有用,无需复杂的多节点集群...

    hadoop环境部署自动化shell脚本(伪分布式、完全分布式集群搭建).docx

    【Hadoop环境部署自动化Shell脚本】是一种高效的方法,用于快速搭建Hadoop集群,无论是用于学习还是开发。本文档提供了一个详细的脚本,涵盖了从Java环境配置到Hadoop集群的完全分布式安装的所有步骤,旨在降低...

    hadoop shell操作与程式开发

    3. **Hadoop Shell脚本**:通过编写bash脚本,可以自动化执行一系列HDFS操作,提高工作效率。 4. **MapReduce编程**:理解MapReduce的工作原理,包括Mapper和Reducer阶段,以及Combiner和Partitioner的角色。学习...

    hadoop集群关机重启shell脚本

    hadoop集群关机重启shell脚本

    shell脚本-大数据

    shell脚本是Linux或Unix操作系统中的一种命令解释器,用于执行一系列的命令、任务自动化和数据处理,特别适合在大数据场景下进行数据预处理、分析和调度。 首先,让我们深入理解shell脚本如何应用于大数据处理。在...

    Hadoop高可用自动化安装使用Shell脚本

    接下来,我们来分析Shell脚本在Hadoop HA安装中的作用。Shell脚本是一种强大的自动化工具,可以用来执行一系列命令,如配置、安装、启动等操作。在Hadoop集群中,一个完善的自动化脚本可以大大简化安装过程,减少...

    大数据中Hadoop Shell介绍

    ### 大数据中Hadoop Shell介绍 ...总之,Hadoop Shell及其相关的脚本为Hadoop的部署、管理和日常维护提供了强大的支持。熟练掌握这些工具的使用方法,对于任何从事大数据处理工作的工程师来说都是必不可少的技能。

    基于Hadoop的ETL处理Shell架构

    通过Hadoop的API或命令行工具,Shell脚本可以启动MapReduce作业,进一步处理数据,例如进行聚合、分类、关联分析等。 此外,Shell脚本还可以实现流程控制,如循环、条件判断,使得ETL过程更加灵活。通过编写脚本,...

    shell脚本完成hadoop的集群安装

    #shell脚本完成hadoop的集群安装 #步骤: #1.安装虚拟机,关闭防火墙、selinux #2.ssh免密码,编辑hosts文件 #3.安装JDK #4.安装hadoop #5.修改配置文件 #6.分发hadoop程序到各个节点 #7.启动集群

    傻瓜式Hadoop集群配置脚本

    利用shell脚本 对Hadoop环境进行傻瓜式配置 先解压! 环节包括: 1.修改hostname 2.修改hosts 3.配置免密 4.Hadoop配置文件的更改 !!!!!!!!!!!!!!!!!!!! ps 请特别注意以下几个问题: 1....

    hadoop-shell(第四章)-带书签高清pdf文字版

    5. **Hadoop Shell脚本编写** - 如何编写使用Hadoop命令的bash脚本,以实现自动化数据处理任务,如批量处理文件、数据清洗等。 - `for`循环和条件判断在Shell脚本中的应用,以及如何结合其他Unix工具如`awk`、`sed...

    shell脚本一键安装zookeeper3.4.5

    在IT行业中,shell脚本是一种常用的自动化工具,用于在Linux或Unix系统中执行一系列命令。在本案例中,"shell脚本一键安装zookeeper3.4.5"指的是使用一个自定义的shell脚本来简化Apache ZooKeeper 3.4.5的安装过程。...

    hadoop hive 半自动安装脚本(初识shell脚本)

    为hive-0.11半自动安装脚本 使用前请先阅读本脚本注释部分 已有hadoop环境可使用本脚本 因为初识shell脚本 望大虾勿喷 如有不吝赐教者 不胜感激

    基于Hadoop的ETL处理Shell架构5

    本篇将详细介绍如何利用Shell脚本在Hadoop环境中实现ETL过程。 1. **Hadoop基础** Hadoop是Apache软件基金会开发的开源分布式计算框架,基于Java语言。其核心组件包括HDFS(Hadoop Distributed File System)和...

    hadoop脚本

    安装hadoop时,集群式安装需要来回的切换机器,那么还有每一步都需要配置文件,很繁琐,所以就在这写了一个脚本

    shell脚本--bigdata.sh

    大数据集群管理脚本

    cdh及其组件安装的shell脚本集合

    【标题】"CDH及其组件安装的Shell脚本集合"主要涵盖了在Linux环境中部署和管理Cloudera's Distribution Including Apache Hadoop (CDH) 的一系列自动化脚本。这些脚本旨在简化CDH组件的安装、配置和维护过程,提高...

    用shell脚本实现hadoop多用户配置

    这个shell脚本是在业余时间写的,从一开始不懂shell,到写出这个程序还是经过了一段时间的,收取小小1分希望得到大家的鼓励 :) 。程序的解释和hadoop多用户配置的步骤也都可以在博客中找到:)

    hadoop集群配置ssh免登录shell脚本

    本篇将详细讲解如何配置Hadoop集群的SSH免登录,并介绍提供的shell脚本`hadoop_ssh_auto_login.sh`以及辅助文件`ip_hosts.txt`的用途。 首先,理解SSH免登录的基本原理。SSH免登录依赖于公钥认证机制,即在每台主机...

Global site tag (gtag.js) - Google Analytics