在上例中,使用Avro框架求出数据的最大值,本例使用Avro对数据排序,输入依然是之前的样本,输出使用文本(也可以输出Avro格式)。

1、在Avro的Schema中直接设置排序方向。

dataRecord.avsc,放入resources目录下:

{
"type":"record",
"name":"WeatherRecord",
"doc":"A weather reading",
"fields":[
{"name":"year","type":"int"},
{"name":"temperature","type":"int","order":"descending"}
]
}

原常量类:

public class AvroSchemas {
private Schema currentSchema; //本例中不使用常量,修改成资源中加载
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\",\"order\":\"descending\"}\n" +
"\t]\t\n" +
"}"); public AvroSchemas() throws IOException {
Schema.Parser parser = new Schema.Parser();
//采用从资源文件中读取Avro数据格式
this.currentSchema = parser.parse(getClass().getResourceAsStream("dataRecord.avsc"));
} public Schema getCurrentSchema() {
return currentSchema;
}
}

2、mapper

public class AvroMapper extends Mapper<LongWritable,Text,AvroKey<GenericRecord>,AvroValue<GenericRecord>> {
private RecordParser parser = new RecordParser();
// private GenericRecord record = new GenericData.Record(AvroSchemas.SCHEMA);
private AvroSchemas schema;
private GenericRecord record; public AvroMapper() throws IOException {
schema =new AvroSchemas();
record = new GenericData.Record(schema.getCurrentSchema());
} @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<>(record),new AvroValue<>(record));
}
}
}

3、reducer

public class AvroReducer extends Reducer<AvroKey<GenericRecord>,AvroValue<GenericRecord>,IntPair,NullWritable> {
//多文件输出,本例中每年一个文件
private MultipleOutputs<IntPair,NullWritable> multipleOutputs; /**
* Called once at the start of the task.
*
* @param context
*/
@Override
protected void setup(Context context) throws IOException, InterruptedException {
multipleOutputs = new MultipleOutputs<>(context);
} @Override
protected void reduce(AvroKey<GenericRecord> key, Iterable<AvroValue<GenericRecord>> values, Context context) throws IOException, InterruptedException {
//在混洗阶段完成排序,reducer只需直接输出数据
for (AvroValue<GenericRecord> value : values){
GenericRecord record = value.datum();
//多文件输出,每年一个文件。
multipleOutputs.write(new IntPair((Integer) record.get("year"),(Integer)(record.get("temperature"))),NullWritable.get(),record.get("year").toString());
// context.write(new IntPair((Integer) record.get("year"),(Integer)(record.get("temperature"))),NullWritable.get());
}
} }

4、job

public class AvroSort extends Configured implements Tool {

    @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, AvroSchemas.SCHEMA);
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);
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);
}
}

hadoop 使用Avro排序的更多相关文章

  1. hadoop 使用Avro求最大值

    在上例中:hadoop MapReduce辅助排序解析,为了求每年的最大数据使用了mapreduce辅助排序的方法. 本例中介绍利用Avro这个序列化框架的mapreduce功能来实现求取最大值.Av ...

  2. 2 weekend110的hadoop的自定义排序实现 + mr程序中自定义分组的实现

    我想得到按流量来排序,而且还是倒序,怎么达到实现呢? 达到下面这种效果, 默认是根据key来排, 我想根据value里的某个排, 解决思路:将value里的某个,放到key里去,然后来排 下面,开始w ...

  3. Hadoop之WritableComprale 排序

    Hadoop之WritableComprale 排序 Hadoop只对key进行排序 排序是 MapReduce 框架中最重要的操作之一.Map Task 和 Reduce Task 均会对数据(按照 ...

  4. Hadoop日记Day18---MapReduce排序分组

    本节所用到的数据下载地址为:http://pan.baidu.com/s/1bnfELmZ MapReduce的排序分组任务与要求 我们知道排序分组是MapReduce中Mapper端的第四步,其中分 ...

  5. Hadoop shuffle与排序

    Mapreduce为了确保每个reducer的输入都按键排序.系统执行排序的过程-----将map的输出作为输入传给reducer 称为shuffle.学习shuffle是如何工作的有助于我们理解ma ...

  6. 三种方法实现Hadoop(MapReduce)全局排序(1)

    我们可能会有些需求要求MapReduce的输出全局有序,这里说的有序是指Key全局有序.但是我们知道,MapReduce默认只是保证同一个分区内的Key是有序的,但是不保证全局有序.基于此,本文提供三 ...

  7. hadoop streaming字段排序介绍

    我们在使用hadoop streaming的时候默认streaming的map和reduce的separator不指定的话,map和reduce会根据它们默认的分隔符来进行排序 map.reduce: ...

  8. 一起学Hadoop——二次排序算法的实现

    二次排序,从字面上可以理解为在对key排序的基础上对key所对应的值value排序,也叫辅助排序.一般情况下,MapReduce框架只对key排序,而不对key所对应的值排序,因此value的排序经常 ...

  9. Hadoop mapreduce自定义排序WritableComparable

    本文发表于本人博客. 今天继续写练习题,上次对分区稍微理解了一下,那根据那个步骤分区.排序.分组.规约来的话,今天应该是要写个排序有关的例子了,那好现在就开始! 说到排序我们可以查看下hadoop源码 ...

随机推荐

  1. JavaSE基础笔记

    JVM 不是跨平台的,他是用 C++编写的. Path 环境变量的地址是 ...jdk/bin java_home 地址是 ...jdk

  2. Docker - vim安装

    在使用docker容器时,有时候里边没有安装vim,敲vim命令时提示说:vim: command not found,这个时候就需要安装vim. apt-get install vim 若提示: R ...

  3. centos7下安装mysql8.0.12及设置权限

    一.mysql版本介绍 mysql的官网为:https://www.mysql.com/ 在官网上可以看到多个版本,主要版本如下, 1.MySQL Community Server 社区版本,开源免费 ...

  4. 「题目代码」P1054~P1059(Java)

    P1054 猴子吃桃 import java.util.*; import java.io.*; import java.math.BigInteger; import java.lang.Chara ...

  5. windows环境下jmeter生成测试报告

    1.要求 jmeter需要在3.0版本以上 jdk1.7以上 需要准备脚本文件,即jmx文件 2.进入cmd界面 3.进入jmeter的bin目录 cd:\xxxx\apache-jmeter-4.0 ...

  6. selenide 自动化测试进阶一: 查找元素和相关操作

    基础环境配置和举例请移步:https://www.cnblogs.com/davice/p/9298742.html 提到自动化有些测试同学就会问,我会使用工具录制做自动化,我会用工具或插件识别元素. ...

  7. Eclipse 常用快捷键 个性设置(Mac)

    推荐编程使用Mac 要是非要一个原因 那就是Apple工程师用Mac Google工程师也用Mac 1. 常用快捷键 Mac自带 Command + ←  跳到当前文本行头 Command + →  ...

  8. Java开发工程师(Web方向) - 01.Java Web开发入门 - 第1章.Web应用开发概述

    第1章--Web应用开发概述 Web应用开发概述 浏览器-服务器架构(BS-architecture) browser/ App    ---- request ---->    server ...

  9. 反片语 (Ananagrams,UVa 156)

    题目描述: #include <iostream> #include <string> #include <cctype> #include <vector& ...

  10. spark操作数据库的几种方法

    一.使用jdbcRDD的接口: SparkConf conf = new SparkConf(); conf.setAppName("Simple Application").se ...