大数据技术之_05_Hadoop学习_03_MapReduce_MapTask工作机制+ReduceTask工作机制+OutputFormat数据输出+Join多种应用+计数器应用+数据清洗(ETL)

本文主要是介绍大数据技术之_05_Hadoop学习_03_MapReduce_MapTask工作机制+ReduceTask工作机制+OutputFormat数据输出+Join多种应用+计数器应用+数据清洗(ETL),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

大数据技术之_05_Hadoop学习_03_MapReduce

        • 3.3.4 WritableComparable排序
        • 3.3.5 WritableComparable排序案例实操(全排序)
        • 3.3.6 WritableComparable排序案例实操(区内排序)
        • 3.3.7 Combiner合并
        • 3.3.8 Combiner合并案例实操
        • 3.3.9 GroupingComparator分组(辅助排序/分组排序)
        • 3.3.10 GroupingComparator分组案例实操
      • 3.4 MapTask工作机制
      • 3.5 ReduceTask工作机制
      • 3.6 OutputFormat数据输出
        • 3.6.1 OutputFormat接口实现类
        • 3.6.2 自定义OutputFormat
        • 3.6.3 自定义OutputFormat案例实操
      • 3.7 Join多种应用
        • 3.7.1 Reduce Join
        • 3.7.2 Reduce Join案例实操
        • 3.7.3 Map Join
        • 3.7.4 Map Join案例实操
      • 3.8 计数器应用
      • 3.9 数据清洗(ETL)
        • 3.9.1 数据清洗案例实操-简单解析版
        • 3.9.2 数据清洗案例实操-复杂解析版
        • 3.10 MapReduce开发总结
    • 第4章 Hadoop数据压缩
      • 4.1 概述
      • 4.2 MR支持的压缩编码
      • 4.3 压缩方式选择
        • 4.3.1 Gzip压缩
        • 4.3.2 Bzip2压缩
        • 4.3.3 Lzo压缩
        • 4.3.4 Snappy压缩
      • 4.4 压缩位置选择
      • 4.5 压缩参数配置
      • 4.6 压缩实操案例
        • 4.6.1 数据流的压缩和解压缩
        • 4.6.2 Map输出端采用压缩
        • 4.6.3 Reduce输出端采用压缩
    • 第5章 Yarn资源调度器
      • 5.1 Yarn基本架构
      • 5.3 Yarn工作机制
      • 5.4 作业提交全过程
      • 5.5 资源调度器
      • 5.6 任务的推测执行(秘籍)

3.3.4 WritableComparable排序

0、排序概述


1、排序的分类

2、自定义排序WritableComparable
(1)原理分析
  bean对象做为key传输,需要实现WritableComparable接口重写compareTo()方法,就可以实现排序。

@Override
public int compareTo(FlowBean o) {int result;// 按照总流量大小,倒序排列if (sumFlow > bean.getSumFlow()) {result = -1;} else if (sumFlow < bean.getSumFlow()) {result = 1;} else {result = 0;}return result;
}
3.3.5 WritableComparable排序案例实操(全排序)

1、需求
  根据案例2.3产生的结果再次对总流量进行排序。
(1)输入数据

(2)期望输出数据

13509468723     7335	110349	117684
13736230513     2481	24681	27162
13956435636     132		1512	1644
13846544121     264		0		264
......

2、需求分析

3、代码实现
(1)FlowBean对象在在需求1基础上增加了比较功能

package com.atguigu.mr.sort;import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;import org.apache.hadoop.io.WritableComparable;public class FlowBean implements WritableComparable<FlowBean> {private long upFlow; // 上行流量private long downFlow; // 下行流量private long sumFlow; // 总流量/*** 反序列化时,需要反射调用空参构造函数,所以必须有*/public FlowBean() {super();}public FlowBean(long upFlow, long downFlow) {super();this.upFlow = upFlow;this.downFlow = downFlow;this.sumFlow = upFlow + downFlow;}/*** 序列化方法*/@Overridepublic void write(DataOutput out) throws IOException {out.writeLong(upFlow);out.writeLong(downFlow);out.writeLong(sumFlow);}/*** 反序列化方法,注意反序列化的顺序和序列化的顺序完全一致*/@Overridepublic void readFields(DataInput in) throws IOException {upFlow = in.readLong();downFlow = in.readLong();sumFlow = in.readLong();}/*** 比较方法*/@Overridepublic int compareTo(FlowBean bean) {int result;// 按照总流量大小,倒序排列if (sumFlow > bean.getSumFlow()) {result = -1;} else if (sumFlow < bean.getSumFlow()) {result = 1;} else {result = 0;}return result;}public long getUpFlow() {return upFlow;}public void setUpFlow(long upFlow) {this.upFlow = upFlow;}public long getDownFlow() {return downFlow;}public void setDownFlow(long downFlow) {this.downFlow = downFlow;}public long getSumFlow() {return sumFlow;}public void setSumFlow(long sumFlow) {this.sumFlow = sumFlow;}@Overridepublic String toString() {return upFlow + "\t" + downFlow + "\t" + sumFlow;}
}

(2)编写Mapper类

package com.atguigu.mr.sort;import java.io.IOException;import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;public class FlowCountSortMapper extends Mapper<LongWritable, Text, FlowBean, Text> {FlowBean k = new FlowBean();Text v = new Text();@Overrideprotected void map(LongWritable key, Text value, Context context)throws IOException, InterruptedException {// 13736230513	2481	24681	27162// 1、获取一行String line = value.toString();// 2、截取String[] fields = line.split("\t");// 3、封装对象String phoneNum = fields[0];long upFlow = Long.parseLong(fields[1]);long downFlow = Long.parseLong(fields[2]);long sumFlow = Long.parseLong(fields[3]);k.setUpFlow(upFlow);k.setDownFlow(downFlow);k.setSumFlow(sumFlow);v.set(phoneNum);// 4、输出context.write(k, v);}
}

(3)编写Reducer类

package com.atguigu.mr.sort;import java.io.IOException;import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;public class FlowCountSortReducer extends Reducer<FlowBean, Text, Text, FlowBean> {@Overrideprotected void reduce(FlowBean key, Iterable<Text> values, Context context)throws IOException, InterruptedException {// 循环输出,避免总流量相同的情况for (Text text : values) {context.write(text, key);}}
}

(4)编写Driver类

package com.atguigu.mr.sort;import java.io.IOException;import org.apache.hadoop.conf.Configuration;
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.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;public class FlowCountSortDriver {public static void main(String[] args) throws IllegalArgumentException, IOException, ClassNotFoundException, InterruptedException {// 输入输出路径需要根据自己电脑上实际的输入输出路径设置args = new String[] { "d:/temp/atguigu/0529/output2", "d:/temp/atguigu/0529/output8" };// 1、获取配置信息,或者job对象实例Configuration configuration = new Configuration();Job job = Job.getInstance(configuration);// 2、指定本程序的jar包所在的本地路径job.setJarByClass(FlowCountSortDriver.class);// 3、指定本业务job要使用的mapper/Reducer业务类job.setMapperClass(FlowCountSortMapper.class);job.setReducerClass(FlowCountSortReducer.class);// 4、指定mapper输出数据的kv类型job.setMapOutputKeyClass(FlowBean.class);job.setMapOutputValueClass(Text.class);// 5、指定最终输出的数据的kv类型job.setOutputKeyClass(Text.class);job.setOutputValueClass(FlowBean.class);// 6、指定job的输入原始文件所在目录FileInputFormat.setInputPaths(job, new Path(args[0]));FileOutputFormat.setOutputPath(job, new Path(args[1]));// 7、将job中配置的相关参数,以及job所用的java类所在的jar包, 提交给yarn去运行boolean result = job.waitForCompletion(true);System.exit(result ? 0 : 1);}
}
3.3.6 WritableComparable排序案例实操(区内排序)

1、需求
  要求每个省份手机号输出的文件中按照总流量内部排序。
2、需求分析
  基于前一个需求,增加自定义分区类,分区按照省份手机号设置。

3、案例实操
(1)增加自定义分区类

package com.atguigu.mr.sort;import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Partitioner;public class ProvincePartitioner extends Partitioner<FlowBean, Text> {@Overridepublic int getPartition(FlowBean key, Text value, int numPartitions) {// 按照手机号的前三位进行分区// 获取手机号的前三位String prePhoneNum = value.toString().substring(0, 3);// 根据手机号归属地设置分区int partition = 4;if ("136".equals(prePhoneNum)) {partition = 0;} else if ("137".equals(prePhoneNum)) {partition = 1;} else if ("138".equals(prePhoneNum)) {partition = 2;} else if ("139".equals(prePhoneNum)) {partition = 3;}return partition;}
}

(2)在驱动类中添加加载分区类

    // 加载自定义分区类(即关联分区)job.setPartitionerClass(ProvincePartitioner.class);// 设置Reducetask个数job.setNumReduceTasks(5);
3.3.7 Combiner合并

  Combiner合并是Hadoop框架优化的一种手段,因为Combiner合并减少了数据的IO传输。

(6)自定义Combiner实现步骤
(a)自定义一个Combiner继承Reducer,重写reduce()方法

package com.atguigu.mr.wordcount;import java.io.IOException;import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;public class WordcountCombiner extends Reducer<Text, IntWritable, Text, IntWritable> {int sum;IntWritable v = new IntWritable();@Overrideprotected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {// 1、汇总,累加求和sum = 0;for (IntWritable value : values) {sum += value.get();}v.set(sum);// 2、写出context.write(key, v);}
}

(b)在Job驱动类中设置:

    job.setCombinerClass(WordcountCombiner.class);
3.3.8 Combiner合并案例实操

1、需求
  统计过程中对每一个MapTask的输出进行局部汇总,以减小网络传输量即采用Combiner功能。
(1)数据输入

banzhang ni hao
xihuan hadoop banzhang
banzhang ni hao
xihuan hadoop banzhang

(2)期望输出数据
  期望:Combine输入数据多,输出时经过合并,输出数据降低。
2、需求分析

3、案例实操-方案一
1)增加一个WordcountCombiner类继承Reducer

package com.atguigu.mr.wordcount;import java.io.IOException;import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;public class WordcountCombiner extends Reducer<Text, IntWritable, Text, IntWritable> {int sum;IntWritable v = new IntWritable();@Overrideprotected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {// 1、汇总,累加求和sum = 0;for (IntWritable value : values) {sum += value.get();}v.set(sum);// 2、写出context.write(key, v);}
}

2)在WordcountDriver驱动类中指定Combiner

    // 指定需要使用Combiner,以及用哪个类作为Combiner的逻辑job.setCombinerClass(WordcountCombiner.class);

4、案例实操-方案二
1)将WordcountReducer作为Combiner在WordcountDriver驱动类中指定

    // 指定需要使用Combiner,以及用哪个类作为Combiner的逻辑job.setCombinerClass(WordcountReducer.class);

运行程序,如下图所示:

3.3.9 GroupingComparator分组(辅助排序/分组排序)

  对Reduce阶段的数据根据某一个或几个字段进行分组。
分组排序步骤:
(1)自定义类继承WritableComparator
(2)重写compare()方法

@Override
public int compare(WritableComparable a, WritableComparable b) {// 比较的业务逻辑// ......return result;
}

(3)创建一个构造将比较对象的类传给父类

protected OrderGroupingComparator() {super(OrderBean.class, true);
}
3.3.10 GroupingComparator分组案例实操

1、需求
  有如下订单数据

  现在需要求出每一个订单中最贵的商品。
(1)输入数据
GroupingComparator.txt

0000001	Pdt_01	222.8
0000002	Pdt_05	722.4
0000001	Pdt_02	33.8
0000003	Pdt_06	232.8
0000003	Pdt_02	33.8
0000002	Pdt_03	522.8
0000002	Pdt_04	122.4

(2)期望输出数据

1	222.8
2	722.4
3	232.8

2、需求分析
(1)利用“订单id和成交金额”作为key,可以将Map阶段读取到的所有订单数据按照id升序排序,如果id相同再按照金额降序排序,发送到Reduce。
(2)在Reduce端利用GroupingComparator将订单id相同的kv聚合成组,然后取第一个即是该订单中最贵商品,如下图所示。

3、代码实现
(1)定义订单信息OrderBean类

package com.atguigu.mr.order;import java.io.DataInput;

这篇关于大数据技术之_05_Hadoop学习_03_MapReduce_MapTask工作机制+ReduceTask工作机制+OutputFormat数据输出+Join多种应用+计数器应用+数据清洗(ETL)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1100803

相关文章

SpringBoot分段处理List集合多线程批量插入数据方式

《SpringBoot分段处理List集合多线程批量插入数据方式》文章介绍如何处理大数据量List批量插入数据库的优化方案:通过拆分List并分配独立线程处理,结合Spring线程池与异步方法提升效率... 目录项目场景解决方案1.实体类2.Mapper3.spring容器注入线程池bejsan对象4.创建

PHP轻松处理千万行数据的方法详解

《PHP轻松处理千万行数据的方法详解》说到处理大数据集,PHP通常不是第一个想到的语言,但如果你曾经需要处理数百万行数据而不让服务器崩溃或内存耗尽,你就会知道PHP用对了工具有多强大,下面小编就... 目录问题的本质php 中的数据流处理:为什么必不可少生成器:内存高效的迭代方式流量控制:避免系统过载一次性

C#实现千万数据秒级导入的代码

《C#实现千万数据秒级导入的代码》在实际开发中excel导入很常见,现代社会中很容易遇到大数据处理业务,所以本文我就给大家分享一下千万数据秒级导入怎么实现,文中有详细的代码示例供大家参考,需要的朋友可... 目录前言一、数据存储二、处理逻辑优化前代码处理逻辑优化后的代码总结前言在实际开发中excel导入很

PHP应用中处理限流和API节流的最佳实践

《PHP应用中处理限流和API节流的最佳实践》限流和API节流对于确保Web应用程序的可靠性、安全性和可扩展性至关重要,本文将详细介绍PHP应用中处理限流和API节流的最佳实践,下面就来和小编一起学习... 目录限流的重要性在 php 中实施限流的最佳实践使用集中式存储进行状态管理(如 Redis)采用滑动

MyBatis-plus处理存储json数据过程

《MyBatis-plus处理存储json数据过程》文章介绍MyBatis-Plus3.4.21处理对象与集合的差异:对象可用内置Handler配合autoResultMap,集合需自定义处理器继承F... 目录1、如果是对象2、如果需要转换的是List集合总结对象和集合分两种情况处理,目前我用的MP的版本

深入浅出Spring中的@Autowired自动注入的工作原理及实践应用

《深入浅出Spring中的@Autowired自动注入的工作原理及实践应用》在Spring框架的学习旅程中,@Autowired无疑是一个高频出现却又让初学者头疼的注解,它看似简单,却蕴含着Sprin... 目录深入浅出Spring中的@Autowired:自动注入的奥秘什么是依赖注入?@Autowired

GSON框架下将百度天气JSON数据转JavaBean

《GSON框架下将百度天气JSON数据转JavaBean》这篇文章主要为大家详细介绍了如何在GSON框架下实现将百度天气JSON数据转JavaBean,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录前言一、百度天气jsON1、请求参数2、返回参数3、属性映射二、GSON属性映射实战1、类对象映

从基础到高级详解Python数值格式化输出的完全指南

《从基础到高级详解Python数值格式化输出的完全指南》在数据分析、金融计算和科学报告领域,数值格式化是提升可读性和专业性的关键技术,本文将深入解析Python中数值格式化输出的相关方法,感兴趣的小伙... 目录引言:数值格式化的核心价值一、基础格式化方法1.1 三种核心格式化方式对比1.2 基础格式化示例

C# LiteDB处理时间序列数据的高性能解决方案

《C#LiteDB处理时间序列数据的高性能解决方案》LiteDB作为.NET生态下的轻量级嵌入式NoSQL数据库,一直是时间序列处理的优选方案,本文将为大家大家简单介绍一下LiteDB处理时间序列数... 目录为什么选择LiteDB处理时间序列数据第一章:LiteDB时间序列数据模型设计1.1 核心设计原则

Java+AI驱动实现PDF文件数据提取与解析

《Java+AI驱动实现PDF文件数据提取与解析》本文将和大家分享一套基于AI的体检报告智能评估方案,详细介绍从PDF上传、内容提取到AI分析、数据存储的全流程自动化实现方法,感兴趣的可以了解下... 目录一、核心流程:从上传到评估的完整链路二、第一步:解析 PDF,提取体检报告内容1. 引入依赖2. 封装