Avro:使用Avro MapReduce进行排序

在MapReduce作业中,框架保证Reducer收到的key是有序的。利用这一点,我们可以对Avro文件进行排序。

假设我们有如下的Schema:

{"namespace": "me.lin.avro.mapreduce",
 "type": "record",
 "name": "User",
 "fields": [
     {"name": "name", "type": "string"},
     {"name": "favorite_number",  "type": ["int", "null"]},
     {"name": "favorite_color", "type": ["string", "null"] 
 ]
}

现在我们有一个无需的avro文件,样例如下:

这里写图片描述

如何生成这些数据,请参考这里

我们现在需求是根据favorite_color进行排序。

Avro不同于其他序列化框架的地方之一就是读写的Schema可以不一样。用前面的Schema写入的文件,我们再读取的时候,可以使用另一个兼容的Schema来读取,为了排序,我们再favorite_color字段加上顺序:

{"namespace": "me.lin.avro.mapreduce",
 "type": "record",
 "name": "User",
 "fields": [
     {"name": "name", "type": "string"},
     {"name": "favorite_number",  "type": ["int", "null"]},
     {"name": "favorite_color", "type": ["string", "null"] , "order":"descending"}
 ]
}

注意order设置为descending倒序,也就是根据字母倒序。我们使用这个带顺序的Schema去读取原来没有顺序的文件,并利用MapReduce的shuffle过程中会进行排序这一点,实现最终的排序目标。

Mapper和Reducer

Mapper的逻辑是读取文件中的记录(作为key输入),针对每一对key-value,往Context中写入key-key的形式,也就是说将输入的key同时作为输出,传送到Reducer。代码如下:

public static class SortMapper<K> extends
            Mapper<AvroKey<K>, NullWritable, AvroKey<K>, AvroValue<K>> {

        @Override
        protected void map(AvroKey<K> key, NullWritable value, Context context)
                throws IOException, InterruptedException {
            context.write(key, new AvroValue<K>(key.datum()));
        }

    }

Reducer收到根据key分值的键值对,是根据key排序过的,由于Mapper中每一个key对应输出了相同值的value,因此对于Reducer收到的一个key,其列表值也是对应有序的,直接输出到avro文件即可完成排序,代码如下:

public static class SortReducer<K> extends
            Reducer<AvroKey<K>, AvroValue<K>, AvroKey<K>, NullWritable> {

        @Override
        protected void reduce(AvroKey<K> key, Iterable<AvroValue<K>> values,
                Context context) throws IOException, InterruptedException {
            for (AvroValue<K> val : values) {
                context.write(new AvroKey<K>(val.datum()), NullWritable.get());
            }
        }
    }

运行作业

我们通过Tool来运行作业,代码如下:

    @Override
    public int run(String[] args) throws Exception {
        if (args.length != 3) {
            System.err
                    .printf("Usage: %s [generic options] <input> <output> <schema-file>\n",
                            getClass().getSimpleName());
            ToolRunner.printGenericCommandUsage(System.err);
            return -1;
        }

        String input = args[0];
        String output = args[1];
        String schemaFile = args[2];

        @SuppressWarnings("deprecation")
        Job job = new Job(getConf());
        job.setJarByClass(getClass());

        job.getConfiguration().setBoolean(
                Job.MAPREDUCE_JOB_USER_CLASSPATH_FIRST, true);
        FileInputFormat.setInputPaths(job, new Path(input));
        FileOutputFormat.setOutputPath(job, new Path(output));

        AvroJob.setDataModelClass(job, GenericData.class);

        Schema schema = new Schema.Parser().parse(new File(schemaFile));
        AvroJob.setInputKeySchema(job, schema);
        AvroJob.setMapOutputKeySchema(job, schema);
        AvroJob.setMapOutputValueSchema(job, schema);
        AvroJob.setOutputKeySchema(job, schema);

        job.setInputFormatClass(AvroKeyInputFormat.class);
        job.setOutputFormatClass(AvroKeyOutputFormat.class);

        job.setOutputKeyClass(AvroKey.class);
        job.setOutputValueClass(NullWritable.class);

        job.setMapperClass(SortMapper.class);
        job.setReducerClass(SortReducer.class);
        return job.waitForCompletion(true) ? 0 : 1;
    }

    public static void main(String... args) throws Exception {
        int exitCode = ToolRunner.run(new AvroSort(), args);
        System.exit(exitCode);
    }

所有代码都放在AvroSort.java中。

将项目打包,准备好待排序文件及有序的Schema,然后运行作业:

hadoop jar  avro-mapreduce-0.0.1-SNAPSHOT-jar-with-dependencies.jar  me.lin.avro.mapreduce.AvroSort /input/avro/users.avro /output/avro/mr-sort ./user.avsc

入口类AvroSort接受三个参数:输入文件,输出目录及schema文件。注意shcema文件配置的路径是当前机器的路径,不是HDFS上的路径。运行效果如下:

这里写图片描述

使用Avro tool包的tojson工具查看排序后的结果:

java -jar avro-tools-1.8.1.jar tojson part-r-00000-sort.avro

这里写图片描述

可以看到是根据favorite_color倒排的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
完整全套资源下载地址:https://download.csdn.net/download/qq_27595745/65977804 【完整课程列表】 大数据与云计算教程课件 优质大数据课程 01.Hadoop简介与安装入门(共29页).pptx 大数据与云计算教程课件 优质大数据课程 02.MapReduce(共23页).pptx 大数据与云计算教程课件 优质大数据课程 03.Hadoop YARN(共25页).pptx 大数据与云计算教程课件 优质大数据课程 04.MapReduce Eclipse开发插件(共20页).pptx 大数据与云计算教程课件 优质大数据课程 05.Hadoop入门数据分析实战(共57页).pptx 大数据与云计算教程课件 优质大数据课程 06.HDFS(共38页).pptx 大数据与云计算教程课件 优质大数据课程 07.HDFS Shell命令(共21页).pptx 大数据与云计算教程课件 优质大数据课程 08.HDFS文件接口(共41页).pptx 大数据与云计算教程课件 优质大数据课程 09.MapReduce序列化(共29页).pptx 大数据与云计算教程课件 优质大数据课程 10.MapReduce MP过程进阶(共42页).pptx 大数据与云计算教程课件 优质大数据课程 11.MapReduce IO操作(共61页).pptx 大数据与云计算教程课件 优质大数据课程 12.序列化框架(共28页).pptx 大数据与云计算教程课件 优质大数据课程 13.深入MapReduce应用开发(共21页).pptx 大数据与云计算教程课件 优质大数据课程 14.Hadoop集群配置(共6页).pptx 大数据与云计算教程课件 优质大数据课程 15.Hive(共46页).pptx 大数据与云计算教程课件 优质大数据课程 16.Hive操作(共43页).pptx 大数据与云计算教程课件 优质大数据课程 17.Hive查询(共32页).pptx 大数据与云计算教程课件 优质大数据课程 18.HBase(共43页).pptx 大数据与云计算教程课件 优质大数据课程 19.Pig(共33页).pptx 大数据与云计算教程课件 优质大数据课程 20.Pig Latin(共36页).pptx 大数据与云计算教程课件 优质大数据课程 21.Pig模式与函数(共64页).pptx 大数据与云计算教程课件 优质大数据课程 22.Zookeeper(共28页).pptx 大数据与云计算教程课件 优质大数据课程 23.Zookeeper服务(共47页).pptx 大数据与云计算教程课件 优质大数据课程 24.使用Zookeeper构建应用(共34页).pptx 大数据与云计算教程课件 优质大数据课程 25.Sqoop(共19页).pptx 大数据与云计算教程课件 优质大数据课程 26.深入Sqoop的导入(共29页).pptx 大数据与云计算教程课件 优质大数据课程 27.深入Sqoop导出(共19页).pptx 大数据与云计算教程课件 优质大数据课程 28.Flume(共33页).pptx 大数据与云计算教程课件 优质大数据课程 29.Kafka(共30页).pptx 大数据与云计算教程课件 优质大数据课程 30.Kafka开发(共34页).pptx 大数据与云计算教程课件 优质大数据课程 31.Strom(共14页).pptx 大数据与云计算教程课件 优质大数据课程 32.Spark入门之Scala(共173页).pptx 大数据与云计算教程课件 优质大数据课程 33.Spark入门(共40页).pptx 大数据与云计算教程课件 优质大数据课程 34.SparkSQL(共15页).pptx 大数据与云计算教程课件 优质大数据课程 35.Oozie(共41页).pptx 大数据与云计算教程课件 优质大数据课程 36.Impala(共20页).pptx 大数据与云计算教程课件 优质大数据课程 37.Solr(共38页).pptx 大数据与云计算教程课件 优质大数据课程 38.Lily(共23页).pptx 大数据与云计算教程课件 优质大数据课程 39.Titan(共20页).pptx 大数据与云计算教程课件 优质大数据课程 40.Neo4j(共50页).pptx 大数据与云计算教程课件 优质大数据课程 41.Elasticsearch(共17页).pptx

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值