【Hadoop离线基础总结】MapReduce案例之自定义groupingComparator
MapReduce案例之自定义groupingComparator
求取Top 1的数据
- 需求
求出每一个订单中成交金额最大的一笔交易
订单id 商品id 成交金额
Order_0000005 Pdt_01 222.8
Order_0000005 Pdt_05 25.8
Order_0000002 Pdt_03 322.8
Order_0000002 Pdt_04 522.4
Order_0000002 Pdt_05 822.4
Order_0000003 Pdt_01 222.8
- 代码实现
自定义一个javaBean,命名为OrderBean
package cn.itcast.demo5;
import org.apache.hadoop.io.WritableComparable;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class OrderBean implements WritableComparable<OrderBean> {
//定义orderId和price变量
private String orderId;
private Double price;
/**
* 重写compareTo方法
*
* @param o
* @return
*/
@Override
public int compareTo(OrderBean o) {
//先对orderId进行比较,如果相同,将它们的price放一起比较,不同就不比较
int result = this.orderId.compareTo(o.orderId);
//进行判断
if (result == 0) {
int i = this.price.compareTo(o.price);
return -i; //返回i求取最小值,返回-i求取最大值
}
return result;
}
@Override
public void write(DataOutput out) throws IOException {
out.writeUTF(orderId);
out.writeDouble(price);
}
@Override
public void readFields(DataInput in) throws IOException {
this.orderId = in.readUTF();
this.price = in.readDouble();
}
//生成get(),set()方法
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
//生成toString()方法
@Override
public String toString() {
return orderId + "\t" + price;
}
}
定义一个Mapper类
package cn.itcast.demo5;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import java.io.IOException;
public class GroupMapper extends Mapper<LongWritable, Text, OrderBean, NullWritable> {
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
//分割获取到的数据
String[] split = value.toString().split("\t");
//创建orderBean对象
OrderBean orderBean = new OrderBean();
//给orderId赋值
orderBean.setOrderId(split[0]);
//给price赋值
orderBean.setPrice(Double.valueOf(split[2]));
context.write(orderBean, NullWritable.get());
}
}
自定义分区(Partition)规则
package cn.itcast.demo5;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.mapreduce.Partitioner;
public class GroupPartitioner extends Partitioner<OrderBean, NullWritable> {
/**
* 重写分区方法
*
* @param orderBean
* @param nullWritable
* @param i
* @return
*/
@Override
public int getPartition(OrderBean orderBean, NullWritable nullWritable, int i) {
//参照HashPartitioner的重写方法
return (orderBean.getOrderId().hashCode() & Integer.MAX_VALUE) % i;
}
}
自定义分组(groupingComparator)规则
package cn.itcast.demo5;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.WritableComparable;
import org.apache.hadoop.io.WritableComparator;
public class GroupComparator extends WritableComparator {
//重写无参构造方法,定义反射出来的对象是OrderBean类
public GroupComparator() {
super(OrderBean.class, true);
}
@Override
public int compare(WritableComparable a, WritableComparable b) {
OrderBean first = (OrderBean) a;
OrderBean second = (OrderBean) b;
//比较orderId,如果相同就认为是同一组数据
return first.getOrderId().compareTo(second.getOrderId());
}
}
定义一个Reducer类
package cn.itcast.demo5;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
public class GroupReducer extends Reducer<OrderBean, NullWritable, OrderBean, NullWritable> {
/**
* 直接将收到的k2,v2的值转换为k3,v3输出
*
* @param key
* @param values
* @param context
* @throws IOException
* @throws InterruptedException
*/
@Override
protected void reduce(OrderBean key, Iterable<NullWritable> values, Context context) throws IOException, InterruptedException {
context.write(key, values.iterator().next());
}
}
程序main函数入口
package cn.itcast.demo5;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.NullWritable;
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;
public class GroupMain extends Configured implements Tool {
@Override
public int run(String[] args) throws Exception {
//获取Job对象
Job job = Job.getInstance(super.getConf(), "myGroupComparator");
//输入数据,设置输入路径
job.setInputFormatClass(TextInputFormat.class);
TextInputFormat.setInputPaths(job, new Path("file:////Volumes/赵壮备份/大数据离线课程资料/5.大数据离线第五天/自定义groupingComparator/input/orders.txt"));
//自定义Map逻辑
job.setMapperClass(GroupMapper.class);
//设置k2,v2输出类型
job.setMapOutputKeyClass(OrderBean.class);
job.setMapOutputValueClass(NullWritable.class);
//自定义Partition逻辑
job.setPartitionerClass(GroupPartitioner.class);
//自定义分组逻辑
job.setGroupingComparatorClass(GroupComparator.class);
//自定义reduce逻辑
job.setReducerClass(GroupReducer.class);
//设置k3,v3输出类型
job.setOutputKeyClass(OrderBean.class);
job.setOutputValueClass(NullWritable.class);
//输出数据,设置输出路径
job.setOutputFormatClass(TextOutputFormat.class);
TextOutputFormat.setOutputPath(job, new Path("file:////Volumes/赵壮备份/大数据离线课程资料/5.大数据离线第五天/自定义groupingComparator/output_top1"));
//提交任务至集群
boolean b = job.waitForCompletion(true);
return b ? 0 : 1;
}
public static void main(String[] args) throws Exception {
int run = ToolRunner.run(new Configuration(), new GroupMain(), args);
System.exit(run);
}
}
- 运行结果
Order_0000002 822.4
Order_0000003 222.8
Order_0000005 222.8
求取TopN的数据
需求
求取Top1运用了GroupBy的规则,排序后,不需要再进行操作,就会自动输出首个数据
如果要获取TopN的数据就需要在Reduce逻辑中添加循环遍历,所有的NullWritable转换为DoubleWritable,其他都不变代码实现
自定义一个javaBean,命名为OrderBean
package cn.itcast.demo6;
import org.apache.hadoop.io.WritableComparable;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class OrderBean implements WritableComparable<OrderBean> {
//定义orderId和price变量
private String orderId;
private Double price;
/**
* 重写compareTo方法
*
* @param o
* @return
*/
@Override
public int compareTo(OrderBean o) {
//先对orderId进行比较,如果相同,将它们的price放一起比较,不同就不比较
int result = this.orderId.compareTo(o.orderId);
//进行判断
if (result == 0) {
int i = this.price.compareTo(o.price);
return -i; //返回i求取最小值,返回-i求取最大值
}
return result;
}
@Override
public void write(DataOutput out) throws IOException {
out.writeUTF(orderId);
out.writeDouble(price);
}
@Override
public void readFields(DataInput in) throws IOException {
this.orderId = in.readUTF();
this.price = in.readDouble();
}
//生成get(),set()方法
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
//生成toString()方法
@Override
public String toString() {
return orderId + "\t" + price;
}
}
定义一个Mapper类
package cn.itcast.demo6;
import org.apache.hadoop.io.DoubleWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import java.io.IOException;
public class GroupMapper extends Mapper<LongWritable, Text, OrderBean, DoubleWritable> {
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
//分割获取到的数据
String[] split = value.toString().split("\t");
//创建orderBean对象
OrderBean orderBean = new OrderBean();
//给orderId赋值
orderBean.setOrderId(split[0]);
//给price赋值
orderBean.setPrice(Double.valueOf(split[2]));
DoubleWritable doubleWritable = new DoubleWritable(Double.valueOf(split[2]));
context.write(orderBean, doubleWritable);
}
}
自定义分区(Partition)规则
package cn.itcast.demo6;
import org.apache.hadoop.io.DoubleWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.mapreduce.Partitioner;
public class GroupPartitioner extends Partitioner<OrderBean, DoubleWritable> {
/**
* 重写分区方法
*
* @param orderBean
* @param doubleWritable
* @param i
* @return
*/
@Override
public int getPartition(OrderBean orderBean, DoubleWritable doubleWritable, int i) {
//参照HashPartitioner的重写方法
return (orderBean.getOrderId().hashCode() & Integer.MAX_VALUE) % i;
}
}
自定义分组(groupingComparator)规则
package cn.itcast.demo6;
import org.apache.hadoop.io.WritableComparable;
import org.apache.hadoop.io.WritableComparator;
public class GroupComparator extends WritableComparator {
//重写无参构造方法,定义反射出来的对象是OrderBean类
public GroupComparator() {
super(OrderBean.class, true);
}
@Override
public int compare(WritableComparable a, WritableComparable b) {
OrderBean first = (OrderBean) a;
OrderBean second = (OrderBean) b;
//比较orderId,如果相同就认为是同一组数据
return first.getOrderId().compareTo(second.getOrderId());
}
}
定义一个Reducer类
package cn.itcast.demo6;
import org.apache.hadoop.io.DoubleWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
public class GroupReducer extends Reducer<OrderBean, DoubleWritable, OrderBean, DoubleWritable> {
/**
* 直接将收到的k2,v2的值转换为k3,v3输出
*
* @param key
* @param values
* @param context
* @throws IOException
* @throws InterruptedException
*/
@Override
protected void reduce(OrderBean key, Iterable<DoubleWritable> values, Context context) throws IOException, InterruptedException {
int i = 0;
for (DoubleWritable value : values) {
i++;
if (i <= 2) {
context.write(key, value);
} else {
break;
}
}
}
}
程序main函数入口
package cn.itcast.demo6;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.DoubleWritable;
import org.apache.hadoop.io.NullWritable;
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;
public class GroupMain extends Configured implements Tool {
@Override
public int run(String[] args) throws Exception {
//获取Job对象
Job job = Job.getInstance(super.getConf(), "myGroupComparator");
//输入数据,设置输入路径
job.setInputFormatClass(TextInputFormat.class);
TextInputFormat.setInputPaths(job, new Path("file:////Volumes/赵壮备份/大数据离线课程资料/5.大数据离线第五天/自定义groupingComparator/input/orders.txt"));
//自定义Map逻辑
job.setMapperClass(GroupMapper.class);
//设置k2,v2输出类型
job.setMapOutputKeyClass(OrderBean.class);
job.setMapOutputValueClass(DoubleWritable.class);
//自定义Partition逻辑
job.setPartitionerClass(GroupPartitioner.class);
//自定义分组逻辑
job.setGroupingComparatorClass(GroupComparator.class);
//自定义reduce逻辑
job.setReducerClass(GroupReducer.class);
//设置k3,v3输出类型
job.setOutputKeyClass(OrderBean.class);
job.setOutputValueClass(DoubleWritable.class);
//输出数据,设置输出路径
job.setOutputFormatClass(TextOutputFormat.class);
TextOutputFormat.setOutputPath(job, new Path("file:////Volumes/赵壮备份/大数据离线课程资料/5.大数据离线第五天/自定义groupingComparator/output_top2"));
//提交任务至集群
boolean b = job.waitForCompletion(true);
return b ? 0 : 1;
}
public static void main(String[] args) throws Exception {
int run = ToolRunner.run(new Configuration(), new GroupMain(), args);
System.exit(run);
}
}
- 运行结果
Order_0000002 822.4 822.4
Order_0000002 522.4 522.4
Order_0000003 222.8 222.8
Order_0000005 222.8 222.8
Order_0000005 25.8 25.8
【Hadoop离线基础总结】MapReduce案例之自定义groupingComparator的更多相关文章
- 【Hadoop离线基础总结】Hue的简单介绍和安装部署
目录 Hue的简单介绍 概述 核心功能 安装部署 下载Hue的压缩包并上传到linux解压 编译安装启动 启动Hue进程 hue与其他框架的集成 Hue与Hadoop集成 Hue与Hive集成 Hue ...
- 【Hadoop离线基础总结】oozie的安装部署与使用
目录 简单介绍 概述 架构 安装部署 1.修改core-site.xml 2.上传oozie的安装包并解压 3.解压hadooplibs到与oozie平行的目录 4.创建libext目录,并拷贝依赖包 ...
- 【Hadoop离线基础总结】impala简单介绍及安装部署
目录 impala的简单介绍 概述 优点 缺点 impala和Hive的关系 impala如何和CDH一起工作 impala的架构及查询计划 impala/hive/spark 对比 impala的安 ...
- 【Hadoop离线基础总结】Hive调优手段
Hive调优手段 最常用的调优手段 Fetch抓取 MapJoin 分区裁剪 列裁剪 控制map个数以及reduce个数 JVM重用 数据压缩 Fetch的抓取 出现原因 Hive中对某些情况的查询不 ...
- 【Hadoop离线基础总结】流量日志分析网站整体架构模块开发
目录 数据仓库设计 维度建模概述 维度建模的三种模式 本项目中数据仓库的设计 ETL开发 创建ODS层数据表 导入ODS层数据 生成ODS层明细宽表 统计分析开发 流量分析 受访分析 访客visit分 ...
- 【Hadoop离线基础总结】Sqoop常用命令及参数
目录 常用命令 常用公用参数 公用参数:数据库连接 公用参数:import 公用参数:export 公用参数:hive 常用命令&参数 从关系表导入--import 导出到关系表--expor ...
- 【Hadoop离线基础总结】MapReduce增强(上)
MapReduce增强 MapReduce的分区与reduceTask的数量 概述 MapReduce当中的分区:物以类聚,人以群分.相同key的数据,去往同一个reduce. ReduceTask的 ...
- 【Hadoop离线基础总结】MapReduce倒排索引建立
MapReduce倒排索引建立 求某些单词在文章中出现多少次 有三个文档的内容,求hello,tom,jerry三个单词在其中各出现多少次 hello tom hello jerry hello to ...
- 【Hadoop离线基础总结】工作流调度器azkaban
目录 Azkaban概述 工作流调度系统的作用 工作流调度系统的实现 常见工作流调度工具对比 Azkaban简单介绍 安装部署 Azkaban的编译 azkaban单服务模式安装与使用 azkaban ...
随机推荐
- JMeter分布式压测-常见问题之( Cannot start. localhost.localdomain is a loopback address)
问题描述: JMeter分布式测试时,以Linux系统作为被测服务器,在其中启动 jmeter-server 服务时出现异常,系统提示如下: [root@localhost bin]# ./jmete ...
- sublime查看项目代码多少行
---------------------sublime 0.右击要查找的文件; 1.勾选正则( .* ); 3.输入正则表达式 ^[ \t]*[^ \t\n\r]+.*$ 0:搜索 \n 是不是 ...
- 从零开始学习docker之在docker中运行springboot项目
一.docker环境配置 首先需要一个安装了docker的服务器(本地或者云服务器),如果没有请看上文,传送门---https://www.cnblogs.com/wdfordream/p/12737 ...
- JavaScript之预编译
javascript是一种解释性弱类型语言,在浏览器中执行时,浏览器会先预览某段代码进行语法分析,检查语法的正确与否,然后再进行预编译,到最后才会从上往下一句一句开始执行这段代码,简单得来说可以表示为 ...
- str_pad 和 filter_var
这两个函数都是php内置函数,filter_var可直接过滤,比如邮箱,ip等,str_pad可补充字符串eg: 1 => 001
- cdn服务器
CDN的基本原理和基础架构 CDN是将源站内容分发至最接近用户的节点,使用户可就近取得所需内容,提高用户访问的响应速度和成功率.解决因分布.带宽.服务器性能带来的访问延迟问题,适用于站点加速.点播.直 ...
- Java语言和C++语言的差异
Java采用了C及C++的语法格式,对于学习过C及C++的程序设计者来说,学习Java将有可能很轻松.但是,如果仔细检查Java语言的许多细节,就会发现Java取消了不少C及C++的特性,并且加入了一 ...
- Mybatis自动生成插件对数据库类型为text的处理
2019独角兽企业重金招聘Python工程师标准>>> 如果数据库中的字段为text或者blob这种大文本类型,在使用MybatisGenerator工具自动生成代码的时候会将其进行 ...
- php-fpm7 启动脚本
[root@bbs init.d]$ cat php-fpm7 #!/bin/sh # DateTime:20170918 # Source function library. . /etc/rc.d ...
- CodeForces - 1047A
A. Little C Loves 3 I time limit per test1 second memory limit per test256 megabytes inputstandard i ...