本人刚刚把Hadoop和Spark的基本原理学习完了,在spark往后学习时,还是需要Hadoop中hive的相关内容,于是开始学习hive。废话不多说,下面进入正题。本文主要介绍的是linux中如何用eclipse开发Hadoop mapreduce与Hive UDF,并且对其中的安装配置进行说明。
一、eclipse开发Hadoop mapreduce程序
1.首先你需要在linux中安装eclipse与Hadoop,这我就不介绍了,有很多博客都介绍了如何安装,你可以去看看并且配置,本文所用的是Hadoop-2.5.2,其安装包已经上传至百度云,百度云链接见我的上篇文章python对Hadoop的hdfs的操作——-pyhdfs或python调用shell文件。
2.当你的Hadoop和eclipse都已经测试成功时,将hadoop-eclipse-plugin-2.5.2.jar放入eclipse/plugins文件夹下,该插件貌似自带版本没有,我这里提供其百度云链接:链接:http://pan.baidu.com/s/1mi40vn6 密码:4xgt 。其结果如下:
3.重新启动eclipse,然后点击“windows“可以看见其中多了“Hadoop Map/Reduce”这一条,并且右侧会有相应的Hadoop路径。
4.按照图中顺序点击,即可看到下图所示内容,点击那个小象配置一个自己Hadoop的相关信息。
5.这里是我已经配置好的,host写自己master主机的IP,端口跟我写的一样就行,其他如图所示即可。
6.配置完成后就可以新建一个mapreduce工程,如图所示:
7.工程新建好了,要将视角切换到MapReduce,如图所示:
同时,还需要查看DFS location里面是否显示出hdfs的文件目录,如果出现,你就可以开始编程了!
8.现在我给出一个我自己的一个mapreduce的编程模板,如下所示:
import java.io.IOException;
import java.util.StringTokenizer;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.KeyValueTextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
public class ModuleMapReduce extends Configured implements Tool {
// step1:Map class
// TODO
public static class ModuleMapper extends
Mapper<LongWritable, Text, Text, IntWritable> {
// private Text mapOutputKey=new Text();
// private final static IntWritable mapOutputValue=new IntWritable(1);
// TODO
@Override
protected void setup(Context context) throws IOException,
InterruptedException {
// Nothing
}
@Override
protected void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
/*
* //line value String lineValue=value.toString();
*
* //split //String[] strs=lineValue.split(" ");
* StringTokenizer stringTokenizer=new StringTokenizer(lineValue);
*
* //iterator while(stringTokenizer.hasMoreTokens()){ //get word
* value String wordValue=stringTokenizer.nextToken(); //set value
* mapOutputKey.set(wordValue); //output context.write(mapOutputKey,
* mapOutputValue); }
*/
// TODO
}
@Override
protected void cleanup(Context context) throws IOException,
InterruptedException {
// Nothing
}
}
// Step2: Reduce Class
/**
*
* @author cjx
*
*/
// TODO
public static class WordCountReducer extends
Reducer<Text, IntWritable, Text, IntWritable> {
// private IntWritable outputValue=new IntWritable();
// TODO
@Override
protected void setup(Context context) throws IOException,
InterruptedException {
// Nothing
}
@Override
protected void reduce(Text key, Iterable<IntWritable> values,
Context context) throws IOException, InterruptedException {
/*
* //sum tmp int sum=0; //iterator for(IntWritable value:values){
* //total sum+=value.get();
*
* } //set value outputValue.set(sum); //output context.write(key,
* outputValue);
*/
// TODO
}
@Override
protected void cleanup(Context context) throws IOException,
InterruptedException {
// Nothing;
}
}
// step 3 : Dirver,component job
public int run(String[] args) throws Exception {
// 1: get configuration
Configuration configuration = getConf();
// 2:create Job
Job job = Job.getInstance(configuration, this.getClass()
.getSimpleName());
// run jar
job.setJarByClass(this.getClass());
//set InputFormat
//job.setInputFormatClass(KeyValueTextInputFormat.class);
// 3:set job
// input -> map -> reduce -> output
// 3.1:input
Path inPath = new Path(args[0]);
FileInputFormat.addInputPath(job, inPath);
// 3.2: map
job.setMapperClass(ModuleMapper.class);
// TODO
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class);
// **********************************Shuffle**************************************
// 1)partitioner
// job.setPartitionerClass(cls);
// 1)sort
// job.setSortComparatorClass(cls);
// 2)optional,combiner
// job.setCombinerClass(cls);
// 3)group
// job.setGroupingComparatorClass(cls);
// **********************************Shuffle**************************************
// 3.3: reduce
job.setReducerClass(WordCountReducer.class);
// TODO
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
// set reduce number
// job.setNumReduceTasks(2);
// 3.4:output
Path outPath = new Path(args[1]);
FileOutputFormat.setOutputPath(job, outPath);
// 4: submit job
Boolean isSuccess = job.waitForCompletion(true);
return isSuccess ? 0 : 1;
}
public static void main(String[] args) throws Exception {
// 1: get configuration
Configuration configuration = new Configuration();
// set compress
// configuration.set("mapreduce.map.output.compress", "true");
// configuration.set("mapreduce.map.output.compress.codec", "cls");
//set reduceNum defautNum=1
//configuration.set("mapreduce.job.reduces");
// TODO Auto-generated method stub
// int status=new WordCountMapReduce().run(args);
int status = ToolRunner.run(configuration, new ModuleMapReduce(), args);
System.exit(status);
}
}
9.mapreduce程序的运行有2种方式,一种是导出所编写的mapreduce的jar包,然后通过Hadoop的shell命令进行运行(主流)
Hadoop安装目录下运行下面的命令:
bin/yarn jar 对应的jar包的路径 hdfs中输入路径 hdfs中输出路径(输出路径必须不存在)
另一种是直接通过eclipse运行(新手),通过eclipse运行时,需要配置好参数。点击“Run As”->“Run Configurations”:
然后出现如下画面,在argument里面填写输入的文件目录,以及输出的目录,这里主要输出目录必须不存在。(另外提一下,我的eclipse直接上传文件会出现文件内容为空,所以最好通过shell命令上传文件):
最后点击运行即可在hdfs中查看输出的文件结果。
二、eclipse开发Hive UDF程序
由于hive是基于mapreduce和hdfs之上的对大型数据库进行查询的一个数据仓库,hive处理的往往是oracle、SQL等数据库无法处理的数据问题。hive中内置了很多函数供hive开发人员使用,但是往往不足以满意hive开发人员的所有需要,于是我们hive开发人员需要自己自定义相关的函数来满足我们查询数据库的需求,这就要求我们必须掌握使用eclipse去开发 hive UDF程序。当然,开发的前提,需要你安装了,hive,Hadoop,eclipse,MySQL等软件,下面我开发介绍如何开发UDF程序:
1.我们新建一个mapreduce的程序(反正我新建java程序后面运行的时候会出错),然后在该项目导入hive的2个jar包(hive-exec-0.13.1.jar和hive-jdbc-0.13.1.jar),如下图所示:
2.然后编写一个类继承UDF这个类,并且实现evaluate()方法。该方法重载都行,必须要返回一个值,可返回null,声明不可为void。其实例代码如下:
package lowerCharUDF;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;
public class lowerCharUDF extends UDF{
public Text evaluate(Text str)
{
//validate
if(null==str.toString()) return null;
//lower
return new Text(str.toString().toLowerCase());
}
public static void main(String[] args) {
System.out.println(new lowerCharUDF().evaluate(new Text("ASDD")));
}
}
这里的main方法只是用于测试自己写的方法是否实现,实际开发中可删除。
3.导出自己编写的程序的jar包,在hive中运行如下命令即可:
add jar /a/b(导出jar包的路径)
create temporary function lowerCharUDF as "lowerCharUDF.lowerCharUDF";(最后一个参数是自己的包名+类名)
show functions; (查看自己定义的function是否添加进来)
select ename,lowerCharUDF(ename) lowerCharUDF from emp limit 5;(运行自己定义的函数)
下面是mapreduce进行计算并显示结果:
Total jobs = 1
Launching Job 1 out of 1
Number of reduce tasks is set to 0 since there's no reduce operator
Starting Job = job_1503110193206_0001, Tracking URL = http://master:18088/proxy/application_1503110193206_0001/
Kill Command = /home/cjx/hadoop-2.5.2/bin/hadoop job -kill job_1503110193206_0001
Hadoop job information for Stage-1: number of mappers: 1; number of reducers: 0
2017-08-19 10:47:23,014 Stage-1 map = 0%, reduce = 0%
2017-08-19 10:48:02,714 Stage-1 map = 100%, reduce = 0%, Cumulative CPU 7.08 sec
MapReduce Total cumulative CPU time: 7 seconds 80 msec
Ended Job = job_1503110193206_0001
MapReduce Jobs Launched:
Job 0: Map: 1 Cumulative CPU: 7.08 sec HDFS Read: 860 HDFS Write: 60 SUCCESS
Total MapReduce CPU Time Spent: 7 seconds 80 msec
OK
ename lowercharudf
SMITH smith
ALLEN allen
WARN warn
JONES jones
MARTIN martin
Time taken: 117.339 seconds, Fetched: 5 row(s)
好了,linux中用eclipse开发Hadoop mapreduce与Hive UDF实例详解及其配置说明讲完了,本人只是将自己学习的经验总结下来,希望可以帮助有需要的人,当然其中可能不全,欢迎大家补充!