hadoop 使用Avro求最大值
在上例中: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求最大值的更多相关文章
- HDU 1754 I Hate It 线段树单点更新求最大值
题目链接 线段树入门题,线段树单点更新求最大值问题. #include <iostream> #include <cstdio> #include <cmath> ...
- HDU 2795 Billboard(区间求最大值的位置update的操作在query里做了)
Billboard 通过这题,我知道了要活用线段树的思想,而不是拘泥于形式, 就比如这题 显然更新和查询放在一起很简单 但如果分开写 那么我觉得难度会大大增加 [题目链接]Billboard [题目类 ...
- c# 任意多个数,求最大值
c# 任意多个数,求最大值 使用parms: 正在研究中,如果有好的方案,可评论,共同进步,共同提高,谢谢!
- 【c语言】求最大值
一.我个人觉得求最大值比较简单的一种方法(当然同时求最大值和最小值时稍微改改也能行) #include <stdio.h> int main(void) { int f, i, max; ...
- zzuli求最大值
1786: 求最大值 Time Limit: 1 Sec Memory Limit: 128 MB Submit: 134 Solved: 28SubmitStatusWeb Board Desc ...
- POJ 3264 Balanced Lineup【线段树区间查询求最大值和最小值】
Balanced Lineup Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 53703 Accepted: 25237 ...
- js求最大值最小值
比较数组中数值的大小是比较常见的操作,比较大小的方法有多种,比如可以使用自带的sort()函数,代码如下: <html> <head> <meta charset=&qu ...
- java求最大值以及定义方法调用
class ArrayDome { public static void main(String[] args) { int[] arr = {-12,-51,-12,-11}; int max = ...
- 算法笔记_096:蓝桥杯练习 算法提高 求最大值(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 给n个有序整数对ai bi,你需要选择一些整数对 使得所有你选定的数的ai+bi的和最大.并且要求你选定的数对的ai之和非负,bi之和非负 ...
随机推荐
- 天津市人民优步Uber司机奖励政策(9月14日~9月20日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- Linux tcpdump命令详解(分享文章)
简介 用简单的话来定义tcpdump,就是:dump the traffic on a network,根据使用者的定义对网络上的数据包进行截获的包分析工具. tcpdump可以将网络中传送的数据包的 ...
- Android 9 Pie震撼来袭 同步登陆WeTest
WeTest 导读 2018年8月7日,Google对外发布最新 Android 9.0 正式版系统,并宣布系统版本Android P 被正式命名为代号“Pie”,最新系统已经正式推送包括谷歌Pixe ...
- Python零基础入门必知
Python自学知识点总结 //2018.10.09 1. Python(英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/), 是一种面向对象的解释型计算机程序设计语言,由荷兰人Guido ...
- JAVA基础学习之路(五)数组的定义及使用
什么是数组:就是一堆相同类型的数据放一堆(一组相关变量的集合) 定义语法: 1.声明并开辟数组 数据类型 数组名[] = new 数据类型[长度]: 2.分布完成 声明数组:数据类型 数组名 [] = ...
- OpenMPI 集群配置
现在有2台机器,希望可以尝试一下在多台机器上跑MPI的感觉,所以跑之前就得配置,先参考网址: https://www.cnblogs.com/awy-blog/p/3402949.html: 1. 配 ...
- jstat命令
jstat命令使用 jstat命令可以查看堆内存各部分的使用量,以及加载类的数量.命令的格式如下: jstat [-命令选项] [vmid] [间隔时间/毫秒] [查询次数] 注意:使用的jdk版本是 ...
- 查看python中包的文档
核心命令:python -m pydoc 查询某包:python -m pydoc 包名 示例: C:\Users\xxx>python -m pydoc pydoc - the Python ...
- win32绘制自定义类窗口导致绘制11个窗口的解决办法
上网查了一圈也没有找到解决问题的办法,一旦创建了一个窗口,并且在过程函数中绘制窗口,尤其是一些非子窗口的自定义类窗口,都会生成11个窗口(算上主窗口就是12个),但是使用系统通用控件就不会有这种情况的 ...
- 面试应该get这三大技能
链接:https://www.nowcoder.com/discuss/84391?type=0&order=3&pos=16&page=0 一.自我介绍凸显学业背景中的隐含信 ...