HDFS相关脚本介绍
简介
本篇主要介绍hdfs整个系统的脚本部分,通过脚本来介绍hdfs文件系统的启动、停止等操作;该篇是基于hadoop-2.6.2的版本进行说明。hdfs的脚本主要位于三个地方,其中$HADOOP_HOME/sbin放置了一些应用层面相关的脚本,如start-dfs.sh等系统的启动、停止脚本,$HADOOP_HOME/bin下面的脚本主要为上层的应用脚本抽象出来的一层命令,$HADOOP_HOME/libexec下面是一些环境变量的脚本信息;另外$HADOOP_HOME/etc/hadoop下存储了应用相关的一些配置信息,包括core-site.xml、slave文件等节点或者服务配置文件,另外还有hadoop-env.sh,定义了一些启动环境变量,包括namenode等服务启动的JVM参数,日志级别等配置,用户可以修改此处的配置来定义自己的服务的启动参数,也可以在起初增加自己的配置,如可以指定HADOOP_SSH_OPTS来指定ssh连接的参数;指定HADOOP_PREFIX变量指定当前的HADOOP的工作目录等等
功能
Hdfs通过脚本为系统提供了很多命令行,如hdfs dfsadmin提供了管理命令,用户可以通过这些命令来查看系统的运行情况、管理文件、升级等操作;所有的这些命令均是通过调用脚本来完成相应的功能(最终是通过执行相关的java类的main函数),因此了解这些脚本的内容显得尤为重要,接下来会先介绍一些主要的脚本内容,然后会通过系统的启动和停止过程来说明各个脚本之间的调用关系。
Sbin目录
主要介绍start-dfs.sh,其他脚本和该脚本类似,该脚本主要是启动hdfs,同时也能完成hdfs的的升级和回滚操作,脚本中要是是根据启动参数或者配置文件中的信息来启动相应的服务,如namenode、datanode、journalnode等。下面仅仅列出了Namenode的部分脚本,最终是通过hadoop-daemons.sh来完成相应的操作。
#执行$HADOP_HOME/libexec/hadoop-config.sh,初始化一些环境信息,包括HADOOP的位置信息、classpath、hadoop启动信息
.$HADOOP_LIBEXEC_DIR/hdfs-config.sh
#获取etc/hadoop下面配置文件中的namenode的配置,即fs.defaultFS的值
NAMENODES=$($HADOOP_PREFIX/bin/hdfsgetconf -namenodes)
echo "Startingnamenodes on [$NAMENODES]"
"$HADOOP_PREFIX/sbin/hadoop-daemons.sh"\
--config "$HADOOP_CONF_DIR" \
--hostnames "$NAMENODES" \
--script "$bin/hdfs" start namenode$nameStartOpt
hadoop-daemons.sh脚本
exec"$bin/slaves.sh" --config $HADOOP_CONF_DIR cd"$HADOOP_PREFIX" \; "$bin/hadoop-daemon.sh" --config$HADOOP_CONF_DIR "$@"
其中\;是对分号的转义,默认情况下“;”用来在一行下执行多个命令(前面的失败了,后面的依然会执行,和&&命令不一样)
if ["$HADOOP_SLAVE_NAMES" != '' ] ; then
SLAVE_NAMES=$HADOOP_SLAVE_NAMES
else
SLAVE_FILE=${HADOOP_SLAVES:-${HADOOP_CONF_DIR}/slaves}
#获取主机配置文件中的主机列表,去除掉注释行和空行,可以通过指定IFS来通过空格分隔每一行host,通过unset IFS来恢复
SLAVE_NAMES=$(cat "$SLAVE_FILE" |sed 's/#.*$//;/^$/d')
fi
# start the daemons
for slave in $SLAVE_NAMES ;do
#对空格进行转移
ssh $HADOOP_SSH_OPTS $slave $"${@// /\\}" \
2>&1 | sed "s/^/$slave: /"&
if [ "$HADOOP_SLAVE_SLEEP" !="" ]; then
sleep $HADOOP_SLAVE_SLEEP
fi
done
Slaves.sh脚本
上层脚本调用通过--hosts指定要启动脚本的主机列表文件或者通过—hostnames直接指定主机列表,如启动namenode主要通过hostnames参数指定,而datanode主要通过hosts参数来指定主机文件,默认是etc/hadoop下面的slave文件
从上面的脚本可以看出,slaves.sh就是通过ssh命令连接需要执行命令的主机列表,最终执行hadoop-daemons.sh中的cd"$HADOOP_PREFIX" \; "$bin/hadoop-daemon.sh" --config$HADOOP_CONF_DIR "$@",其中--config$HADOOP_CONF_DIR在hadoop-config.sh中被转换完了HADOOP_SLAVE_NAMES变量。
hadoop-daemon.sh
通过上述的脚本的调用关系,最终会执行脚本hadoop-daemon.sh,命令的格式为
hadoop-daemon.sh [--config<conf-dir>] [--hosts hostlistfile] [--script script] (start|stop)<hadoop-command> <args...>
script表示要执行的脚本的绝对路径,如果启动的是hdfs的服务节点时,会忽略掉此参数,该参数主要是为了用户自定义的命令提供扩展
hadoop-command为namenode、datanode、journalnode等
启动过程的部分脚本,其中保存PID的文件路径可以通过HADOOP_PID_DIR参数指定,默认是安装目录的pids目录下
case $command in
namenode|secondarynamenode|datanode|journalnode|dfs|dfsadmin|fsck|balancer|zkfc)
if [ -z "$HADOOP_HDFS_HOME"]; then
hdfsScript="$HADOOP_PREFIX"/bin/hdfs
else
hdfsScript="$HADOOP_HDFS_HOME"/bin/hdfs
fi
nohup nice -n $HADOOP_NICENESS$hdfsScript --config $HADOOP_CONF_DIR $command "$@" >"$log" 2>&1 < /dev/null &
;;
(*)
nohup nice -n $HADOOP_NICENESS$hadoopScript --config $HADOOP_CONF_DIR $command "$@" >"$log" 2>&1 < /dev/null &
;;
esac
echo $! > $pid
sleep 1
停止阶段的部分脚本
if [ -f $pid ]; then
TARGET_PID=`cat $pid`
if kill -0 $TARGET_PID > /dev/null2>&1; then
echo stopping $command
kill $TARGET_PID
sleep $HADOOP_STOP_TIMEOUT
if kill -0 $TARGET_PID > /dev/null2>&1; then
echo "$command did not stopgracefully after $HADOOP_STOP_TIMEOUT seconds: killing with kill -9"
kill -9 $TARGET_PID
fi
else
echo no $command to stop
fi
rm -f $pid
else
echo no $command to stop
fi
;;
可以看出,hdfs相关服务的停止显示通过kill来进行终止,通过HADOOP_STOP_TIMEOUT来指定停止的周期,如果超过这个时间未停止,默认是5s再通过kill -9来终止。
Bin目录
Bin目录下的文件主要是基于hadoop本身的一些原生命令,主要是根据具体的命令字转换为调用java启动相应的函数,完成相应的操作请求处理。主要的文件截图如下:
Hdfs脚本
…
if [ "$COMMAND" ="namenode" ] ; then
CLASS='org.apache.hadoop.hdfs.server.namenode.NameNode'
HADOOP_OPTS="$HADOOP_OPTS$HADOOP_NAMENODE_OPTS"
elif [ "$COMMAND"= "journalnode" ] ; then
CLASS='org.apache.hadoop.hdfs.qjournal.server.JournalNode'
HADOOP_OPTS="$HADOOP_OPTS$HADOOP_JOURNALNODE_OPTS"
elif [ "$COMMAND"= "dfs" ] ; then
CLASS=org.apache.hadoop.fs.FsShell
HADOOP_OPTS="$HADOOP_OPTS$HADOOP_CLIENT_OPTS"
elif [ "$COMMAND"= "version" ] ; then
CLASS=org.apache.hadoop.util.VersionInfo
else
CLASS="$COMMAND"
fi
exec "$JAVA" -Dproc_$COMMAND$JAVA_HEAP_MAX $HADOOP_OPTS $CLASS "$@"
Hdfs脚本主要流程如下
1. 根据命令字匹配到相应的类路径
2. 设置相应的启动的classpath
3. Java启动相应得而进程
根据上述的脚本,可以自定义自己的command,其中命令字为全类名,启动类型为start,---script为hdfs脚本的路径
Hadoop脚本
function print_usage(){
echo "Usage: hadoop [--config confdir]COMMAND"
echo " where COMMAND is one of:"
echo " fs run a genericfilesystem user client"
echo " version print the version"
echo " jar <jar> run ajar file"
echo " checknative [-a|-h] check nativehadoop and compression libraries availability"
echo " distcp <srcurl> <desturl> copy file or directoriesrecursively"
echo " archive -archiveName NAME -p <parent path> <src>*<dest> create a hadoop archive"
echo " classpath prints theclass path needed to get the"
echo " credential interact withcredential providers"
echo " Hadoop jar and therequired libraries"
echo " daemonlog get/set thelog level for each daemon"
echo " trace view andmodify Hadoop tracing settings"
echo " or"
echo " CLASSNAME run the classnamed CLASSNAME"
echo ""
echo "Most commands print help wheninvoked w/o parameters."
}
if [ $# = 0 ]; then
print_usage
exit
fi
如果调用hadoop中的命令是属于hdfs的相关操作,则调用hdfs脚本来执行,其他的话也是和hdfs的逻辑一样,根据命令字查找具体的java实现类,启动java进程执行相应的逻辑操作。