在上例中: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. springboot与activemq的使用

    1.springboot和activemq的使用相对来说比较方便了,我在网上看了很多其他的资料,但是自己写出来总是有点问题所以,这里重点描述一下遇到的一些问题. 2.至于activemq的搭建和spr ...

  2. Android 模拟器 下载、编译及调试

    Android 模拟器源码下载 Android 模拟器源码的下载与 Android AOSP 源码库的下载过程类似,可以参考 Google 官方提供的 Android 源码下载文档 来了解这个过程. ...

  3. “网易有钱”sketch使用分享

    本文来自网易云社区 写在开头,关于ps与sketch之间的优劣网上已经有很多分享,大家有兴趣可以百度,其中对否我们在这里不予评价.在移动互联网时代每个app从几十到上百张页面,如果用ps绘制一个个页面 ...

  4. 无法嵌入互操作类型“ADOX.CatalogClass”。请改用适用的接口。

    编译环境:vs2013 系统报错:无法嵌入互操作类型"ADOX.CatalogClass".请改用适用的接口. 解决方法:选中项目中引入的dll(本例中为Microsoft ADO ...

  5. OSG-基础知识-程序框架

    本文转至http://www.cnblogs.com/shapherd/archive/2010/08/10/osg.html 作者写的比较好,再次收藏,希望更多的人可以看到这个文章 互联网是是一个相 ...

  6. Selenium(Python)生成Html测试报告

    由于Python3已经不支持HTMLTestRunner了, 无论是PyCharm还是pip都无法安装成功, 所以只能去 http://tungwaiyip.info/software/HTMLTes ...

  7. Windowserver2012部署always on

    1.首先,安装域环境 IP设置 域服务安装 如果建立域配置时出现 administrator账户密码不符合要求错误: cmd运行命令: net user administrator /password ...

  8. Java开发工程师(Web方向) - 04.Spring框架 - 第4章.数据访问

    第4章--数据访问 Spring JDBC DAO (Data Access Object) 实现数据访问相关接口(接口和实现分离) ORM (Object Relation Mapping) 对象关 ...

  9. js设计模式:工厂模式、构造函数模式、原型模式、混合模式

    一.js面向对象程序 var o1 = new Object();     o1.name = "宾宾";     o1.sex = "男";     o1.a ...

  10. leetcode-反转链表

      转载至:https://blog.csdn.net/fx677588/article/details/72357389 反转一个单链表.   示例: 输入: 1->2->3->4 ...