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之和非负 ...
随机推荐
- DATA 转 16 进制
// 转 16进制 编码 NSData *data = [NSData dataWithBytes:(const void *)dataOut length:(NSUInteger)dataOutMo ...
- GDAL中GDALDataset::RasterIO分块读取的实现
GDALDataset类中的RasterIO函数能够对图像任意指定区域.任意波段的数据按指定数据类型.指定排列方式读入内存和写入文件中,因此可以实现对大影像的分块读.写运算操作.针对特大的影像图像,有 ...
- 笔记:ndk-stack和addr2line
笔记:关于ndk开发调试时,获取崩溃堆栈方法 1. 使用ndk-stack 直接获取c/c++崩溃代码的文件名和行号 adb shell logcat | ndk-stack -sym $PROJEC ...
- MySQL高级-索引优化
索引失效 1. 2.最佳左前缀法则 4. 8. 使用覆盖索引解决这个问题. 二.索引优化 1.ORDER BY 子句,尽量使用Index方式排序,避免使用FileSort方式排序 MySQL支持两种方 ...
- 给大家推荐:五个Python小项目,Github上的人气很高的
1.深度学习框架 Pytorch https://github.com/pytorch/pytorch PyTorch 是一个 Torch7 团队开源的 Python 优先的深度学习框架,提供两个高级 ...
- 利用爬虫、SMTP和树莓派3B发送邮件&续集&(爬取墨迹天气预报信息)
-----------------------------------------------学无止境----------------------------------------------- 前 ...
- ubuntu 执行Python脚本出现: /usr/bin/env: ‘python\r’: No such file or directory
原因: #!/usr/bin/env python 在ubuntu会变成 #!/usr/bin/env python\r 而\r 会被shell 当成参数 所以出现: /usr/bin/env: ‘ ...
- JavaScript 之 对象/JSON/数组
对象 简单说,所谓对象,就是一种无序的数据集合,由若干个“键值对”(key-value)构成. var obj = { p: 'Hello World' }; 上面代码中,大括号就定义了一个对象,它被 ...
- LeetCode - 136. Single Number - ( C++ ) - 解题报告 - 位运算思路 xor
1.题目大意 Given an array of integers, every element appears twice except for one. Find that single one. ...
- Nodejs基础之redis
安装redis 模块 npm install redis 1 代码部分 const redis = require('redis') const client = redis.createClient ...