真正帮你实现—MapReduce统计WordCount词频,并将统计结果按出现次数降序排列

项目整体介绍

对类似WordCount案例的词频统计,并将统计结果按出现次数降序排列。

网上有很多帖子,均用的相似方案,重写某某方法然后。。。运行起来可能会报这样那样的错误,这里实现了一种解决方案,分享出来供大家参考:编写两个MapReduce程序,第一个程序进行词频统计,第二个程序进行降序处理,由于是降序,还需要自定义对象,在对象内部实现降序排序。

一、项目背景及数据集说明

现有某电商网站用户对商品的收藏数据,记录了用户收藏的商品id以及收藏日期,名为buyer_favorite1。buyer_favorite1包含:买家id,商品id,收藏日期这三个字段,数据以“\t”分割,样例展现如下:在这里插入图片描述

二、编写MapReduce程序,统计每个买家收藏商品数量。(即统计买家id出现的次数)

前置说明

1.配置好Hadoop集群环境,并开启相应服务、
2.在hdfs对应路径上先上传好文件,可以自己根据文件路径定义,这里是"hdfs://localhost:9000/mymapreduce1/in/buyer_favorite1"。同时再定义好输出路径
3.这里是整个程序(词频降序)的入口,若只是想统计词频,请注释掉WordCountSortDESC.mainJob2();

package mapreduce;

import java.io.IOException;
import java.util.StringTokenizer;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.*;
import org.apache.hadoop.mapreduce.*;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

public class WordCount {
	public static void main(String[] args) {
		Configuration conf = new Configuration();
		conf.set("yarn,resourcemanager", "bym@d2e674ec1e78");
		try {
			Job job = Job.getInstance(conf, "111");
			job.setJobName("WordCount");
			job.setJarByClass(WordCount.class);
			job.setMapperClass(doMapper.class); // 这里就是设置下job使用继承doMapper类,与定义的内容保持一致
			job.setReducerClass(doReducer.class); // 同上,设置Reduce类型

			job.setMapOutputKeyClass(Text.class); // 如果map的输出和reduce的输出不一样,这里要分别定义好格式
			job.setMapOutputValueClass(IntWritable.class);
			job.setOutputKeyClass(Text.class);
			job.setOutputValueClass(Text.class);

			Path in = new Path(
					"hdfs://localhost:9000/mymapreduce1/in/buyer_favorite1");
			Path out = new Path("hdfs://localhost:9000/mymapreduce1/out");
			FileInputFormat.addInputPath(job, in);
			FileOutputFormat.setOutputPath(job, out);
			if (job.waitForCompletion(true)) {
				System.out.println("WordCount completition");
				WordCountSortDESC.mainJob2();
				System.out.println("diaoyong");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		// System.exit(job.waitForCompletion(true) ? 0 : 1);
	}

	// 第一个Object表示输入key的类型、是该行的首字母相对于文本文件的首地址的偏移量;
	// 第二个Text表示输入value的类型、存储的是文本文件中的一行(以回车符为行结束标记);
	// 第三个Text表示输出键的类型;第四个IntWritable表示输出值的类型
	public static class doMapper extends
			Mapper<LongWritable, Text, Text, IntWritable> {
		public static final IntWritable one = new IntWritable(1);
		public static Text word = new Text();

		@Override
		// 前面两个Object key,Text value就是输入的key和value,第三个参数Context
		// context是可以记录输入的key和value。
		protected void map(LongWritable key, Text value, Context context)
				throws IOException, InterruptedException {

			// StringTokenizer是Java工具包中的一个类,用于将字符串进行拆分
			StringTokenizer tokenizer = new StringTokenizer(value.toString(),
					"\t");
			// 返回当前位置到下一个分隔符之间的字符串, 并把字符串设置成Text格式
			word.set(tokenizer.nextToken());
			context.write(word, one);
		}
	}

	// 参数依次表示是输入键类型,输入值类型,输出键类型,输出值类型
	public static class doReducer extends
			Reducer<Text, IntWritable, Text, Text> {

		@Override
		// 输入的是键值类型,其中值类型为归并后的结果,输出结果为Context类型
		protected void reduce(Text key, Iterable<IntWritable> values,
				Context context) throws IOException, InterruptedException {
			int sum = 0;
			for (IntWritable value : values) {
				sum += value.get();
			}
			context.write(key, new Text(Integer.toString(sum)));
		}
	}
}

三、核心问题:再次编写MapReduce程序,将上一步统计的结果降序排列

前置说明

1.这里将上一步统计的结果作为输入,进行第二次mapreduce程序的运行。因此要注意输入路径与上一步的输出路径保持一致。
2.由于是降序排列,只能自定义FlowBean对象,内部实现排序方式。否则,升序可以利用shuffle机制默认的排序策略不用自定义对象排序,这里不再叙述。

package mapreduce;

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

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.*;
import org.apache.hadoop.mapreduce.*;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

public class WordCountSortDESC {
	public static void mainJob2() {
		Configuration conf = new Configuration();
		conf.set("yarn,resourcemanager", "bym@d2e674ec1e78");
		try {
			Job job = Job.getInstance(conf, "1111");
			job.setJobName("WordCountSortDESC");
			job.setJarByClass(WordCountSortDESC.class);
			job.setMapperClass(TwoMapper.class); // 这里就是设置下job使用继承doMapper类,与定义的内容保持一致
			job.setReducerClass(TwoReducer.class); // 同上,设置Reduce类型
			
			job.setMapOutputKeyClass(FlowBean.class);
			job.setMapOutputValueClass(Text.class);

			job.setOutputKeyClass(Text.class);
			job.setOutputValueClass(FlowBean.class);

			Path in = new Path("hdfs://localhost:9000/mymapreduce1/out");
			Path out = new Path("hdfs://localhost:9000/mymapreduce1/out555");
			FileInputFormat.addInputPath(job, in);
			FileOutputFormat.setOutputPath(job, out);
			if (job.waitForCompletion(true)) {
				System.out.println("DESC Really Done");
			}
		} catch (Exception e) {
			System.out.println("errormainJob2-----------");
		}
	}

	public static class TwoMapper extends Mapper<Object, Text, FlowBean, Text> {
		private FlowBean outK = new FlowBean();
		private Text outV = new Text();

		@Override
		protected void map(Object key, Text value, Context context)
				throws IOException, InterruptedException {
			// 由于真实的数据存储在文件块上,这里是因为数据量较小,可以保证只在一个文件块
			FileSplit fs = (FileSplit) context.getInputSplit();
			if (fs.getPath().getName().contains("part-r-00000")) {

				// 1 获取一行数据
				String line = value.toString();

				// 2 按照"\t",切割数据
				String[] split = line.split("\t");

				// 3 封装outK outV
				outK.setNumber(Long.parseLong(split[1]));
				outV.set(split[0]);

				// 4 写出outK outV
				context.write(outK, outV);
			} else {
				System.out.println("error-part-r-------------------");
			}
		}
	}

	public static class TwoReducer extends
			Reducer<FlowBean, Text, Text, FlowBean> {
		@Override
		protected void reduce(FlowBean key, Iterable<Text> values,
				Context context) throws IOException, InterruptedException {

			// 遍历values集合,循环写出,避免总流量相同的情况
			for (Text value : values) {
				// 调换KV位置,反向写出
				context.write(value, key);
			}
		}
	}


	public static class FlowBean implements WritableComparable<FlowBean> {

		private long number;

		// 提供无参构造
		public FlowBean() {
		}

		public long getNumber() {
			return number;
		}

		public void setNumber(long number) {
			this.number = number;
		}

		// 实现序列化和反序列化方法,注意顺序一定要一致
		@Override
		public void write(DataOutput out) throws IOException {
			out.writeLong(this.number);
		}

		@Override
		public void readFields(DataInput in) throws IOException {
			this.number = in.readLong();
		}

		@Override
		public String toString() {
			return number + "\t";
		}

		@Override
		public int compareTo(FlowBean o) {
			// 按照总流量比较,倒序排列
			if (this.number > o.number) {
				return -1;
			} else if (this.number < o.number) {
				return 1;
			} else {
				return 0;
			}
		}
	}

}

四、结果展示:

执行查看文件命令

hadoop fs -cat /mymapreduce1/out555/part-r-00000

在这里插入图片描述
可以发现已经进行了降序排列,其他数据集结果应类似。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/51810.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

8年测试整理,自动化测试框架从0到1实施,一篇打通自动化...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 框架本身一般不完…

tauri在github上进行自动更新打包并发版过程,实战操作避坑

从网上找了很多很多的文章&#xff0c;结果还是入坑了&#xff0c;一个问题找了一天才解决&#xff1a; Error A public key has been found, but no private key. Make sure to set TAURI_PRIVATE_KEY environment variable. 596 ELIFECYCLE  Command failed with exit code…

NLP实验案例100个(1-5)

实验一 array数组&#xff08;01&#xff09; 一、实验目的及要求 1.安装numpy环境&#xff0c;掌握基本的数组知识以及操作。 二、实验设备&#xff08;环境&#xff09;及要求 开发环境&#xff1a;jupyter notebook 开发语言以及相关的库&#xff1a;python开发语言、nu…

hive删除数据进行恢复

在实际开发或生产中&#xff0c;hive表如果被误删&#xff0c;如被truncate或是分区表的分区被误删了&#xff0c;只要在回收站的清空周期内&#xff0c;是可以恢复数据的&#xff0c;步骤如下&#xff1a; &#xff08;1&#xff09; 先找到被删除数据的存放目录&#xff0c;…

CF1833 A-E

A题 题目链接&#xff1a;https://codeforces.com/problemset/problem/1833/A 基本思路&#xff1a;for循环遍历字符串s&#xff0c;依次截取字符串s的子串str&#xff0c;并保存到集合中&#xff0c;最后输出集合内元素的数目即可 AC代码&#xff1a; #include <iostrea…

MD-MTSP:斑马优化算法ZOA求解多仓库多旅行商问题MATLAB(可更改数据集,旅行商的数量和起点)

一、斑马优化算法ZOA 斑马优化算法&#xff08;Zebra Optimization Algorithm&#xff0c;ZOA&#xff09;Eva Trojovsk等人于2022年提出&#xff0c;其模拟斑马的觅食和对捕食者攻击的防御行为。斑马优化算法&#xff08;Zebra Optimization Algorithm&#xff0c;ZOA&#x…

14-测试分类

1.按照测试对象划分 ①界面测试 软件只是一种工具&#xff0c;软件与人的信息交流是通过界面来进行的&#xff0c;界面是软件与用户交流的最直接的一层&#xff0c;界面的设计决定了用户对设计的软件的第一印象。界面如同人的面孔&#xff0c;具有吸引用户的直接优势&#xf…

一篇文章彻底搞懂TCP协议!

文章目录 1. TCP协议的引入2. TCP协议的特点3. TCP协议格式3.1 序号与确认序号3.2 发送缓冲区与接收缓冲区3.3 窗口大小3.4 六个标志位 4. 确认应答机制5. 超时重传机制6. 连接管理机制6.1 三次握手6.2 四次挥手 7. 流量控制8. 滑动窗口9. 拥塞控制10. 延迟应答11. 捎带应答12.…

Python爬虫的urlib的学习(学习于b站尚硅谷)

目录 一、页面结构的介绍  1.学习目标  2.为什么要了解页面&#xff08;html&#xff09;  3. html中的标签&#xff08;仅介绍了含表格、无序列表、有序列表、超链接&#xff09;  4.本节的演示 二、Urllib  1.什么是互联网爬虫&#xff1f;  2.爬虫核心  3.爬虫…

Linux环境安装MySQL(详细教程)

1、下载MySQL MySQL官网&#xff1a;MySQLhttps://www.mysql.com/ 下载社区版&#xff08;免费&#xff0c;但不提供技术支持&#xff09; 简单说明一下rpm和tar包的区别&#xff1a; tar 只是一种压缩文件格式&#xff0c;所以&#xff0c;它只是把文件压缩打包 rpm&#xf…

初步了解预训练语言模型BERT

本文字数&#xff1a;&#xff1a;4024字 预计阅读时间&#xff1a;12分钟 BERT是由Google提出的预训练语言模型&#xff0c;它基于transformer架构&#xff0c;被广泛应用于自然语言处理领域&#xff0c;是当前自然语言处理领域最流行的预训练模型之一。而了解BERT需要先了解注…

Verilog语法学习——LV6_多功能数据处理器

LV6_多功能数据处理器 题目来源于牛客网 [牛客网在线编程_Verilog篇_Verilog快速入门 (nowcoder.com)](https://www.nowcoder.com/exam/oj?page1&tabVerilog篇&topicId301) 题目 描述 根据指示信号select的不同&#xff0c;对输入信号a,b实现不同的运算。输入信号a…

Ubuntu的安装与部分配置

该教程使用的虚拟机是virtuabox&#xff0c;镜像源的版本是ubuntu20.04.5桌面版 可通过下面的链接在Ubuntu官网下载&#xff1a;Alternative downloads | Ubuntu 也可直接通过下面的链接进入百度网盘下载【有Ubuntu20.04.5与hadoop3.3.2以及jdk1.8.0_162&#xff0c;该篇需要使…

ChatGPT结合知识图谱构建医疗问答应用 (一) - 构建知识图谱

一、ChatGPT结合知识图谱 在本专栏的前面文章中构建 ChatGPT 本地知识库问答应用&#xff0c;都是基于词向量检索 Embedding 嵌入的方式实现的&#xff0c;在传统的问答领域中&#xff0c;一般知识源采用知识图谱来进行构建&#xff0c;但基于知识图谱的问答对于自然语言的处理…

使用预训练的2D扩散模型改进3D成像

扩散模型已经成为一种新的生成高质量样本的生成模型&#xff0c;也被作为有效的逆问题求解器。然而&#xff0c;由于生成过程仍然处于相同的高维&#xff08;即与数据维相同&#xff09;空间中&#xff0c;极高的内存和计算成本导致模型尚未扩展到3D逆问题。在本文中&#xff0…

内部类(下)匿名内部类,静态内部类的使用

文章目录 前言一、匿名内部类二、静态内部类三、内部类的继承总结 前言 该文将会介绍匿名内部类、静态内部类的使用&#xff0c;补充完毕java中的内部类。补充内容为向上转型为接口、使用this关键字获取引用、内部类的继承。 一、匿名内部类 定义&#xff1a;没有名称的内部类。…

嵌入式开发:单片机嵌入式Linux学习路径

SOC&#xff08;System on a Chip&#xff09;的本质区别在于架构和功能。低端SOC如基于Cortex-M架构的芯片&#xff0c;如STM32和NXP LPC1xxx系列&#xff0c;不具备MMU&#xff08;Memory Management Unit&#xff09;&#xff0c;适用于轻量级实时操作系统如uCOS和FreeRTOS。…

Matlab Image Processing toolbox 下载安装方法

当安装好Matlab之后&#xff0c;发现没有Image Processing toolbox这个图像处理工具箱 从新安装一遍&#xff0c; 选上 Image Processing toolbox 但是不用选matlab即可 1.找到之前安装时的Setup安装程序包&#xff0c;按照之前安装Matlab步骤&#xff0c;到选择需要安装的Ma…

360T7路由器进行WiFi无线中继教程

360T7路由器进行WiFi中继教程 1. 概述2. 360T7路由器进行WiFi中继实现教程2.1 登录路由器管理界面2.2 选择上网方式2.3 搜索WiFi2.4 连接WiFi2.5 点击确认2.6 在主页面查看网络 1. 概述 中继路由系统由一组中继路由器组成&#xff0c;为不能交换路由信息的路由域提供中继路由。…

本土机器视觉创业企业涌现,深眸科技携手AI+3D视觉勇闯小场景赛道

随着工业自动化技术向智能化方向发展&#xff0c;人工智能实现快速落地&#xff0c;机器视觉应用产品在算力、算法和技术等方面得到持续升级&#xff0c;助力中国机器视觉行业进入高质量发展阶段。 在制造业转型升级、新兴产业发展的过程中&#xff0c;中国作为全球制造中心之…