在上例中:hadoop MapReduce辅助排序解析,为了求每年的最大数据使用了mapreduce辅助排序的方法。

本例中介绍利用Avro这个序列化框架的mapreduce功能来实现求取最大值。Avro的优点在这里不做扩展。

1、依赖引入,不使用插件

        <dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>3.2.0</version>
</dependency> <dependency>
<groupId>org.apache.avro</groupId>
<artifactId>avro-mapred</artifactId>
<version>1.8.2</version>
</dependency>

2、定义Avro数据结构,样本依然使用上例的数据样本,只有年份和数据两个字段。

Avro数据结构应该是这样:
{
"type":"record",
"name":"WeatherRecord",
"doc":"A weather reading",
"fields":[
{"name":"year","type":"int"},
{"name":"temperature","type":"int"}
]
}

本例中直接定义为常量,也可以根据需求直接从文件中读入,各有优劣。

public class AvroSchemas {
public static final Schema SCHEMA = new Schema.Parser().parse("{\n" +
"\t\"type\":\"record\",\n" +
"\t\"name\":\"WeatherRecord\",\n" +
"\t\"doc\":\"A weather reading\",\n" +
"\t\"fields\":[\n" +
"\t\t{\"name\":\"year\",\"type\":\"int\"},\n" +
"\t\t{\"name\":\"temperature\",\"type\":\"int\"}\n" +
"\t]\t\n" +
"}"); }

3、mapper

public class AvroMapper extends Mapper<LongWritable,Text,AvroKey<Integer>,AvroValue<GenericRecord>> {
private RecordParser parser = new RecordParser();
private GenericRecord record = new GenericData.Record(AvroSchemas.SCHEMA); @Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
parser.parse(value.toString());
if(parser.isValid()){
record.put("year",parser.getYear());
record.put("temperature",parser.getData());
context.write(new AvroKey<>(parser.getYear()),new AvroValue<>(record));
}
}
}

4、reducer

public class AvroReducer extends Reducer<AvroKey<Integer>,AvroValue<GenericRecord>,AvroKey<GenericRecord>,NullWritable> {

    @Override
protected void reduce(AvroKey<Integer> key, Iterable<AvroValue<GenericRecord>> values, Context context) throws IOException, InterruptedException {
GenericRecord max = null;
for (AvroValue<GenericRecord> value : values){
GenericRecord record = value.datum();
if(max==null ||
(Integer)record.get("temperature") > (Integer) max.get("temperature")){
//必须重新生成GenericRecord,不能直接max=record进行对象引用
//迭代算法为了高效,直接重用了实例
max = newRecord(record);
}
}
context.write(new AvroKey<>(max),NullWritable.get());
} private GenericRecord newRecord(GenericRecord value){
GenericRecord record = new GenericData.Record(AvroSchemas.SCHEMA);
record.put("year",value.get("year"));
record.put("temperature",value.get("temperature")); return record;
}
}

5、job,这里是关键,和普通job所有区别

public class AvroSort extends Configured implements Tool {
/**
* Execute the command with the given arguments.
*
* @param args command specific arguments.
* @return exit code.
* @throws Exception
*/
@Override
public int run(String[] args) throws Exception {
Configuration conf = getConf();
conf.set("mapreduce.job.ubertask.enable","true"); Job job = Job.getInstance(conf,"Avro sort");
job.setJarByClass(AvroSort.class); //通过AvroJob直接设置Avro key和value的输入和输出,而不是使用Job来设置
AvroJob.setMapOutputKeySchema(job, Schema.create(Schema.Type.INT));
AvroJob.setMapOutputValueSchema(job,AvroSchemas.SCHEMA);
AvroJob.setOutputKeySchema(job,AvroSchemas.SCHEMA); job.setMapperClass(AvroMapper.class);
job.setReducerClass(AvroReducer.class); job.setInputFormatClass(TextInputFormat.class);
job.setOutputFormatClass(AvroKeyOutputFormat.class);
//也可以输出文本格式,AvroKey会被转换成json文本模式
// job.setOutputFormatClass(TextOutputFormat.class); FileInputFormat.addInputPath(job,new Path(args[0]));
FileOutputFormat.setOutputPath(job,new Path(args[1])); Path outPath = new Path(args[1]);
FileSystem fileSystem = outPath.getFileSystem(conf);
//删除输出路径
if(fileSystem.exists(outPath))
{
fileSystem.delete(outPath,true);
} return job.waitForCompletion(true) ? 0:1;
} public static void main(String[] args) throws Exception{
int exitCode = ToolRunner.run(new AvroSort(),args);
System.exit(exitCode);
}
}

6、查看Avro文件,需要下载Avro的工具jar包avro-tools-1.8.2.jar,官方镜像链接:https://mirrors.tuna.tsinghua.edu.cn/apache/avro/avro-1.8.2/java/avro-tools-1.8.2.jar

[hadoop@bigdata-senior01 ~]$ java -jar avro-tools-1.8.2.jar tojson part-r-00000.avro
log4j:WARN No appenders could be found for logger (org.apache.hadoop.metrics2.lib.MutableMetricsFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
{"year":1990,"temperature":100}
{"year":1991,"temperature":100}
{"year":1992,"temperature":100}
{"year":1993,"temperature":100}
{"year":1994,"temperature":100}
{"year":1995,"temperature":100}
{"year":1996,"temperature":100}
{"year":1997,"temperature":100}
{"year":1998,"temperature":100}
{"year":1999,"temperature":100}
{"year":2000,"temperature":100}

如果job中,使用的是文本输出,那么直接使用cat就可以查看。

[hadoop@bigdata-senior01 ~]$ hadoop fs -cat /output6/part-r-00000
{"year": 1990, "temperature": 100}
{"year": 1991, "temperature": 100}
{"year": 1992, "temperature": 100}
{"year": 1993, "temperature": 100}
{"year": 1994, "temperature": 100}
{"year": 1995, "temperature": 100}
{"year": 1996, "temperature": 100}
{"year": 1997, "temperature": 100}
{"year": 1998, "temperature": 100}
{"year": 1999, "temperature": 100}
{"year": 2000, "temperature": 100}

hadoop 使用Avro求最大值的更多相关文章

  1. HDU 1754 I Hate It 线段树单点更新求最大值

    题目链接 线段树入门题,线段树单点更新求最大值问题. #include <iostream> #include <cstdio> #include <cmath> ...

  2. HDU 2795 Billboard(区间求最大值的位置update的操作在query里做了)

    Billboard 通过这题,我知道了要活用线段树的思想,而不是拘泥于形式, 就比如这题 显然更新和查询放在一起很简单 但如果分开写 那么我觉得难度会大大增加 [题目链接]Billboard [题目类 ...

  3. c# 任意多个数,求最大值

    c#  任意多个数,求最大值 使用parms: 正在研究中,如果有好的方案,可评论,共同进步,共同提高,谢谢!

  4. 【c语言】求最大值

    一.我个人觉得求最大值比较简单的一种方法(当然同时求最大值和最小值时稍微改改也能行) #include <stdio.h> int main(void) { int f, i, max; ...

  5. zzuli求最大值

    1786: 求最大值 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 134  Solved: 28SubmitStatusWeb Board Desc ...

  6. POJ 3264 Balanced Lineup【线段树区间查询求最大值和最小值】

    Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 53703   Accepted: 25237 ...

  7. js求最大值最小值

    比较数组中数值的大小是比较常见的操作,比较大小的方法有多种,比如可以使用自带的sort()函数,代码如下: <html> <head> <meta charset=&qu ...

  8. java求最大值以及定义方法调用

    class ArrayDome { public static void main(String[] args) { int[] arr = {-12,-51,-12,-11}; int max = ...

  9. 算法笔记_096:蓝桥杯练习 算法提高 求最大值(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 问题描述 给n个有序整数对ai bi,你需要选择一些整数对 使得所有你选定的数的ai+bi的和最大.并且要求你选定的数对的ai之和非负,bi之和非负 ...

随机推荐

  1. apache和IIS共存,服务器对外统一使用80端口

    apache和IIS共用80端口为了PHP与ASP各自的执行效率,要在服务器上安装iis与Apache,但是无法同时使用80端口,否则其中必定有一个启动不了.让它们共存的并且访问网站不需要加端口号,解 ...

  2. 用CRF做命名实体识别(二)

    用CRF做命名实体识别(一) 用CRF做命名实体识别(三) 一. 摘要 本文是对上文用CRF做命名实体识别(一)做一次升级.多添加了5个特征(分别是词性,词语边界,人名,地名,组织名指示词),另外还修 ...

  3. Ajax中post请求和get请求的区别

    首先提出两点Post比Get大的不同地方 1.post请求浏览器每次不会缓存,每次都会重新请求,而get请求不要缓存的时候,需要手动设置 写上xhr.setRequestHeader("If ...

  4. jmeter 函数助手

    1.选项,函数助手对话框,打开函数助手 2.使用方法 输入参数,点击生成,可以直接使用(Name of variable in which to store the result (optional) ...

  5. 【Extremely Basic Words for Listening】word list

    [Extremely Basic Words for Listening]word list updated continuously recite count: 0 careless exercis ...

  6. mysql bin log配置及查看

    mysql执行sql可以通过设置mysql bin 日志进行记录查看   mysql bin日志配置如下:   log_bin:on log_bin_basename:bin文件路径及名前缀(/var ...

  7. 【picker】选择器组件说明

    picker从底部弹起选择器组件 组件细节: 1) 该组件有五种类型,分别是普通选择器.多列选择器.时间选择器.日期选择器.省市区选择器. 2) 组件内必需包裹内容,不然无法弹出选项 <!-- ...

  8. js for循环实例

    1.求1-100的寄数和? //2.奇数求和 var ppt=0 for(var i=1;i<=100;i+=2){ ppt+=i } 2.求1-100的偶数和 var num=0 for(va ...

  9. 十六:The YARN Service Registry

    yarn 服务注册功能是让长期运行的程序注册为服务一直运行. yarn中运行的程序分为两类,一类是短程序,一类一直运行的长程序.第二种也称为服务.yarn服务注册就是让应用程序能把自己注册为服务,如h ...

  10. HDU 4568 Hunter(最短路径+DP)(2013 ACM-ICPC长沙赛区全国邀请赛)

    Problem Description One day, a hunter named James went to a mysterious area to find the treasures. J ...