MapReduce编程基础

article/2025/10/16 17:47:02

(一)实现词频统计的基本的MapReduce编程。

①在/user/hadoop/input文件夹(该文件夹为空),创建文件wordfile1.txtwordfile2.txt上传到HDFS中的input文件夹下。
文件wordfile1.txt的内容如下:
I love Spark
I love Hadoop
文件wordfile2.txt的内容如下:
Hadoop is good
Spark is fast
②启动Eclipse,启动以后会弹出如下图所示界面,提示设置工作空间(workspace)。可以直接采用默认的设置“/home/hadoop/workspace”,点击“OK”按钮。可以看出,由于当前是采用hadoop用户登录了Linux系统,因此,默认的工作空间目录位于hadoop用户目录“/home/hadoop”下。
在这里插入图片描述
Eclipse启动以后,选择“File–>New–>Java Project”菜单,开始创建一个Java工程。
在这里插入图片描述
④在“Project name”后面输入工程名称“WordCount”,选中“Use default location”,让这个Java工程的所有文件都保存到“/home/hadoop/workspace/WordCount”目录下。在“JRE”这个选项卡中,可以选择当前的Linux系统中已经安装好的JDK,比如jdk1.8.0_162。然后,点击界面底部的“Next>”按钮,进入下一步的设置。
在这里插入图片描述
⑤进入下一步的设置以后,需要在该界面中加载该Java工程所需要用到的JAR包,这些JAR包中包含了与Hadoop相关的Java API。这些JAR包都位于Linux系统的Hadoop安装目录下,对于本教程而言,就是“/usr/local/hadoop/share/hadoop”目录下。点击界面中的“Libraries”选项卡,然后,点击界面右侧的“Add External JARs…”按钮,弹出如下图所示界面。
在这里插入图片描述
⑥在该界面中,上面有一排目录按钮(即“usr”、“local”、“hadoop”、“share”、“hadoop”、“mapreduce”和“lib”),当点击某个目录按钮时,就会在下面列出该目录的内容。
为了编写一个MapReduce程序,一般需要向Java工程中添加以下JAR包:
a.“/usr/local/hadoop/share/hadoop/common”目录下的hadoop-common-3.1.3.jarhaoop-nfs-3.1.3.jar
b.“/usr/local/hadoop/share/hadoop/common/lib”目录下的所有JAR包;
c.“/usr/local/hadoop/share/hadoop/mapreduce”目录下的所有JAR包,但是,不包括jdiffliblib-examplessources目录。
在这里插入图片描述
⑦编写一个Java应用程序,即WordCount.java。在Eclipse工作界面左侧的“Package Explorer”面板中(如下图所示),找到刚才创建好的工程名称“WordCount”,然后在该工程名称上点击鼠标右键,在弹出的菜单中选择“New–>Class”菜单。
在这里插入图片描述
⑧选择“New–>Class”菜单以后会出现如下图所示界面,在该界面中只需要在“Name”后面输入新建的Java类文件的名称,这里采用名称“WordCount”,其他都可以采用默认设置,然后,点击界面右下角“Finish”按钮。
在这里插入图片描述
⑨可以看出Eclipse自动创建了一个名为“WordCount.java”的源代码文件,并且包含了代码“public class WordCount{}”,清空该文件里面的代码,然后在该文件中输入完整的词频统计程序代码。
在这里插入图片描述

(二)配置eclipse环境,跑词频统计的程序。

(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的终端中执行如下命令,可以看到,“/usr/local/hadoop/myapp”目录下已经存在一个WordCount.jar文件。
在这里插入图片描述
(2)运行程序
①在运行程序之前,需要启动Hadoop
在这里插入图片描述
②在启动Hadoop之后,需要首先删除HDFS中与当前Linux用户hadoop对应的inputoutput目录(即HDFS中的“/user/hadoop/input”和“/user/hadoop/output”目录),这样确保后面程序运行不会出现问题。
在这里插入图片描述
③然后,再在HDFS中新建与当前Linux用户hadoop对应的input目录,即“/user/hadoop/input”目录。
在这里插入图片描述
④然后把之前在Linux本地文件系统中新建的两个文件wordfile1.txtwordfile2.txt(两个文件位于“/usr/local/hadoop”目录下,并且里面包含了一些英文语句),上传到HDFS中的“/user/hadoop/input”目录下。
在这里插入图片描述
⑤如果HDFS中已经存在目录“/user/hadoop/output”,则使用如下命令删除该目录。
在这里插入图片描述
⑥现在就可以在Linux系统中使用hadoop jar命令运行程序。命令执行以后,当运行顺利结束时,屏幕上会显示类似如下的信息。
在这里插入图片描述
⑦此时词频统计结果已经被写入了HDFS的“/user/hadoop/output”目录中,执行如下命令会在屏幕上显示如下词频统计结果。
在这里插入图片描述
至此,词频统计程序顺利运行结束。需要注意的是,如果要再次运行WordCount.jar,需要首先删除HDFS中的output目录,否则会报错。

(三)编写MapReduce程序,实现计算平均成绩的程序。

import java.io.IOException;
import java.util.Iterator;
import java.util.StringTokenizer;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;public class Score {public static class Map extendsMapper<LongWritable, Text, Text, IntWritable> {// 实现map函数public void map(LongWritable key, Text value, Context context)throws IOException, InterruptedException {// 将输入的纯文本文件的数据转化成StringString line = value.toString();// 将输入的数据首先按行进行分割StringTokenizer tokenizerArticle = new StringTokenizer(line, "\n");// 分别对每一行进行处理while (tokenizerArticle.hasMoreElements()) {// 每行按空格划分StringTokenizer tokenizerLine = new StringTokenizer(tokenizerArticle.nextToken());String strName = tokenizerLine.nextToken();// 学生姓名部分String strScore = tokenizerLine.nextToken();// 成绩部分Text name = new Text(strName);int scoreInt = Integer.parseInt(strScore);// 输出姓名和成绩context.write(name, new IntWritable(scoreInt));}}}public static class Reduce extendsReducer<Text, IntWritable, Text, IntWritable> {// 实现reduce函数public void reduce(Text key, Iterable<IntWritable> values,Context context) throws IOException, InterruptedException {int sum = 0;int count = 0;Iterator<IntWritable> iterator = values.iterator();while (iterator.hasNext()) {sum += iterator.next().get();// 计算总分count++;// 统计总的科目数}int average = (int) sum / count;// 计算平均成绩context.write(key, new IntWritable(average));}}public static void main(String[] args) throws Exception {Configuration conf = new Configuration();// "localhost:9000" 需要根据实际情况设置一下conf.set("mapred.job.tracker", "localhost:9000");// 一个hdfs文件系统中的 输入目录 及 输出目录String[] ioArgs = new String[] { "input/score", "output" };String[] otherArgs = new GenericOptionsParser(conf, ioArgs).getRemainingArgs();if (otherArgs.length != 2) {System.err.println("Usage: Score Average <in> <out>");System.exit(2);}Job job = new Job(conf, "Score Average");job.setJarByClass(Score.class);// 设置Map、Combine和Reduce处理类job.setMapperClass(Map.class);job.setCombinerClass(Reduce.class);job.setReducerClass(Reduce.class);// 设置输出类型job.setOutputKeyClass(Text.class);job.setOutputValueClass(IntWritable.class);// 将输入的数据集分割成小数据块splites,提供一个RecordReder的实现job.setInputFormatClass(TextInputFormat.class);// 提供一个RecordWriter的实现,负责数据输出job.setOutputFormatClass(TextOutputFormat.class);// 设置输入和输出目录FileInputFormat.addInputPath(job, new Path(otherArgs[0]));FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));System.exit(job.waitForCompletion(true) ? 0 : 1);}
}

(四)MapReduce的工作原理是什么?

通过ClientJobTrackerTaskTracker的角度来分析MapReduce的工作原理。

在这里插入图片描述

  首先是客户端client要编写好mapreduce程序,配置好mapreduce的作业也就是job,接下来就是启动job了,启动job是告知JobTracker上要运行作业,这个时候JobTracker就会返回给客户端一个新的job任务的ID值,接下来它会做检查操作,这个检查就是确定输出目录是否存在,如果存在那么job就不能正常运行下去,JobTracker会抛出错误给客户端,接下来还要检查输入目录是否存在,如果不存在同样抛出错误,如果存在JobTracker会根据输入计算输入分片(Input Split),如果分片计算不出来也会抛出错误,这些都做好了JobTracker就会配置Job需要的资源了。拿到jobID后,将运行作业所需要的资源文件复制到HDFS上,包括MapReduce程序打包的JAR文件、配置文件和计算所得的输入分片信息。这些文件都存放在jobTracker专门为该作业创建的文件夹中,文件夹名为该作业的Job IDJAR文件默认会有10个副本(mapred.submit.replication属性控制);输入分片信息告诉 JobTracker应该为这个作业启动多少个map任务等信息。当资源文件夹创建完毕后,客户端会提交job告知jobTracker我已将所需资源写入hdfs上,接下来请你帮我真正去执行job
  分配好资源后,JobTracker接收提交job请求后就会初始化作业,初始化主要做的是将Job放入一个内部的队列,等待作业调度器对其进行调度。当作业调度器根据自己的调度算法调度到该作业时,作业调度器会创建一个正在运行的job对象(封装任务和记录信息),以便JobTracker跟踪job的状态和进程。创建job对象时作业调度器会获取hdfs文件夹中的输入分片信息,根据分片信息为每个input split创建一个map任务,并将map任务分配给tasktracker执行。对于mapreduce任务,tasktracker根据主机核的数量和内存的大小有固定数量的map槽和reduce槽。这里需要强调的是:map任务不是随随便便地分配给某个tasktracker的,这里涉及到后面要讲的数据本地化。
  接下来就是任务分配了,这个时候tasktracker会运行一个简单的循环机制定期发送心跳给jobtracker,心跳间隔是5秒,程序员可以配置这个时间,心跳就是jobtrackertasktracker沟通的桥梁,通过心跳,jobtracker可以监控tasktracker是否存活,也可以获取tasktracker处理的状态和问题,同时tasktracker也可以通过心跳里的返回值获取jobtracker给它的操作指令。tasktracker会获取运行job所需的资源,比如代码等,为真正执行做准备。任务分配好后就是执行任务了。在任务执行时候jobtracker可以通过心跳机制监控tasktracker的状态和进度,同时也能计算出整个job的状态和进度,而tasktracker也可以本地监控自己的状态和进度。TaskTracker每隔一段时间会给JobTracker发送一个心跳,告诉JobTracker它依然在运行,同时心跳中还携带者很多的信息,比如当前map任务完成的进度等信息。当jobtracker获得了最后一个完成指定任务的tasktracker操作成功的通知时候,jobtracker会把整个job状态置为成功,然后当客户端查询job运行状态时候(注意:这个是异步操作),客户端会查到job完成的通知的。如果job中途失败,mapreduce也会有相应机制处理,一般而言如果不是程序员程序本身有bugmapreduce错误处理机制都能保证提交的job能正常完成。

(五)Hadoop是如何运行MapReduce程序的?

①将编译软件与hadoop相连(如Eclipse去链接hadoop),直接运行程序。
②将mapreduce程序打包成jar文件。


http://chatgpt.dhexx.cn/article/CoTrc64u.shtml

相关文章

(超详细)MapReduce工作原理及基础编程

MapReduce工作原理及基础编程&#xff08;代码见文章后半部分&#xff09; JunLeon——go big or go home 目录 MapReduce工作原理及基础编程&#xff08;代码见文章后半部分&#xff09; 一、MapReduce概述 1、什么是MapReduce&#xff1f; 2、WordCount案例解析MapRed…

【小白视角】大数据基础实践(五) MapReduce编程基础操作

目录 1. MapReduce 简介1.1 起源1.2 模型简介1.3 MRv1体系结构1.4 YARN1.4.1 YARN体系结构1.4.2 YARN工作流程 2. MapReduce 工作流程3. Java Api要点4. 实验过程最后 1. MapReduce 简介 1.1 起源 在函数式语言里&#xff0c;map表示对一个列表&#xff08;List&#xff09;中…

MapReduce编程

一、MapReduce编程规范 MapReduce的开发一共又八个步骤&#xff0c;其中Map阶段分为2个步骤&#xff0c;Shuffle阶段4个步骤&#xff0c;Reduce阶段分为2个步骤。 1.1 步骤流程 Map阶段2个步骤 设置InputFormat类&#xff0c;将数据切分为key-value&#xff08;k1和v1&#x…

SSL/TLS

SSL/TLS 一、SSL/TLS1.1 历史发展1.2 使用场景1.3 解决的问题1.4 工作流程 二、对称加密&#xff08;Symmetric Cryptography&#xff09;2.1 工作原理2.2 翻转攻击2.3 认证加密&#xff08;Authentication Encryption&#xff09;2.4 Diffie-Hellman2.5 KDF2.6 Diffie-Hellman…

HTTPS,SSL,TLS

SSL TLS secure sockets layer 安全套接字层&#xff0c;Netscape公司研发。 transport layer security 安全传输层协议 定义 协议 年份 SSL 1.0 未知 SSL 2.0 1995 SSL 3.0 1996 TLS 1.0 1999 TLS 1.1 2006 TLS 1.2 2008 TLS 1.3 2018 IETF&#xff08;The…

TLS传输协议

TLS&#xff1a;安全传输层协议&#xff08;TLS&#xff09;用于在两个通信应用程序之间提供保密性和数据完整性。 该协议由两层组成&#xff1a;TLS 记录协议&#xff08;TLS Record&#xff09;和 TLS 握手协议&#xff08;TLS Handshake&#xff09;。 传输层安全性协议&a…

LVGL misc tlsf算法(lv_tlsf.c)

更多源码分析请访问:LVGL 源码分析大全 目录 1、概述2、算法特点3、同类型算法举例1、概述 LVGL采用的内存分配器是使用的tlsf算法。因为这个算法只是一个实时系统常用的算法,可以看作是一个工具,对LVGL本身并没有逻辑上的关联,所以这里只介绍一下算法的基本知识,就不过…

TLS/SSL 协议详解(17) Certificate verify

发送这个类型的握手需要2个前提条件 &#xff08;1&#xff09;&#xff1a;服务器端请求了客户端证书 &#xff08;2&#xff09;&#xff1a;客户端发送了非0长的证书 此时&#xff0c;客户端想要证明自己拥有该证书&#xff0c;必然需要私钥签名一段数据发给服务器验证。 …

HTTPS之TLS证书

文章目录 一. TLS概述1. TLS概述2. HTTPS 协议栈与 HTTP 的唯一区别3. TLS协议版本 二. TLS证书格式1. 概述2. 示例&#xff1a;知乎网站证书解析(mac系统)3. 通过openssl获取证书的含义 三. 证书链&#xff08;Certificate Chain&#xff09;1. 背景2. 概述3. 背景问题的解释 …

SSL和TLS简单概述

SSL和TLS简单概述 本文不会只有几个比较重要的概念,科普性质的文章,方便自己记忆,极大概率存在缺陷 如果想了解这方面的内容&#xff0c;请参阅官方文档。 SSL和TLS TLS是更安全版本的ssl,先出的的ssh,一个基于加密机制的应用,之后为了方便给其他应用层使用然后引入了ssl,最…

动态内存管理——tlsf

定义 TLSF(全称Two-Level Segregated Fit) 源码 https://github.com/mattconte/tlsf 代码 结构体 typedef struct block_header_t {/* 指向上一个物理块。*/struct block_header_t * prev_phys_block;/* 此块的大小&#xff0c;不包括块头。*/size_t size;/* 下一个和上一…

SSL与TLS协议详解

写在最前面的话&#xff1a;这篇文章是我借鉴了Eric Rescorla的《SSL and TLS》一书之后对该书的前半部分内容整合而做。如您需要开发围绕SSL、TLS的程序建议参阅原著或者RFC相关文档。 一、关于SSL、TLS与HTTPS的三两事 什么是SSL、TLS&#xff1a; 众所周知&#xff0c;真…

TLS协议/SSL协议

历史背景 SSL(Secure Socket Layer 安全套接层)是基于HTTPS下的一个协议加密层&#xff0c;最初是由网景公司&#xff08;Netscape&#xff09;研发&#xff0c;后被IETF&#xff08;The Internet Engineering Task Force - 互联网工程任务组&#xff09;标准化后写入&#xf…

TLS加密体系

谈到这个词&#xff0c;可能大家的第一印象就是加密&#xff0c;而对TLS了解甚少。那么在介绍 TLS 加密体系之前先来讲一讲加密。 一提到加密&#xff0c;可能很多人脑海中会浮现出电视剧里特务的场景&#xff0c;他们拿出一台电报机&#xff0c;“滴滴滴滴”按下情报报文&…

TLS概述

握手过程 可分为5步&#xff08;使用Diffie – Hellman算法&#xff09;&#xff1a; 第一步&#xff0c;浏览器给出协议版本号、一个客户端生成的随机数&#xff08;Client random&#xff09;&#xff0c;以及客户端支持的加密方法。 第二步&#xff0c;服务器确认双方使用的…

SSL与DTLS简介

目录 SSL简介 DTLS-基于UDP的TLS 记录层 传输层映射 早期我们在访问web时使用HTTP协议&#xff0c;该协议在传输数据时使用明文传输&#xff0c;会带来了以下风险&#xff1a; 信息窃听风险&#xff0c;第三方可以获取通信内容&#xff1b; 信息篡改风险&#xff0c;第三方…

TLS/SSL 协议

TLS/SSL 协议的工作原理 TLS/SSL 协议的工作原理 • 身份验证 • 保密性 • 完整 TLS/SSL 发展 TLS 协议 • Record 记录协议 • 对称加密 • Handshake 握手协议 • 验证通讯双方的身份 • 交换加解密的安全套件 • 协商加密参 TLS 安全密码套件解 对称加密的工作原理&am…

SSL/TLS详解

SSL/TLS详解 1. 前言 ​ 我们都知道Https就是加密协议中采用了SSL/TLS协议&#xff0c;这是面试常客&#xff0c;如果被问到了&#xff0c;你懂的越多&#xff0c;答得越深&#xff0c;你的面评相应来说也就会越高&#xff0c;对于SSL/TLS&#xff0c;我们不仅仅要知道其为数…

TLS协议简单介绍

TLS简介 介绍 TLS&#xff08;Transport Layer Security&#xff09;即安全传输层协议&#xff0c;在两个通信应用程序之间提供保密性和数据完整性。最典型的应用就是HTTPS。HTTPS&#xff0c;即HTTP over TLS&#xff0c;就是安全的HTTP&#xff0c;运行在HTTP层之下&#x…

esp-idf的内存管理——tlsf之上的封装

目录 1 为什么要封装2 先看结构2.1 multi heapnote1note2 2.2 heap caps2.3 层次关系 3 再看接口3.1 内存的申请3.2 内存的释放3.2 堆完整性检测3.3 其它 参考 1 为什么要封装 封装通常会降低效率&#xff0c;但能够带来诸如通用性提升等好处&#xff0c;idf在tlsf的基础上增加…