hadoop学习笔记--找到执行hadoop的入口
参与个hadoop项目,之前没搞过,赶紧学习:
照葫芦画瓢,得到代码是hdfs2local.sh脚本和LiaoNingFilter.jar包,迫不及待用jd-gui打开jar包,搜索到main(在MANIFEST.MF中没有找到main,只能search,其实在hdfs2local.sh脚本中写明了main所在的package)。
package cn.com.dtmobile.hadoop.biz.LiaoNingFilter.job; import cn.com.dtmobile.hadoop.biz.LiaoNingFilter.mr.DataMap;
import cn.com.dtmobile.hadoop.biz.LiaoNingFilter.mr.DataReduce;
import java.net.URI;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.filecache.DistributedCache;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.compress.CompressionCodec;
import org.apache.hadoop.io.compress.GzipCodec;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.MultipleOutputs;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner; public class DataJob
extends Configured
implements Tool
{
public int run(String[] args)
throws Exception
{
Configuration conf = getConf();
conf.setBoolean("mapred.output.compress", true);
conf.setClass("mapred.output.compression.codec", GzipCodec.class, CompressionCodec.class); String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs(); String sysHour = otherArgs[10]; DistributedCache.addCacheFile(new URI(otherArgs[9]), conf);
Job job = new Job(conf, "LiaoNingFilter");
job.getConfiguration().setStrings("sys_hour", new String[] { sysHour });
job.setJarByClass(DataJob.class);
job.setMapperClass(DataMap.class);
job.setReducerClass(DataReduce.class);
job.setNumReduceTasks(100); job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(Text.class); job.setOutputKeyClass(NullWritable.class);
job.setOutputValueClass(Text.class); MultipleOutputs.addNamedOutput(job, "volterx", TextOutputFormat.class, NullWritable.class, Text.class); MultipleOutputs.addNamedOutput(job, "s1mmeorgn", TextOutputFormat.class, NullWritable.class, Text.class); MultipleOutputs.addNamedOutput(job, "voltesv", TextOutputFormat.class, NullWritable.class, Text.class); MultipleOutputs.addNamedOutput(job, "sgsorgn", TextOutputFormat.class, NullWritable.class, Text.class); MultipleOutputs.addNamedOutput(job, "s1uhttporgn", TextOutputFormat.class, NullWritable.class, Text.class); MultipleOutputs.addNamedOutput(job, "volteorgn", TextOutputFormat.class, NullWritable.class, Text.class); MultipleOutputs.addNamedOutput(job, "sharevolterx", TextOutputFormat.class, NullWritable.class, Text.class); MultipleOutputs.addNamedOutput(job, "shares1mme", TextOutputFormat.class, NullWritable.class, Text.class); MultipleOutputs.addNamedOutput(job, "sharehttp", TextOutputFormat.class, NullWritable.class, Text.class); MultipleOutputs.addNamedOutput(job, "sharevolteorgn", TextOutputFormat.class, NullWritable.class, Text.class); MultipleOutputs.addNamedOutput(job, "voltemossession", TextOutputFormat.class, NullWritable.class, Text.class); MultipleOutputs.addNamedOutput(job, "voltemosslice", TextOutputFormat.class, NullWritable.class, Text.class); FileInputFormat.addInputPath(job, new Path(otherArgs[0])); FileInputFormat.addInputPath(job, new Path(otherArgs[1])); FileInputFormat.addInputPath(job, new Path(otherArgs[2])); FileInputFormat.addInputPath(job, new Path(otherArgs[3])); FileInputFormat.addInputPath(job, new Path(otherArgs[4])); FileInputFormat.addInputPath(job, new Path(otherArgs[5])); FileInputFormat.addInputPath(job, new Path(otherArgs[6])); FileInputFormat.addInputPath(job, new Path(otherArgs[7])); FileOutputFormat.setOutputPath(job, new Path(otherArgs[8])); return job.waitForCompletion(true) ? 0 : 1;
} public static void main(String[] args)
throws Exception
{
try
{
int returnCode = ToolRunner.run(new DataJob(), args);
System.exit(returnCode);
}
catch (Exception e)
{
e.printStackTrace();
}
}
class DataJob76~92行:
这是传递参数给hadoop,但args到底是什么,otherArgs从run(String[] args)来的,run(String[] args)从main(String[] args)来的,main(String[] args)需要回到调用jar包的hdfs2local.sh脚本中找:
#!/bin/bash
#
export HADOOP_CONF_DIR=/etc/hadoop/conf #ANALY_DATE=
#ANALY_HOUR=
ANALY_DATE=`date +%Y%m%d`
ANALY_HOUR="`date -d ' -1 hour' +%H`"
CUR_DATE=`date +%Y%m%d`
CUR_HOUR="`date +%H`"
#CUR_DATE=
#CUR_HOUR=
if [ $CUR_HOUR = ]
then
ANALY_DATE="`date -d ' -1 day' +%Y%m%d`"
else
ANALY_DATE=$CUR_DATE
fi
mypath="$(cd "$(dirname "$0")"; pwd)"
cd $mypath
#SOURCE_SVR="hdfs://nameservice1:8020/datang"
SOURCE_SVR="hdfs://nameservice1:8020/ws/detail" JAR_PACKAGK="/cup/d6/datang/bin/LiaoNingFilter.jar"
JAR_MAIN="cn.com.dtmobile.hadoop.biz.LiaoNingFilter.job.DataJob" HIVE_TABLES="s1mme_orgn sgs_orgn volte_rx volte_sv s1u_http_orgn volte_mos_session volte_mos_slice" GX=${SOURCE_SVR}/volte_rx/p1_day=${ANALY_DATE}/*${ANALY_DATE}${ANALY_HOUR}*.ok1
S1=${SOURCE_SVR}/s1mme_orgn/p1_day=${ANALY_DATE}/*${ANALY_DATE}${ANALY_HOUR}*.txt
SV=${SOURCE_SVR}/volte_sv/p1_day=${ANALY_DATE}/*${ANALY_DATE}${ANALY_HOUR}*.ok1
SGS=${SOURCE_SVR}/sgs_orgn/p1_day=${ANALY_DATE}/*${ANALY_DATE}${ANALY_HOUR}*.ok1
MW=${SOURCE_SVR}/volte_sip/p1_day=${ANALY_DATE}/*${ANALY_DATE}${ANALY_HOUR}*.ok1
HTTP=${SOURCE_SVR}/s1u_http_orgn/p1_day=${ANALY_DATE}/*${ANALY_DATE}${ANALY_HOUR}*.txt
SESSION=${SOURCE_SVR}/volte_mos_session/p1_day=${ANALY_DATE}/*${ANALY_DATE}${ANALY_HOUR}*.ok1
SLICE=${SOURCE_SVR}/volte_mos_slice/p1_day=${ANALY_DATE}/*${ANALY_DATE}${ANALY_HOUR}*.ok1
OUTPUT=/datang/FILTER/${ANALY_DATE}${ANALY_HOUR}
NODATA=/datang/nodata
hdfs dfs -test -e ${GX}
if [ $? -ne 0 ];then
GX=${NODATA}
fi
hdfs dfs -test -e ${S1}
if [ $? -ne 0 ];then
S1=${NODATA}
fi
hdfs dfs -test -e ${SV}
if [ $? -ne 0 ];then
SV=${NODATA}
fi
hdfs dfs -test -e ${SGS}
if [ $? -ne 0 ]; then
SGS=${NODATA}
fi
hdfs dfs -test -e ${MW}
if [ $? -ne 0 ]; then
MW=${NODATA}
fi
hdfs dfs -test -e ${HTTP}
if [ $? -ne 0 ]; then
HTTP=${NODATA}
fi
hdfs dfs -test -e ${SESSION}
if [ $? -ne 0 ];then
SESSION=${NODATA}
fi
hdfs dfs -test -e ${SLICE}
if [ $? -ne 0 ];then
SLICE=${NODATA}
fi T_PROCESS=/datang/t_process/t_process.csv
echo "`date '+/%y/%m/%d %H:%M:%S'` INFO begni,exit..."
HADOOP=`which hadoop`
#${HADOOP} fs -rm -R ${OUTPUT}
${HADOOP} jar ${JAR_PACKAGK} ${JAR_MAIN} \
${GX} \
${S1} \
${SV} \
${SGS} \
${MW} \
${HTTP} \
${SESSION} \
${SLICE} \
${OUTPUT} \
${T_PROCESS} \
${ANALY_HOUR} #exit TEMP_DIR=/cup/d6/datang/TEMP
echo "get data begin!------------------------------------------" for tableName in ${HIVE_TABLES}
do file_name=`echo ${tableName}|sed 's/_//g'` rm -rf ${TEMP_DIR}/${tableName}/$ANALY_DATE/$ANALY_HOUR/*
mkdir -p ${TEMP_DIR}/${tableName}/$ANALY_DATE/$ANALY_HOUR hdfs dfs -get ${OUTPUT}/${file_name}* ${TEMP_DIR}/${tableName}/$ANALY_DATE/$ANALY_HOUR/
echo "hdfs dfs -get ${OUTPUT}/${file_name}* ${TEMP_DIR}/${tableName}/$ANALY_DATE/$ANALY_HOUR/"
done orgn=volteorgn
rm -rf $TEMP_DIR/volte_orgn/$ANALY_DATE/$ANALY_HOUR/*
mkdir -p ${TEMP_DIR}/volte_orgn/$ANALY_DATE/$ANALY_HOUR
hdfs dfs -get ${OUTPUT}/${orgn}* ${TEMP_DIR}/volte_orgn/$ANALY_DATE/$ANALY_HOUR
rm -rf $TEMP_DIR/share_volte_orgn/$ANALY_DATE/$ANALY_HOUR/*
mkdir -p ${TEMP_DIR}/share_volte_orgn/$ANALY_DATE/$ANALY_HOUR
hdfs dfs -get ${OUTPUT}/sharevolteorgn* ${TEMP_DIR}/share_volte_orgn/$ANALY_DATE/$ANALY_HOUR rm -rf $TEMP_DIR/share_s1mme/$ANALY_DATE/$ANALY_HOUR/*
mkdir -p ${TEMP_DIR}/share_s1mme/$ANALY_DATE/$ANALY_HOUR
hdfs dfs -get ${OUTPUT}/shares1mme* ${TEMP_DIR}/share_s1mme/$ANALY_DATE/$ANALY_HOUR rm -rf $TEMP_DIR/share_volterx/$ANALY_DATE/$ANALY_HOUR/*
mkdir -p ${TEMP_DIR}/share_volterx/$ANALY_DATE/$ANALY_HOUR
hdfs dfs -get ${OUTPUT}/sharevolterx* ${TEMP_DIR}/share_volterx/$ANALY_DATE/$ANALY_HOUR DEL_HOUR="`date -d ' -6 hour' +%H`"
if [ $ANALY_HOUR = 00 ]
then
ANALY_DATE="`date -d ' -1 day' +%Y%m%d`"
elif [ $ANALY_HOUR = 01 ]; then
ANALY_DATE="`date -d ' -1 day' +%Y%m%d`"
elif [ $ANALY_HOUR = 02 ]; then
ANALY_DATE="`date -d ' -1 day' +%Y%m%d`"
elif [ $ANALY_HOUR = 03 ]; then
ANALY_DATE="`date -d ' -1 day' +%Y%m%d`"
elif [ $ANALY_HOUR = 04 ]; then
ANALY_DATE="`date -d ' -1 day' +%Y%m%d`"
elif [ $ANALY_HOUR = 23 ]; then
ANALY_DATE="`date -d ' -1 day' +%Y%m%d`"
else
ANALY_DATE=$1
fi
hdfs dfs -rm -R -skipTrash /datang/FILTER/${ANALY_DATE}${DEL_HOUR}
echo "get data end!------------------------------------------"
echo "`date '+/%y/%m/%d %H:%M:%S'` INFO done ,exit..."
exit
hdfs2local.sh脚本76~87行:
这是hadoop命令调用jar包的命令,格式为:
jar
运行jar文件。用户可以把他们的Map Reduce代码捆绑到jar文件中,使用这个命令执行。
用法:hadoop jar <jar> [mainClass] args...
http://hadoop.apache.org/docs/r1.0.4/cn/commands_manual.html
问题来了,取到的参数是哪些?
${HADOOP} jar ${JAR_PACKAGK} ${JAR_MAIN} \ ${GX} \ ${S1} \ ${SV} \ ${SGS} \ ${MW} \ ${HTTP} \ ${SESSION} \ ${SLICE} \ ${OUTPUT} \ ${T_PROCESS} \ ${ANALY_HOUR}
按理说${HADOOP} jar后面的都是参数,但是数量与class DataJob76~92行的参数数量对不上,问题出在哪?分析GenericOptionsParser类有蹊跷:
34 String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
找到官方文档:http://hadoop.apache.org/docs/r1.0.4/api/org/apache/hadoop/util/GenericOptionsParser.html
String[] |
getRemainingArgs() Returns an array of Strings containing only application-specific arguments. |
还需要说明的是,hadoop的参数分两类:通用参数和命令参数
bin/hadoop command [genericOptions] [commandOptions] 通用参数是:
常规选项
下面的选项被 dfsadmin, fs, fsck和 job支持。 应用程序要实现 Tool来支持 常规选项。
GENERIC_OPTION | 描述 |
---|---|
-conf <configuration file> | 指定应用程序的配置文件。 |
-D <property=value> | 为指定property指定值value。 |
-fs <local|namenode:port> | 指定namenode。 |
-jt <local|jobtracker:port> | 指定job tracker。只适用于job。 |
-files <逗号分隔的文件列表> | 指定要拷贝到map reduce集群的文件的逗号分隔的列表。 只适用于job。 |
-libjars <逗号分隔的jar列表> | 指定要包含到classpath中的jar文件的逗号分隔的列表。 只适用于job。 |
-archives <逗号分隔的archive列表> | 指定要被解压到计算节点上的档案文件的逗号分割的列表。 只适用于job。 |
除了generic options 通用参数以外的,都是命令的参数(或者叫application-specific arguments命令专属参数) 所以执行代码String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs()后,otherArgs 中剔除了${JAR_PACKAGK} ${JAR_MAIN},只保留剩余的参数:
${GX} \ ${S1} \ ${SV} \ ${SGS} \ ${MW} \ ${HTTP} \ ${SESSION} \ ${SLICE} \ ${OUTPUT} \ ${T_PROCESS} \ ${ANALY_HOUR} 这就与class DataJob76~92行对应上了。 相关参考材料:
Hadoop 常见指令
https://blog.csdn.net/u011414200/article/details/50465433
MapReduce处理输出多文件格式(MultipleOutputs)
https://blog.csdn.net/shujuboke/article/details/77199840
Hadoop系列之ToolRunner与GenericOptionsParser用法
https://blog.csdn.net/u011734144/article/details/60769745
Class GenericOptionsParser
http://hadoop.apache.org/docs/r1.0.4/api/org/apache/hadoop/util/GenericOptionsParser.html
Hadoop 0.18 命令手册
http://hadoop.apache.org/docs/r1.0.4/cn/commands_manual.html
hadoop学习笔记--找到执行hadoop的入口的更多相关文章
- Hadoop学习笔记(1) 初识Hadoop
1. Hadoop提供了一个可靠的共享存储和分析系统.HDFS实现存储,而MapReduce实现分析处理,这两部分是Hadoop的核心. 2. MapReduce是一个批量查询处理器,并且它能够在合理 ...
- Hadoop学习笔记之一:Hadoop IPC
因为某些原因需要把前一段时间对Hadoop(版本基于0.20.2)的学习积累搬到这里,成为一个系列.写得会很简单,只为必要时给自己提醒. IPC框架 所有Hadoop协议接口的实现都依赖Hadoop ...
- Hadoop学习笔记(9) ——源码初窥
Hadoop学习笔记(9) ——源码初窥 之前我们把Hadoop算是入了门,下载的源码,写了HelloWorld,简要分析了其编程要点,然后也编了个较复杂的示例.接下来其实就有两条路可走了,一条是继续 ...
- Hadoop学习笔记—22.Hadoop2.x环境搭建与配置
自从2015年花了2个多月时间把Hadoop1.x的学习教程学习了一遍,对Hadoop这个神奇的小象有了一个初步的了解,还对每次学习的内容进行了总结,也形成了我的一个博文系列<Hadoop学习笔 ...
- Hadoop学习笔记(5) ——编写HelloWorld(2)
Hadoop学习笔记(5) ——编写HelloWorld(2) 前面我们写了一个Hadoop程序,并让它跑起来了.但想想不对啊,Hadoop不是有两块功能么,DFS和MapReduce.没错,上一节我 ...
- Hadoop学习笔记(3)——分布式环境搭建
Hadoop学习笔记(3) ——分布式环境搭建 前面,我们已经在单机上把Hadoop运行起来了,但我们知道Hadoop支持分布式的,而它的优点就是在分布上突出的,所以我们得搭个环境模拟一下. 在这里, ...
- Hadoop学习笔记(1) ——菜鸟入门
Hadoop学习笔记(1) ——菜鸟入门 Hadoop是什么?先问一下百度吧: [百度百科]一个分布式系统基础架构,由Apache基金会所开发.用户可以在不了解分布式底层细节的情况下,开发分布式程序. ...
- Hadoop学习笔记(1)(转)
Hadoop学习笔记(1) ——菜鸟入门 Hadoop是什么?先问一下百度吧: [百度百科]一个分布式系统基础架构,由Apache基金会所开发.用户可以在不了解分布式底层细节的情况下,开发分布式程序. ...
- Hadoop学习笔记(10) ——搭建源码学习环境
Hadoop学习笔记(10) ——搭建源码学习环境 上一章中,我们对整个hadoop的目录及源码目录有了一个初步的了解,接下来计划深入学习一下这头神象作品了.但是看代码用什么,难不成gedit?,单步 ...
随机推荐
- Docker设置http代理
在国内由于不可描述的原因无法访问Google等网站,但是作为一枚挨踢人士,无法使用Google搜索,在使用Ctrl + C技能时是抓狂的:特别是当下Docker.Kubernetes等容器技术火热的时 ...
- iOS URL Cache文章推荐 (待完成)
推荐链接是:http://www.cnblogs.com/Mike-zh/archive/2016/02/24/5210169.html http://blog.csdn.net/y550918116 ...
- linux安装selenium+chrome+phantomjs
1. 安装 selenium pip3 install selenium pip3 安装参考 2. 安装 ChromeDriver yum install chromedriver.x86_64 3. ...
- RabbitMQ可靠性投递及高可用集群
可靠性投递: 首先需要明确,效率与可靠性是无法兼得的,如果要保证每一个环节都成功,势必会对消息的收发效率造成影响.如果是一些业务实时一致性要求不是特别高的场合,可以牺牲一些可靠性来换取效率. 要保证消 ...
- 利用Graphviz绘制逻辑关系依赖图
说明:在很多情况下,需要将复杂且有些规律的代码整理成逻辑片段,这个时候就需要画图,很多时候图比代码更加直观 Graphviz是一个比较好的绘图工具,可以通过简单的代码绘制出复杂的逻辑图,且其代码就像平 ...
- Valgrind与内存问题
1 简介 "Valgrind是一款用于内存调试.内存泄漏检测以及性能分析的软件开发工具.Valgrind这个名字取自北欧神话中英灵殿的入口. Valgrind的最初作者是Julian Sew ...
- 【转】Oracle imp 总是不停地重复闪烁
http://blog.itpub.net/7282477/viewspace-1003160/ 在dos下执行: imp username/password buffer=1000000 file= ...
- MySQL通过Navicat实现远程连接的过程
直接使用Navicat通过IP连接会报各种错误,例如:Error 1130: Host '192.168.1.80' is not allowed to connect to this MySQL ...
- 关于jmeter读取CSV文件的详细设置
jmeter 读取excel数据使用的方法是使用Jmeter CSV Data Set Config参数化 但是将excel文件保存成csv格式后,jmeter读取后返回的数据总是出现乱码问题, 以下 ...
- 项目之初的模型设计与status状态字段
0X01 开始做一个app的时候,要先做的是流程设计与数据库模型设计. 但做的模型设计往往是设置字段满足当前的需求,缺乏足够的经验,即使为以后的功能预留出位置,也无法考虑周全. 比如,刚开始做用户表, ...