Hadoop入门指南之排序实战

Hadoop系列文章索引

Hadoop入门指南之HDFS介绍

Hadoop入门指南之Linux环境搭建

Hadoop入门指南之Linux软件安装

Hadoop入门指南之Hadoop安装

Hadoop入门指南之hdfs命令行使用.

Hadoop入门指南之MapReduce介绍

Hadoop入门指南之统计库存实战

Hadoop入门指南之分区、规约实战

Hadoop入门指南之排序实战

Hadoop入门指南之分组实战

Hadoop入门指南之表连接操作

Hadoop入门指南之yarn介绍​​​​​​​

排序是指按照自定义的排序规则,对数据进行排序,输出时,数据是按照排序组织的。排序往往还伴随着序列化,序列化指的是把Java对象转化成字节流来传输,到达指定位置再反序列化成Java对象,这样就提升了网络传输的速度,减轻了网络传输的压力。

序列化和反序列化在上一章分区和规约实战中已经介绍了,就是写一个StockBean的JavaBean,然后重写write和readFields方法。

我们还用上一章使用的数据:

p004,2021-01-01,5,2
p003,2021-01-01,8,1
p002,2021-01-03,3,3
p003,2021-01-03,6,2
p004,2021-01-05,9,1
p001,2021-01-05,3,2
p004,2021-01-05,2,2
p003,2021-01-07,3,1
p002,2021-01-07,6,5
p001,2021-01-08,2,1
p001,2021-01-09,6,1

这次我们不再统计库存了,而是要把库存记录按照入库数升序、出库数降序方式排序。

其实实现排序要简单的多,只要写一个JavaBean实现WritableComparable接口,重写compareTo方法,定义排序规则就好了。

这里需要输出的是库存数据,所以K2、V2是含有统计日期、入库数、出库数的StockBean和Text的商品Id,K3、V3要反过来,并且因为不需要对相同商品id的数据进行合并,Reducer里拿到数据直接写入就好了。

为什么Mapper的时候要把StockBean作为K2,是因为在Reducer前的Shuffle阶段,是按照key来做排序的,必须要把实现了WritableComparable接口的JavaBean作为Key才能使排序生效。Reducer再反过来是为了保证数据格式的不变。

首先把测试数据保存为stock,txt,接着rz -E上传到node01中,然后在hdfs上新建一个目录,把数据上传到目录中:

hdfs dfs -mkdir /stock_count3_input
hdfs dfs -put stock.txt /stock_count3_input

在IDEA新建一个package,com.demo.stock_count3。

先写一个StockBean类:

package com.demo.stock_count3;

import org.apache.hadoop.io.Writable;
import org.apache.hadoop.io.WritableComparable;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

public class StockBean implements WritableComparable<StockBean> {
    private String date;//统计日期
    private Integer inStock;//入库数
    private Integer outStock;//出库数

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public Integer getInStock() {
        return inStock;
    }

    public void setInStock(Integer inStock) {
        this.inStock = inStock;
    }

    public Integer getOutStock() {
        return outStock;
    }

    public void setOutStock(Integer outStock) {
        this.outStock = outStock;
    }

    /**
     * 无参构造方法
     */
    public StockBean() {
    }

    /**
     * 有参构造方法
     * @param date 统计日期
     * @param inStock 入库数
     * @param outStock 出库数
     */
    public StockBean(String date,Integer inStock, Integer outStock) {
        this.date = date;
        this.inStock = inStock;
        this.outStock = outStock;
    }

    /**
     * 对象转String的方法
     * @return
     */
    @Override
    public String toString() {
        return date+"\t"+inStock+"\t"+outStock;
    }

    /**
     * 序列化
     * @param dataOutput
     * @throws IOException
     */
    @Override
    public void write(DataOutput dataOutput) throws IOException {
        dataOutput.writeUTF(date);
        dataOutput.writeInt(inStock);
        dataOutput.writeInt(outStock);
    }

    /**
     * 反序列化
     * @param dataInput
     * @throws IOException
     */
    @Override
    public void readFields(DataInput dataInput) throws IOException {
        date = dataInput.readUTF();
        inStock = dataInput.readInt();
        outStock = dataInput.readInt();
    }

    /**
     * 排序规则,入库数升序,出库数降序
     * @param o
     * @return
     */
    @Override
    public int compareTo(StockBean o) {
        int result = this.inStock-o.inStock;
        if(result==0){
            return o.outStock-this.outStock;
        }
        return result;
    }
}

这里和上一篇大体上差不多,就是多了个成员变量date,重写了compareTo方法。

接着写Mapper:

package com.demo.stock_count3;

import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

import java.io.IOException;

public class StockMapper extends Mapper<LongWritable, Text,StockBean, Text> {
    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        String[] strings = value.toString().split(",");//对文本进行拆分
        context.write(new StockBean(strings[1],Integer.parseInt(strings[2]),Integer.parseInt(strings[3])),new Text(strings[0]));
    }
}

这里一定要注意K2是StockBean,而不是Text。

接着写Reducer:

package com.demo.stock_count3;

import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

import java.io.IOException;

public class StockReducer extends Reducer<StockBean,Text ,Text,StockBean> {
    @Override
    protected void reduce(StockBean key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
        for (Text value : values) {
            context.write(value,key);
        }
    }
}

这里只是把Key和Value倒过来写入而已。

最后是主类:

package com.demo.stock_count3;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

import java.net.URI;

public class StockMain extends Configured implements Tool {
    @Override
    public int run(String[] strings) throws Exception {
        Job job = Job.getInstance(super.getConf(), "stock_count3");
        job.setJarByClass(StockMain.class);//指定jar的主类
        job.setInputFormatClass(TextInputFormat.class);//指定输入类
        TextInputFormat.addInputPath(job,new Path("hdfs://node01:8020/stock_count3_input"));//指定输入路径
        job.setMapperClass(StockMapper.class);//指定Mapper类
        job.setMapOutputKeyClass(StockBean.class);//指定K2
        job.setMapOutputValueClass(Text.class);//指定V2
        job.setReducerClass(StockReducer.class);//指定Reducer类
        job.setOutputKeyClass(Text.class);//指定K3
        job.setOutputValueClass(StockBean.class);//指定V3
        job.setOutputFormatClass(TextOutputFormat.class);//指定输出类
        Path path = new Path("hdfs://node01:8020/stock_count3_output");
        FileSystem fileSystem = FileSystem.get(new URI("hdfs://node01:8020"), new Configuration());
        boolean exists = fileSystem.exists(path);
        if(exists){
            fileSystem.delete(path,true);//如果目录存在,就先删除目录
        }
        TextOutputFormat.setOutputPath(job,path);//设置输出路径
        boolean b = job.waitForCompletion(true);//运行job
        fileSystem.close();//关闭文件系统
        return b?0:1;
    }

    public static void main(String[] args) throws Exception {
        Configuration configuration = new Configuration();//新建一个配置对象
        int run = ToolRunner.run(configuration, new StockMain(), args);//运行MapReduce
        System.exit(run);//系统退出
    }
}

写完之后打包,然后把jar包上传到node01中,之后运行:

hadoop jar original-mapreduce_demo-1.0-SNAPSHOT.jar com.demo.stock_count3.StockMain

http://node01:50070/explorer.html#/stock_count3_output中去看输出结果:

发现确实按照入库数升序,出库数降序的方式排列了。

至此,排序的案例实战就介绍完了。

感谢观看,如果您觉得文章写得还不错,不妨点个赞。如果您觉得有什么疑惑或者不对的地方,可以留下评论,看到我会及时回复的。如果您关注一下我,那么我会更高兴的,谢谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Cloudera Hadoop大数据平台实战指南是一本介绍如何在Cloudera Hadoop平台上实施大数据解决方案的指南。它包括了Hadoop平台的概述、架构、安装、配置和管理;同时还介绍了如何使用Hadoop组件来管理和处理大数据。本书适合大数据开发人员和管理员阅读。 ### 回答2: Cloudera Hadoop大数据平台实战指南是一本介绍使用Cloudera Hadoop大数据平台进行大数据处理的实践指南。本书主要由两个部分组成:第一部分介绍了Hadoop集群的搭建、安装和管理,以及如何处理和分析大数据;第二部分则详细介绍了Cloudera Hadoop平台的特点和优势,并使用具体的案例来演示这些功能。 本书的第一部分与其他的Hadoop入门教材和指南类似,介绍了Hadoop集群的各个组件,包括HDFS、MapReduce、HBase等,以及在集群上操作和管理这些组件的方法和工具。同时,本书还详细讲解了如何使用Hadoop进行大数据处理和分析,包括使用Pig、Hive、Sqoop等工具进行数据的查询、清洗、转换和导入导出。 第二部分则是本书的重头戏,它介绍了Cloudera Hadoop平台的特性和优势,以及如何在这个平台上进行大数据处理和分析。Cloudera Hadoop平台是目前最受欢迎和使用最广泛的Hadoop平台之一,它提供了许多强大的工具和功能,包括Cloudera Manager、Impala、Search等。本书通过介绍这些工具和功能的使用方法和实际案例,展示了Cloudera Hadoop平台在处理大数据方面的强大能力和应用价值。 总的来说,Cloudera Hadoop大数据平台实战指南是一本非常实用和有价值的指南,它可以帮助读者了解和掌握Hadoop集群的搭建、管理和大数据处理的方法,同时也介绍了Cloudera Hadoop平台的特性和优势,让读者更好地利用这个平台处理和分析大数据。对于想要学习和使用Hadoop进行大数据处理的人来说,本书是一本不可错过的实践指南。 ### 回答3: Cloudera Hadoop是一个用于大数据分析和处理的开源软件平台,它是继Amazon EC2和Google Bigtable之后最受欢迎的大数据分析和处理平台之一。Cloudera Hadoop面向于大型企业机构和互联网公司,其功能包括数据处理、数据仓库、数据搜索等。Cloudera Hadoop对于企业来讲,具有更好的大数据处理和分析能力。基于Cloudera Hadoop平台搭建的大数据处理系统,可以轻松的实现海量数据的快速分析、处理、存储和查询。 Cloudera Hadoop大数据平台实战指南主要是为大数据处理和分析工程师设计的。本书对于大数据技术感兴趣的读者也是非常实用的。指南介绍了Cloudera Hadoop的各种组件和功能,以及如何构建和部署基于这个平台的大型数据应用程序。Cloudera Hadoop大数据平台实战指南内容包括了Hadoop生态系统、HDFS存储、Hive SQL、Pig数据分析、MapReduce计算框架以及使用Hadoop进行数据可视化和实时数据处理等内容。 Cloudera Hadoop平台获得了广泛的应用,包括大型企业级数据处理系统,互联网应用程序、医疗健康数据研究、日志分析、移动应用程序分析、金融分析和多媒体内容分析等。 Cloudera Hadoop平台与传统的数据仓库和商业智能系统相比,有很多优势。首先,它可以处理结构化和非结构化的海量数据,并且可以针对不同的数据类型进行处理。其次,Hadoop可以在分布式服务器网络中实现高可扩展性,并支持大量的并行计算。最后,Cloudera Hadoop庞大的开源社区提供了丰富的工具和插件,并支持同行之间的知识共享。 Cloudera Hadoop大数据平台实战指南将会有助于读者更深入的了解Hadoop技术,剖析大数据处理应用程序,学会如何搭建和维护大型数据处理系统。这本书对于正在寻找更有效的大数据处理和分析工具的企业和组织,以及对于学习和了解Hadoop技术的读者来说都是非常有用的。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值