用于大规模数据集(大于1TB)的并行运算的MapReduce是怎么实现的?

MapReduce 是一种编程模型,用于处理和生成大数据集。MapReduce 分为两个阶段:Map 阶段和 Reduce 阶段。

  1. Map 阶段:在这个阶段,输入数据被拆分成不同的数据块,这些数据块被分发到各个 Map 任务上。每个 Map 任务对输入的数据块进行处理并输出成一组键值对。具体的处理方式取决于编写 Map 任务的方式,这将由程序员决定。

  2. Shuffle 阶段:在 Map 阶段之后,系统会根据 Map 阶段输出的键值对进行排序和分区。这个过程是系统自动完成的,不需要程序员编写代码。

  3. Reduce 阶段:在这个阶段,一组键值对会送到同一个 Reduce 任务上。Reduce 任务会对这些键值对按照键来进行合并,并对每个键的所有值进行处理,输出处理结果。具体的处理方式也是由程序员编写的 Reduce 任务来决定。

通过 Map 和 Reduce 两个步骤,MapReduce 能够将大规模的数据计算工作分解成小规模的计算任务,这些小规模的计算任务可以在不同的计算节点上并行处理。这使得 MapReduce 可以处理非常大规模的数据。

例如,一个简单的MapReduce程序可能会将文本文件分成单词(map),然后计算每个单词的出现次数(reduce)。在这种情况下,Map任务将文本文件切分为单词,并输出每个单词的键值对(键是单词,值是1),然后Reduce任务将这些键值对按照键(单词)合并,并计算每个键(单词)的值(出现次数)的总和。

在真实的环境中,这个模型通常由分布式计算框架(如 Hadoop)来实现,框架会负责任务的调度、数据的分布和容错等工作,使得程序员可以专注于编写处理数据的 Map 和 Reduce 函数。

上demo:

// 导入 IOException 类,用于处理输入/输出错误
import java.io.IOException;// 导入 StringTokenizer 类,用于解析字符串
import java.util.StringTokenizer;// 导入 Hadoop 提供的 Configuration 类,用于 Hadoop 配置设置
import org.apache.hadoop.conf.Configuration;// 导入 Hadoop 提供的 Path 类,处理 Hadoop 文件系统路径
import org.apache.hadoop.fs.Path;// 导入 Hadoop 提供的 IntWritable 和 Text 类,数据类型转换
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;// 导入 Hadoop MapReduce Job 类,用于定义和提交 MapReduce 任务
import org.apache.hadoop.mapreduce.Job;// 从 Hadoop MapReduce 库导入 Mapper 和 Reducer 类
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;// 导入 Hadoop IO 类库,用于 MapReduce 输入输出
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;// 定义 WordCount 类
public class WordCount {// 定义公开的静态 TokenizerMapper 类,继承 Hadoop 的 Mapper 类public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable>{// 定义一个值为 1 的整型变量,作为每个单词计数的值private final static IntWritable one = new IntWritable(1);// 定义一个 Text 类型的变量,存储每个即将被计数的单词private Text word = new Text();// 重写 map 方法,这个方法会被 MapReduce 框架调用,每读入一行数据调用一次public void map(Object key, Text value, Context context) throws IOException, InterruptedException {// 使用 StringTokenizer 将每行的字符串拆解为单个的单词StringTokenizer itr = new StringTokenizer(value.toString());// 循环单词字符串while (itr.hasMoreTokens()) {// 为 word 对象设值word.set(itr.nextToken());// 将每个单词及其数量(默认为 1)输出context.write(word, one);}}}// 定义公开的静态 IntSumReducer 类,继承 Hadoop 的 Reducer 类public static class IntSumReducer extends Reducer<Text,IntWritable,Text,IntWritable> {// 定义 IntWritable 类型的对象,存储每个单词的计数总和private IntWritable result = new IntWritable();// 重写 reduce 方法,这个方法用于汇总每个单词的数量public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {// 定义 sum 变量,用于累加每个单词的数量int sum = 0;// 使用 for 循环,遍历当前单词的所有数量值,进行累加for (IntWritable val : values) {sum += val.get();}// 为结果设值result.set(sum);// 将每个单词及其最终计数总和写出context.write(key, result);}}// 定义主方法,运行 MapReduce 任务的入口public static void main(String[] args) throws Exception {// 创建 Hadoop 配置对象Configuration conf = new Configuration();// 创建 Job 实例,设置 Job 名称Job job = Job.getInstance(conf, "word count");// 设置 Jar 文件 这行代码的作用是设置该作业的 jar 文件。在 Hadoop 中执行一个 MapReduce 作业,需要将其打包为一个 jar 文件并上传到 Hadoop 集群中。这里的 WordCount.class 即是你的作业驱动类, Hadoop 将会通过这个类查找包含该类的 jar 文件,然后使用这个 jar 文件执行整个作业。这样设置可以确保作业在 Hadoop 集群中的每个节点上都可以正确执行。job.setJarByClass(WordCount.class);// 设置 Mapper 类 这行代码的作用是设置 MapReduce 作业的 Mapper 类。在 MapReduce 模型中,Mapper 是负责处理输入数据,将输入数据转换为一系列键值对的组件。TokenizerMapper.class 就是你写的处理数据的类,你可以在这个类中定义如何处理和映射输入数据。设置 Mapper 类是进行 MapReduce 作业的关键步骤之一。job.setMapperClass(TokenizerMapper.class);// 设置 Combiner 类  当一个特定的 Mapper 结束处理之后,它会输出很多记录,这些记录中可能有很多键是相同的。如果没有 Combiner,这些记录就会直接传递给 Reducer,这样可能会产生大量的网络 I/O,显著地影响性能。//而有了 Combiner,我们可以在每个 Mapper 所在的节点上先进行一次局部的归约操作,将相同键的值合并后再传输到 Reducer,这样可以大大减少需要传输的数据量,提高任务的运行性能。job.setCombinerClass(IntSumReducer.class);// 设置 Reducer 类及其输出键-值对的类型// 这行代码是设定了该 MapReduce 任务的 Reducer 类是 IntSumReducer。Reducer 类是对所有 Mapper 的输出进行汇总的部分,每一个 MapReduce 任务都需要设定一个 Reducer 类。这里的 IntSumReducer 类定义了如何对数据进行汇总操作。job.setReducerClass(IntSumReducer.class); //这行代码是设定了该 MapReduce 任务输出数据的键的类型是 Text。在 MapReduce 中,数据是以键值对的形式存储和传输的。这行代码指明了输出键的数据类型,确保处理结果的格式正确。job.setOutputKeyClass(Text.class);//这行代码是设定了该 MapReduce 任务输出数据的值的类型是 IntWritable。这是对job.setOutputKeyClass(Text.class)的补充,指明了输出值的数据类型。job.setOutputValueClass(IntWritable.class);// 设置输入数据的路径,取自程序参数FileInputFormat.addInputPath(job, new Path(args[0]));// 设置输出数据的路径,取自程序参数FileOutputFormat.setOutputPath(job, new Path(args[1]));// 等待任务完成后退出程序 这行代码是 MapReduce 任务的最后一步,作用是让主线程等待这个 MapReduce 任务完成。//在这段代码中,waitForCompletion方法将主线程挂起,直到 MapReduce 任务完成为止。这里的参数 true 表示会在控制台上显示这个任务的进度,也就是说你运行这个程序的时候,会在控制台上看到任务的完成进度。//这段代码的含义就是:如果任务成功完成,那么程序正常退出;如果任务执行过程中出现了错误,那么程序异常退出。System.exit(job.waitForCompletion(true) ? 0 : 1);}
}
/**
MapReduce 模型的并发性体现在其 Map 和 Reduce 操作的实现中,这两个操作对数据进行分布式处理。在以上代码片段中,没有一行明确地标示了并发操作,因为并发性质是 MapReduce 框架内部管理的,并非是在业务代码中直接表现出来的。
然而,job.setMapperClass(TokenizerMapper.class); 和 job.setReducerClass(IntSumReducer.class); 
这两行设置了 Mapper 类和 Reducer 类,这两类的实例在运行时会在多个节点上同时处理数据(一个节点处理输入数据的一部分),这便是 MapReduce 的并发性!!!
具体来说:
在 Mapper 阶段,输入的数据集会被划分成多个数据块,每一个数据块会被一个 Mapper 实例负责处理,这些 Mapper 实例是在集群的各个计算节点上同时运行的。
Reducer 阶段同样具有并发性,不同的 Reducer 实例会并发地处理 Mapper 输出的数据集中具有相同键的数据子集。
请注意,这些并发处理是由 Hadoop 框架自动管理的,并不需要在业务代码中明确地进行并发控制,这也是使用这种大数据处理框架的优点之一。
*/

这个程序把一个任务分为两个部分:

  1. Mapper (TokenizerMapper class):接受一行文本,拆分成单词,然后返回一系列的<单词,1>这样的键值对。
  2. Reducer (IntSumReducer class):对所有相同的单词计数总和,并返回<单词,总计数>这样的键值对。

执行这个程序,需要有一个 Hadoop 环境并且把待统计名词的文本文件放到应当的路径,并将结果输出的路径设置为期望的路径进行查看结果。

请注意,这些并发处理是由 Hadoop 框架自动管理的,并不需要在业务代码中明确地进行并发控制,这也是使用这种大数据处理框架的优点之一。

"Hadoop 框架自动管理" 的主要体现在哪些方便?

  1. 数据划分和任务分派:在 Map 阶段,Hadoop 按照一定的规则(默认为按文件大小)将输入数据划分成多个块(block),并为每个数据块创建一个 Map 任务,然后分派到集群的多个节点上并行执行。这个过程是 Hadoop 框架自动完成的,用户无需在代码中做任何处理。

  2. 任务调度和监控:Hadoop 采用 master-slave 架构,其中 master 节点(即 JobTracker)负责管理和调度整个集群,slave 节点(即 TaskTracker)负责执行具体的任务。JobTracker 根据集群的资源情况和任务需求,智能调度任务到各个 TaskTracker 执行,并实时监控任务的执行状态,一旦某个任务失败,会自动重新调度该任务到其他节点执行。

  3. 数据局部性优化:在划分数据和分派任务时,Hadoop 尽可能将数据存放在本地,或者距离执行任务的计算节点较近的其他节点上,以提高数据读取速度,减少网络传输开销,这称为数据局部性优化。

  4. 容错处理:如果在执行过程中某个节点出现故障,Hadoop 可以自动将该节点上的任务重新分派到其他正常的节点上执行,用户无需人工干预,这就是 Hadoop 的高容错性。

以上这些都是 Hadoop 框架自动进行的管理操作,用户只需要关注业务逻辑的编写,无需在代码中处理这些底层的细节问题。这就是 Hadoop 框架的强大之处,能够帮助用户简化分布式计算的复杂性,大大提高开发效率。

MapReduce模型的体系结构:
MapReduce体系结构主要由四个部分组成,分别是:Client、JobTracker、TaskTracker以及Task。

  1. Client:Client 是用户交互的入口,用户编写的MapReduce程序通过Client提交到JobTracker。同时,用户也可以通过Client提供接口查看作业运行状态。

  2. JobTracker:JobTracker 是集群的管理者,负责资源监控和作业调度。它监控TaskTracker与Job的状态,如有节点失败,将会将任务转移至其他节点。同时,JobTracker跟踪任务的执行进度、资源使用量等信息,并将这些信息提供给任务调度器(TaskScheduler),该调度器在资源出现空闲时选择合适的任务去使用这些资源。

  3. TaskTracker:TaskTracker 是具体任务执行的工作节点,它会周期性地通过心跳信号将本节点上的资源使用情况和任务的运行进度汇报给JobTracker。任务调度器根据这些信息为任务分配资源。TaskTracker还会执行JobTracker发送的命令(如启动新任务、杀死任务等)。它使用“slot”对本节点上的资源进行划分(CPU、内存等)。一个Task 获取到一个slot 后才有机会运行。

  4. Task:Task 是具体的执行单位,它们分为Map Task和Reduce Task两种,由TaskTracker启动。这两种任务分别处理Map和Reduce操作。

MapReduce模型的总体过程可以概括为:首先由Client提交作业,然后由JobTracker接收并管理这个作业,作业被分解为多个Task,然后由TaskTracker在各计算节点上执行这些任务。这就是MapReduce体系结构的工作方式。

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

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

相关文章

Golang | Leetcode Golang题解之第24题两两交换链表中的节点

题目&#xff1a; 题解&#xff1a; func swapPairs(head *ListNode) *ListNode {dummyHead : &ListNode{0, head}temp : dummyHeadfor temp.Next ! nil && temp.Next.Next ! nil {node1 : temp.Nextnode2 : temp.Next.Nexttemp.Next node2node1.Next node2.Nex…

数据结构(算法)

总结&#xff0c;建议看EXCEL的《算法》页签&#xff0c;不然感觉有点乱 备注原理/步骤时间复杂度空间复杂度串的应用模式匹配简单/暴力O(mn) KMP  O(mn) 树的应用树哈夫曼树1、带权路径长度WPL 2、外部排序-最佳归并树1、哈夫曼树的度&#xff0c;只有0和m&#xff08;m叉…

Linux上下载部署zentao v15.5及具体的使用

1.先查询一下Linux的操作系统的位数&#xff0c;确保下载的文件位数与os的一致 [rootlocalhost xiaoming]# uname -m x86_64 [rootlocalhost xiaoming]# getconf LONG_BIT 64 2.下载zentao的Linux压缩包 wget https://www.zentao.net/dl/zentao/15.5/ZenTaoPMS.15.5.zbox…

【opencv】示例-inpaint.cpp 图像修复是通过填充损坏图像部分从而修复这些损坏的过程...

原始图像 这段代码展示了一个使用OpenCV库进行图像修复的例子。它首先包含了处理图像编码、解码、显示、处理和照片处理所必要的OpenCV模块的头文件。然后利用cv和std命名空间下的类和方法。通过定义一个鼠标回调函数onMouse来处理图像上的绘图操作&#xff0c;并通过主函数mai…

基于大数据的全国热门景点数据可视化分析系统

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长 QQ 名片 :) 1. 项目简介 本文将介绍如何使用Python中的Pandas库进行数据挖掘&#xff0c;并结合Flask Web框架实现一个旅游景点数据分析系统。该系统将包括以下功能模块&#xff1a;热门景点概况、景点星级与评分分析、景…

如何使用 Grafana 监控文件系统状态

当 JuiceFS 文件系统部署完成并投入生产环境&#xff0c;接下来就需要着手解决一个非常重要的问题 —— 如何实时监控它的运行状态&#xff1f;毕竟&#xff0c;它可能正在为关键的业务应用或容器工作负载提供持久化存储支持&#xff0c;任何小小的故障或性能下降都可能造成不利…

HCIP-Datacom(H12-821)题库补充(4月12日)

最新 HCIP-Datacom&#xff08;H12-821&#xff09;完整题库请扫描上方二维码访问&#xff0c;持续更新中。 在BGP进程下&#xff0c;Aggregate命令中的detail&#xff3f;suppressed关键字的作用是以下哪一项&#xff1f; A&#xff1a;抑制生成的聚合路由下发IP路由表 B&…

vueRouter动态路由(实现菜单权限控制)

一、权限控制管理&#xff1a; 对于企业级的项目, 我们可能需要对项目做权限控制管理, 实现不同角色的用户登录项目根据所拥有的权限访问不同的页面内容&#xff0c;此时就需要使用到动态路由来对权限页面做限制。 【使用vue-router实现动态路由&#xff0c;达到实现菜单权限…

React + three.js 实现人脸动捕与3D模型表情同步

系列文章目录 React 使用 three.js 加载 gltf 3D模型 | three.js 入门React three.js 3D模型骨骼绑定React three.js 3D模型面部表情控制React three.js 实现人脸动捕与3D模型表情同步 示例项目(github)&#xff1a;https://github.com/couchette/simple-react-three-facia…

BI数据分析软件:行业趋势与功能特点剖析

随着数据量的爆炸性增长&#xff0c;企业对于数据的需求也日益迫切。BI数据分析软件作为帮助企业实现数据驱动决策的关键工具&#xff0c;在当前的商业环境中扮演着不可或缺的角色。本文将从行业趋势、功能特点以及适用场景等方面&#xff0c;深入剖析BI数据分析软件&#xff0…

IP证书申请流程

目录 域名与IP的关系 SSL证书绑定域名还是绑定IP&#xff1f; IP证书支持免费申请吗&#xff1f; 如何申请IP地址证书 IP类型的SSL证书&#xff0c;又称之为IP SSL&#xff0c;这种SSL证书是专门用于公网IP地址验证的一种数字证书。 主要功能就是解决IP地址明文传输的安全…

毅四捕Go设计模式笔记——代理模式

代理模式&#xff08;Proxy Pattern&#xff09; 为了解决什么问题&#xff1f; 代理模式用于在不直接访问实际对象的情况下&#xff0c;通过引入一个代理对象来控制和管理对该对象的访问。主要解决的问题是对原始对象的访问控制&#xff0c;以及在不改变原始对象接口的情况下…

bilibili PC客户端架构设计——基于Electron

众所周知&#xff0c;bilibili是个学习的网站&#xff0c;网页端和粉版移动端都非常的好用&#xff0c;不过&#xff0c;相对其它平台来说bilibili的PC客户端也算是大器晚成了。在有些场景PC客户端的优势也是显而易见的&#xff0c;比如&#xff0c;跓留电脑桌面的快捷、独立的…

C#在后台自动化截图指定网站并保存图片

先安装PuppeteerSharp的库 然后调用如下方法 private async Task ScreenShotAsync(string url){//using var browserFetcher new BrowserFetcher();//await browserFetcher.DownloadAsync();await using var browser await Puppeteer.LaunchAsync(new LaunchOptions { Headle…

gitlab 搭建

cat etc/initial_root_password Password: ipGg5y7GJPp/YmVHf3c3ViMKzCWYJSjU4JzUktrw8cY ###### 可修改&#xff0c;可不修改&#xff0c;并###并#并 #初始密码 #本次未修改 vim /data/gitlab/etc/gitlab.rb external_url http://ip/gitlab #访问网址及端口 #ssh远程地址 gi…

时钟周期检测标志信号

在某些情况下需要对系统时钟分频后的时钟进行周期检测&#xff0c;引出周期标志信号以便在后续其他情况的使用。虽然在大多数情况下我们能够知道分频后的时钟是系统时钟的几倍分频&#xff0c;但为增强在分频时钟改变情况下周期标志信号的复用性或对未知时钟的周期检测&#xf…

FFmpeg: 简易ijkplayer播放器实现--06封装打开和关闭stream

文章目录 流程图stream openstream close 流程图 stream open 初始化SDL以允许⾳频输出&#xff1b;初始化帧Frame队列初始化包Packet队列初始化时钟Clock初始化音量创建解复用读取线程read_thread创建视频刷新线程video_refresh_thread int FFPlayer::stream_open(const cha…

如何解决Uniapp更新数据不重新渲染组件

办法就是在修改数据的函数里面&#xff0c;用let thatthis&#xff0c;再给that用赋值。 原因是给数据赋值的函数没用箭头函数&#xff0c;this是函数自己的this。比如success&#xff08;res&#xff09;{} 或者用箭头函数&#xff0c;比如success&#xff08;res&#xff0…

在Ubuntu服务器上快速安装一个redis并提供远程服务

一、快速安装一个Redis 第一步&#xff1a;更新apt源 sudo apt update第二步&#xff1a;下载Redis sudo apt install redis第三步&#xff1a;查看Redis是否已自启动 systemctl status redis二、配置Redis提供远程服务 第一步&#xff1a;先确保6379端口正常开放 如果是…

STM32F427+RTthread——USB虚拟串口

书接上回说到&#xff0c;RT-Thread完整版移植完毕&#xff0c;接下来做USB虚拟串口的功能 打开MX工程文件&#xff0c;配置USB CDC 先在ENV上选好USB CDC选项 在CubeMX_Config文件夹下就有生成的usb相关文件&#xff0c;添加到Project工程里 然后引入驱动drv_usbd.c&#xff…