Hadoop(2):常见的MapReduce[在Ubuntu中运行!]

1 以词频统计为例子介绍 mapreduce怎么写出来的

弄清楚MapReduce的各个过程:

将文件输入后,返回的<k1,v1>代表的含义是:k1表示偏移量,即v1的第一个字母在文件中的索引(从0开始数的);v1表示对应的一整行的值

map阶段:将每一行的内容按照空格进行分割后作为k2,将v2的值写为1后输出

reduce阶段:将相同的k2合并后,输出

1.1 创建Mapper、Reducer、Driver类

创建这三种类用的是一种方法,用Mapper举例如下:

注意选择父类

1.2 map阶段代码书写

(1)mapper源码

本来可以按住ctrl键后,点击open 后查看mapper源代码,但是在虚拟机里一直调不出来。所以从网上搜索出具体代码如下:

/*** Licensed to the Apache Software Foundation (ASF) under one* or more contributor license agreements.  See the NOTICE file* distributed with this work for additional information* regarding copyright ownership.  The ASF licenses this file* to you under the Apache License, Version 2.0 (the* "License"); you may not use this file except in compliance* with the License.  You may obtain a copy of the License at**     http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package org.apache.hadoop.mapreduce;import java.io.IOException;import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.io.RawComparator;
import org.apache.hadoop.io.compress.CompressionCodec;
import org.apache.hadoop.mapreduce.task.MapContextImpl;@InterfaceAudience.Public
@InterfaceStability.Stable
public class Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT> {/*** The <code>Context</code> passed on to the {@link Mapper} implementations.*/public abstract class Contextimplements MapContext<KEYIN,VALUEIN,KEYOUT,VALUEOUT> {}/*** Called once at the beginning of the task.*/protected void setup(Context context) throws IOException, InterruptedException {// NOTHING}/*** Called once for each key/value pair in the input split. Most applications* should override this, but the default is the identity function.*/@SuppressWarnings("unchecked")protected void map(KEYIN key, VALUEIN value, Context context) throws IOException, InterruptedException {context.write((KEYOUT) key, (VALUEOUT) value);}/*** Called once at the end of the task.*/protected void cleanup(Context context) throws IOException, InterruptedException {// NOTHING}/*** Expert users can override this method for more complete control over the* execution of the Mapper.* @param context* @throws IOException*/public void run(Context context) throws IOException, InterruptedException {setup(context);try {while (context.nextKeyValue()) {map(context.getCurrentKey(), context.getCurrentValue(), context);}} finally {cleanup(context);}}
}

(2)修改的注意事项

注意我们需要修改的只是map方法 

1. Mapper组件开发方式:自定义一个类,继承Mapper
2. Mapper组件的作用是定义每一个MapTask具体要怎么处理数据。例如一个文件,256MB,会生成2个MapTask(每个切片大小,默认是128MB,所以MapTask的多少有处理的数据大小来决定)。即2个MapTask处理逻辑是一样的,只是每个MapTask处理的数据不一样。
3. 下面是Mapper类中的4个泛型含义:a.泛型一:KEYIN:LongWritable,对应的Mapper的输入key。输入key是每行的行首偏移量b.泛型二: VALUEIN:Text,对应的Mapper的输入Value。输入value是每行的内容c.泛型三:KEYOUT:对应的Mapper的输出key,根据业务来定义d.泛型四:VALUEOUT:对应的Mapper的输出value,根据业务来定义
4. 注意:初学时,KEYIN和VALUEIN写死(LongWritable,Text)。KEYOUT和VALUEOUT不固定,根据业务来定
5. Writable机制是Hadoop自身的序列化机制,常用的类型:a. LongWritable b. Text(String)c. IntWritabled. NullWritable
6. 定义MapTask的任务逻辑是通过重写map()方法来实现的。
读取一行数据就会调用一次此方法,同时会把输入key和输入value进行传递
7. 在实际开发中,最重要的是拿到输入value(每行内容)
8. 输出方法:通过context.write(输出key,输出value)
9. 开发一个MapReduce程序(job),Mapper可以单独存储,此时,最后的输出的结果文件内容就是Mapper的输出。
10. Reducer组件不能单独存在,因为Reducer要依赖于Mapper的输出。当引入了Reducer之后,最后输出的结果文件的结果就是Reducer的输出。

(3)具体实例

重写map方法:输入map后 按住"alt"加"?" 后,就可以自动补全代码!

然后进行编写:

import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;public class WordMapper extends Mapper<LongWritable, Text, Text, IntWritable> {@Overrideprotected void map(LongWritable key, Text value, Mapper<LongWritable, Text,  Text,IntWritable>.Context context)throws IOException, InterruptedException {//将value转换成字符串,再将其转化成字符串数组String line = value.toString(); //hello wordString[] wordarr = line.split(" ");for (String word:wordarr) {context.write(new Text(word), new IntWritable(1));}		}}

 1.3  reducer阶段代码的书写

(1)reducer源码

和mapper差不多

(2)修改时的注意事项

1. Reducer组件用于接收Mapper组件的输出
2. reduce的输入key,value需要和mapper的输出key,value类型保持一致
3. reduce的输出key,value类型,根据具体业务决定
4. reduce收到map的输出,会按相同的key做聚合,
形成:key Iterable 形式然后通过reduce方法进行传递
5. reduce方法中的Iterable是一次性的,即遍历一次之后,再遍历,里面就没有数据了。
所以,在某些业务场景,会涉及到多次操作此迭代器,处理的方法是
:①先创建一个List  ②把Iterable装到List ③多次去使用List即可

(3)具体案例

注意:IntWriter是一个迭代器!context负责输出!

import java.io.IOException;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.examples.SecondarySort.Reduce;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;public class WordReducer extends Reducer<Text, IntWritable, Text, IntWritable> {@Overrideprotected void reduce(Text key, Iterable<IntWritable> values,Reducer<Text, IntWritable, Text, IntWritable>.Context context) throws IOException, InterruptedException {int total =0;    for (IntWritable value:values) {total = total + value.get();		    	}context.write(key, new IntWritable(total));}

1.4 主函数代码的书写

【1】还未进行reducer阶段时

(1)主函数也就是驱动函数一般包含以下几个阶段:

注意:实例化job、设置输入文件地址、输出文件地址。这三个代码是固定的!!!每次都这样哦

import java.io.IOException;
public class WordDriver {public static void main(String[] args) throws Exception {//1.实例化jobConfiguration conf = new Configuration();String[] otherArgs = (new GenericOptionsParser(conf, args)).getRemainingArgs();if(otherArgs.length < 2) {System.err.println("Usage: wordcount <in> [<in>...] <out>");System.exit(2);}Job job = Job.getInstance(conf, "word count");//2.关联class文件job.setJarByClass(WordDriver.class);job.setMapperClass(WordMapper.class);//3.设置"mapper"的输出数据类型job.setOutputKeyClass(Text.class);job.setOutputValueClass(IntWritable.class);//4.设置reducer的是输出数据类型//5.设置输入文件路径for(int i = 0; i < otherArgs.length - 1; ++i) {FileInputFormat.addInputPath(job, new Path(otherArgs[i]));}//6.设置输出文件路径FileOutputFormat.setOutputPath(job, new Path(otherArgs[otherArgs.length - 1]));		 //7.提交job文件!System.exit(job.waitForCompletion(true)?0:1);}}

输出的结果为:

!!!!!!!!就是我们map阶段应该产生的结果!!!

【2】进行reducer阶段后

import java.io.IOException;
public class WordDriver {public static void main(String[] args) throws Exception {//1.实例化jobConfiguration conf = new Configuration();String[] otherArgs = (new GenericOptionsParser(conf, args)).getRemainingArgs();if(otherArgs.length < 2) {System.err.println("Usage: wordcount <in> [<in>...] <out>");System.exit(2);}Job job = Job.getInstance(conf, "word count");//2.关联class文件job.setJarByClass(WordDriver.class);job.setMapperClass(WordMapper.class);job.setReducerClass(WordReducer.class);//3.设置"mapper"的输出数据类型job.setOutputKeyClass(Text.class);job.setOutputValueClass(IntWritable.class);//4.设置reducer的是输出数据类型job.setOutputKeyClass(Text.class);job.setOutputValueClass(IntWritable.class);//5.设置输入文件路径for(int i = 0; i < otherArgs.length - 1; ++i) {FileInputFormat.addInputPath(job, new Path(otherArgs[i]));}//6.设置输出文件路径FileOutputFormat.setOutputPath(job, new Path(otherArgs[otherArgs.length - 1]));		 //7.提交job文件!System.exit(job.waitForCompletion(true)?0:1);}}

1.5 在Ubuntu上运行

1.5.1 编译打包程序

现在就可以编译上面编写的代码。可以直接点击Eclipse工作界面上部的运行程序的快捷按钮,当把鼠标移动到该按钮上时,在弹出的菜单中选择“Run as”,继续在弹出来的菜单中选择“Java Application”,如下图所示。

然后,会弹出如下图所示界面。

点击界面右下角的“OK”按钮,开始运行程序。程序运行结束后,会在底部的“Console”面板中显示运行结果信息(如下图所示)。

下面就可以把Java应用程序打包生成JAR包,部署到Hadoop平台上运行。现在可以把词频统计程序放在“/usr/local/hadoop/myapp”目录下。如果该目录不存在,可以使用如下命令创建:

cd /usr/local/hadoop
mkdir myapp

首先,请在Eclipse工作界面左侧的“Package Explorer”面板中,在工程名称“WordCount”上点击鼠标右键,在弹出的菜单中选择“Export”,如下图所示。

然后,会弹出如下图所示界面。

在该界面中,选择“Runnable JAR file”,然后,点击“Next>”按钮,弹出如下图所示界面。

在该界面中,“Launch configuration”用于设置生成的JAR包被部署启动时运行的主类,需要在下拉列表中选择刚才配置的类“WordCount-WordCount”。在“Export destination”中需要设置JAR包要输出保存到哪个目录,比如,这里设置为“/usr/local/hadoop/myapp/WordCount.jar”。在“Library handling”下面选择“Extract required libraries into generated JAR”。然后,点击“Finish”按钮,会出现如下图所示界面。

可以忽略该界面的信息,直接点击界面右下角的“OK”按钮,启动打包过程。打包过程结束后,会出现一个警告信息界面,如下图所示。

可以忽略该界面的信息,直接点击界面右下角的“OK”按钮。至此,已经顺利把WordCount工程打包生成了WordCount.jar。可以到Linux系统中查看一下生成的WordCount.jar文件,可以在Linux的终端中执行如下命令:

cd /usr/local/hadoop/myapp
ls

1.5.2 运行程序

在运行程序之前,需要启动Hadoop,命令如下:

cd /usr/local/hadoop
./sbin/start-dfs.sh

在启动Hadoop之后,需要首先删除HDFS中与当前Linux用户hadoop对应的input和output目录(即HDFS中的“/user/hadoop/input”和“/user/hadoop/output”目录),这样确保后面程序运行不会出现问题,具体命令如下:

cd /usr/local/hadoop
./bin/hdfs dfs -rm -r input
./bin/hdfs dfs -rm -r output

然后,再在HDFS中新建与当前Linux用户hadoop对应的input目录,即“/user/hadoop/input”目录,具体命令如下:

cd /usr/local/hadoop
./bin/hdfs dfs -mkdir input

然后,把之前在中在Linux本地文件系统中新建的文件wordfile1.txt(假设这个文件位于“/usr/local/hadoop”目录下,并且里面包含了一些英文语句),上传到HDFS中的“/user/hadoop/input”目录下,命令如下:

cd /usr/local/hadoop
./bin/hdfs dfs -put ./wordfile1.txt input

如果HDFS中已经存在目录“/user/hadoop/output”,则使用如下命令删除该目录:

cd /usr/local/hadoop
./bin/hdfs dfs -rm -r /user/hadoop/output

现在,就可以在Linux系统中,使用hadoop jar命令运行程序,命令如下:

cd /usr/local/hadoop
./bin/hadoop jar ./myapp/WordDriver.jar input output

上面命令执行以后,当运行顺利结束时,屏幕上会显示类似如下的信息:

词频统计结果已经被写入了HDFS的“/user/hadoop/output”目录中,可以执行如下命令查看词频统计结果:

cd /usr/local/hadoop
./bin/hdfs dfs -cat output/*

上面命令执行后,会在屏幕上显示如下词频统计结果:

Hadoop  2
I   2
Spark   2
fast    1
good    1
is  2
love    2

至此,词频统计程序顺利运行结束。需要注意的是,如果要再次运行WordCount.jar,需要首先删除HDFS中的output目录,否则会报错。

最后关闭hadoop程序:

cd /usr/local/hadoop
./sbin/stop-dfs.sh

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot学习笔记-01-springboot-helloworld的编写以及原理初步了解(自动装配)

文章目录原理初探主程序关于spring boot&#xff0c;谈谈你的理解&#xff1a;微服务阶段原理初探 pom.xml spring-boot-dependencies&#xff1a;核心依赖在父工程中&#xff01;我们在写或者引入一些springboot依赖的时候&#xff0c;不需要指定版本&#xff0c;就因为有这…

2022年:机器人技术的重大革命

来源&#xff1a;ScienceAI编辑&#xff1a;萝卜皮一段时间以来&#xff0c;跟踪机器人技术发展的人已经注意到该领域的一场无声革命。虽然自动驾驶汽车占据了所有的头条新闻&#xff0c;但人工智能、机器视觉和机器学习的交叉领域正在迅速成为下一阶段机器人技术的基础。通过将…

陈天奇高赞文章:新一代深度学习编译技术变革和展望

来源&#xff1a;机器之心作者&#xff1a;陈天奇陈天奇是机器学习领域著名的青年华人学者之一&#xff0c;本科毕业于上海交通大学ACM班&#xff0c;博士毕业于华盛顿大学计算机系&#xff0c;研究方向为大规模机器学习。在本文中&#xff0c;陈天奇回答了目前深度学习编译技术…

操作系统欢乐笔记-01-带你推开操作系统的大门(雾)

B站-操作系统-哈尔并工业大学-劝退警告223 文章目录1.什么是操作系统&#xff1f;什么是操作系统&#xff1f;小目标&#xff1f;2.揭开钢琴的盖子熟悉的win开机画面从白纸到图灵机冯-诺依曼一拍脑袋瓜&#xff0c;他说摁下开机键这段不是rap 223 劝退警告emmmmm1.什么是操作系…

2022年值得关注的22项新兴技术

来源&#xff1a;参考消息网英国《经济学人》网站11月8日发表题为《下一个是什么&#xff1f;2022年值得关注的22项新兴技术》的文章。在文章列举的22项新技术中&#xff0c;既有今年大热的“元宇宙”、太空旅游、脑机接口&#xff0c;也有备受期待的量子计算、艾滋病病毒疫苗……

分别安装搭建lamp服务环境

一、 分别安装搭建lamp服务环境 准备工作&#xff1a; 1、配置防火墙&#xff0c;开启80端口、3306端口vi /etc/sysconfig/iptables-A INPUT -m state –state NEW -m tcp -p tcp –dport 80 -j ACCEPT #允许80端口通过防火墙-A INPUT -m state –state NEW -m tcp -p tcp –dp…

springdata学习笔记-01-helloworld-(暂时不全223)

第一天 orm思想和hibernate以及jpa的概述和jpd的基本操作 传统jdbc操作 获取链接创建statement对象可以对占位符赋值发送查询 操作繁琐占位符赋值麻烦 orm思想 主要目的&#xff1a;操作实体类就相当于操作数据库表建立两个映射关系 实体类和表的映射关系实体类中属性和表中…

nginx学习笔记-01nginx入门,环境搭建,常见命令

nginx学习笔记-01nginx入门&#xff0c;环境搭建&#xff0c;常见命令 文章目录nginx学习笔记-01nginx入门&#xff0c;环境搭建&#xff0c;常见命令1.nginx的基本概念2.nginx的安装&#xff0c;常用命令和配置文件3.nginx配置实例1.nginx的基本概念 nginx是什么&#xff0c;做…

MIT博士用概率编程让AI和人类一样看三维|NeurIPS 2021

来源&#xff1a;机器学习研究组订阅人与AI之间最大的区别就是对常识的利用&#xff01;无论各种AI模型在各大排行榜以何种性能超越了人类&#xff0c;它们在常识的利用上仍然远远不及人类&#xff0c;而这也正是目前AI研究中需要面临的一个巨大的挑战。对于自然语言处理的研究…

Unity Shader 2D水流效果

水流的模拟主要运用了顶点变换和纹理动画的结合&#xff1b; 顶点变换中&#xff0c;利用正弦函数模拟河流的大致形态&#xff0c;例如波长&#xff0c;振幅等。 纹理动画中&#xff0c;将纹理坐标朝某一方向持续滚动以形成流动的效果。 脚本如下&#xff1a; 1 Shader "M…

2022年智能家居十大预测新鲜出炉:全屋智能驶入快车道?健身镜成新宠……

来源&#xff1a;物联网智库 2021年接近尾声&#xff0c;这一年&#xff0c;新冠病毒仍旧没有离开地球&#xff0c;而在疫情常态化、工作与生活回归正轨之余&#xff0c;人们对于网络与虚拟世界的依赖度也陡然骤增。这一转变无疑将极大拉动消费端的数字化产业发展&#xff0c;除…

数据结构与算法——动态规划

文章目录1.内容概述2.爬楼梯2.1 题目描述2.算法思想2.3 代码实现3.打家劫舍3.1 题目描述3.2 算法思路3.3 代码实现4.最大子序和4.1 题目描述4.2 算法思路4.3 代码思路5. 零钱兑换5.1 题目描述5.2 算法思路5.3 代码实现6.三角形最小路径和6.1 题目描述6.2 算法思路6.3 代码实现7…

vue学习笔记-01-前端的发展历史(从后端到前端,再到前后端分离,再到全栈)

vue学习笔记-01-前端的发展历史&#xff08;从后端到前端&#xff0c;再到前后端分离&#xff0c;再到全栈&#xff09; 这篇文章是博主在看vue-前端发展简史的时候做的笔记&#xff0c;以供后续学习复习 文章目录vue学习笔记-01-前端的发展历史&#xff08;从后端到前端&#…

黑客帝国「缸中之脑」有眉目了?培养皿中百万人脑细胞学会打乒乓球,仅用了5分钟...

来源&#xff1a;机器之心编辑&#xff1a;张倩、杜伟既然生物神经元如此高效&#xff0c;为什么不拿来用呢&#xff1f;最新版本的《黑客帝国》还有两天才会上映&#xff0c;但最近的一些科技进展总让我们觉得&#xff0c;导演描述的世界似乎离我们越来越近了。其中一个进展来…

《Science》基因组比对的革命性技术

来源&#xff1a;生物通加州大学圣克鲁斯基因组研究所(UC Santa Cruz Genomics Institute)的研究人员推出了一种名为“长颈鹿”(Giraffe)的新工具&#xff0c;可以有效地将新的基因组序列绘制到代表多种不同人类基因组序列的“泛基因组”(pangenome)上。使用泛基因组学方法而不…

vue学习笔记-02-前端的发展历史浅谈mmvm设计理念

vue学习笔记-02-前端的发展历史浅谈mmvm设计理念 文章目录1. MVVM模式的实现者2.第一个vue程序3.什么是mvvm&#xff1f;4.为什么要用mvvm&#xff1f;5.mvvm的组成部分7.MVVM 模式的实现者8.为什么要使用 Vue.js1. MVVM模式的实现者 Model:模型层&#xff0c;在这里表示JavaSc…

linux——select、poll、epoll

文章目录1.多路I/O转接服务器2.select3.select代码4.poll5.epoll5.1 基础API5.3 epoll代码5.4 边沿触发和水平触发5.4.1 水平出发LT5.4.2 边缘触发5.4.3 服务器的边缘触发和水平触发5.4 边缘触发但是能一次读完6.epoll反应堆模型6.1 反应堆模型6.2 epoll反应堆代码7.心跳包8.线…

年终盘点:2021年中国科技的重大突破

来源&#xff1a;科技日报2021年已经步入尾声&#xff0c;过去的一年是科技界屡创新高、收获满仓的一年。这一年&#xff0c;恰逢中国共产党百年华诞&#xff0c;我国科技界更是取得多项重要突破。量子计算获得重大进展&#xff0c;使我国成为唯一在两个物理体系中实现量子计算…

vue学习笔记-03-浅谈组件-概念,入门,如何用props给组件传值?

vue学习笔记-03-浅谈组件-概念&#xff0c;入门&#xff0c;如何用props给组件传值&#xff1f; 文章目录vue学习笔记-03-浅谈组件-概念&#xff0c;入门&#xff0c;如何用props给组件传值&#xff1f;什么是组件&#xff1f;为什么要使用组件&#xff1f;如何使用组件呢&…

盘点:2021年度物理学十大突破|《物理世界》

来源&#xff1a;物理世界作者&#xff1a;哈米什约翰斯顿&#xff08;Hamish Johnston&#xff09;译者&#xff1a;王晓涛、乔琦2021年12月14日&#xff0c;《物理世界》&#xff08;Physics World&#xff09;编辑从其网站发表的近600项研究进展中评选出了年度物理学领域十大…