MapReduce:处理数据密集型文本处理–局部聚合第二部分

这篇文章继续进行有关使用MapReduce进行数据密集型处理的书中实现算法的系列文章。 第一部分可以在这里找到。 在上一篇文章中,我们讨论了使用本地聚合技术来减少通过网络进行混洗和传输的数据量的方法。 减少传输的数据量是提高MapReduce作业效率的主要方法之一。 单词计数MapReduce作业用于演示本地聚合。 由于结果只需要总数,因此我们可以为合并器重新使用相同的化简器,因为更改加数的顺序或分组不会影响总和。

但是,如果您想要平均水平呢? 然后,由于计算平均值的平均值不等于原始数字集的平均值,因此相同的方法将行不通。 尽管有了一点见识,我们仍然可以使用本地聚合。 对于这些示例,我们将使用Hadoop最终指南书中使用的NCDC天气数据集的示例。 我们将计算1901年每个月的平均温度。可以在MapReduce的数据密集型处理的第3.1.3章中找到组合器和映射器内组合选项的平均值算法。

一种尺寸并不适合所有人

上一次,我们介绍了两种用于在MapReduce作业中减少数据的方法:Hadoop组合器和映射器内组合方法。 Hadoop框架将组合器视为一种优化,并且无法保证调用组合器的次数(如果有的话)。 结果,映射器必须以减速器期望的形式发出数据,因此,如果不涉及组合器,则最终结果不会更改。 要针对计算平均值进行调整,我们需要返回到映射器并更改其输出。

映射器更改

在单词计数示例中,未优化的映射器仅发出单词和1的计数。合并器和映射器内组合映射器通过将每个单词保留为哈希映射中的键(总计数为n)来优化此输出。值。 每次看到一个单词,计数都将增加1。在这种设置下,如果未调用组合器,则缩减器将接收到该单词作为键,并将一长串的1?s加在一起,从而得到相同的输出(当然,使用映射器内组合映射器可以避免此问题,因为可以保证合并结果是映射器代码的一部分)。 为了计算平均值,我们将使基本映射器发出一个字符串键(将天气观测的年和月连接在一起)和一个自定义可写对象,称为TemperatureAveragingPair。 TemperatureAveragingPair对象将包含两个数字(IntWritables),获取的温度和一个计数。 我们将从Hadoop:权威指南中获取MaximumTemperatureMapper,并以此为灵感来创建AverageTemperatureMapper:

public class AverageTemperatureMapper extends Mapper<LongWritable, Text, Text, TemperatureAveragingPair> {//sample line of weather data//0029029070999991901010106004+64333+023450FM-12+000599999V0202701N015919999999N0000001N9-00781+99999102001ADDGF10899199999999999private Text outText = new Text();private TemperatureAveragingPair pair = new TemperatureAveragingPair();private static final int MISSING = 9999;@Overrideprotected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {String line = value.toString();String yearMonth = line.substring(15, 21);int tempStartPosition = 87;if (line.charAt(tempStartPosition) == '+') {tempStartPosition += 1;}int temp = Integer.parseInt(line.substring(tempStartPosition, 92));if (temp != MISSING) {outText.set(yearMonth);pair.set(temp, 1);context.write(outText, pair);}}
}

通过使映射器输出键和TemperatureAveragingPair对象,无论调用组合器如何,我们的MapReduce程序都可以保证具有正确的结果。

合路器

我们需要减少发送的数据量,因此我们将对温度求和,对计数求和并分别存储。 这样,我们将减少发送的数据,但保留计算正确平均值所需的格式。 如果/在调用组合器时,它将采用所有传入的TemperatureAveragingPair对象,并为同一键发出单个TemperatureAveragingPair对象,其中包含温度和计数值的总和。 这是合并器的代码:

public class AverageTemperatureCombiner extends Reducer<Text,TemperatureAveragingPair,Text,TemperatureAveragingPair> {private TemperatureAveragingPair pair = new TemperatureAveragingPair();@Overrideprotected void reduce(Text key, Iterable<TemperatureAveragingPair> values, Context context) throws IOException, InterruptedException {int temp = 0;int count = 0;for (TemperatureAveragingPair value : values) {temp += value.getTemp().get();count += value.getCount().get();}pair.set(temp,count);context.write(key,pair);}
}

但是我们非常有兴趣确保我们减少了发送到reducer的数据量,因此我们将看看下一步如何实现。

在Mapper合并平均值中

类似于单词计数示例,为了计算平均值,映射器内组合映射器将使用哈希图,将连接的年+月作为键,将TemperatureAveragingPair作为值。 每次获得相同的年+月组合时,我们都会将对对象从地图中取出,添加温度并将计数增加一个。 调用cleanup方法后,我们将发出所有对及其各自的键:

public class AverageTemperatureCombiningMapper extends Mapper<LongWritable, Text, Text, TemperatureAveragingPair> {//sample line of weather data//0029029070999991901010106004+64333+023450FM-12+000599999V0202701N015919999999N0000001N9-00781+99999102001ADDGF10899199999999999private static final int MISSING = 9999;private Map<String,TemperatureAveragingPair> pairMap = new HashMap<String,TemperatureAveragingPair>();@Overrideprotected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {String line = value.toString();String yearMonth = line.substring(15, 21);int tempStartPosition = 87;if (line.charAt(tempStartPosition) == '+') {tempStartPosition += 1;}int temp = Integer.parseInt(line.substring(tempStartPosition, 92));if (temp != MISSING) {TemperatureAveragingPair pair = pairMap.get(yearMonth);if(pair == null){pair = new TemperatureAveragingPair();pairMap.put(yearMonth,pair);}int temps = pair.getTemp().get() + temp;int count = pair.getCount().get() + 1;pair.set(temps,count);}}@Overrideprotected void cleanup(Context context) throws IOException, InterruptedException {Set<String> keys = pairMap.keySet();Text keyText = new Text();for (String key : keys) {keyText.set(key);context.write(keyText,pairMap.get(key));}}
}

通过遵循在映射调用之间跟踪数据的相同模式,我们可以通过实现映射器内合并策略来实现可靠的数据减少。 同样的注意事项适用于在对映射器的所有调用中保持状态,但是考虑使用这种方法可以提高处理效率,这是值得考虑的。

减速器

在这一点上,编写我们的reducer很容易,为每个键列出一对配对,将所有温度和计数求和,然后将温度的总和除以计数的总和。

public class AverageTemperatureReducer extends Reducer<Text, TemperatureAveragingPair, Text, IntWritable> {private IntWritable average = new IntWritable();@Overrideprotected void reduce(Text key, Iterable<TemperatureAveragingPair> values, Context context) throws IOException, InterruptedException {int temp = 0;int count = 0;for (TemperatureAveragingPair pair : values) {temp += pair.getTemp().get();count += pair.getCount().get();}average.set(temp / count);context.write(key, average);}
}


结果

使用合并器和映射器内合并映射器选项可以预测结果,从而显着减少数据输出。
未优化的映射器选项:

12/10/10 23:05:28 INFO mapred.JobClient:     Reduce input groups=12
12/10/10 23:05:28 INFO mapred.JobClient:     Combine output records=0
12/10/10 23:05:28 INFO mapred.JobClient:     Map input records=6565
12/10/10 23:05:28 INFO mapred.JobClient:     Reduce shuffle bytes=111594
12/10/10 23:05:28 INFO mapred.JobClient:     Reduce output records=12
12/10/10 23:05:28 INFO mapred.JobClient:     Spilled Records=13128
12/10/10 23:05:28 INFO mapred.JobClient:     Map output bytes=98460
12/10/10 23:05:28 INFO mapred.JobClient:     Total committed heap usage (bytes)=269619200
12/10/10 23:05:28 INFO mapred.JobClient:     Combine input records=0
12/10/10 23:05:28 INFO mapred.JobClient:     Map output records=6564
12/10/10 23:05:28 INFO mapred.JobClient:     SPLIT_RAW_BYTES=108
12/10/10 23:05:28 INFO mapred.JobClient:     Reduce input records=6564

组合器选项:

12/10/10 23:07:19 INFO mapred.JobClient:     Reduce input groups=12
12/10/10 23:07:19 INFO mapred.JobClient:     Combine output records=12
12/10/10 23:07:19 INFO mapred.JobClient:     Map input records=6565
12/10/10 23:07:19 INFO mapred.JobClient:     Reduce shuffle bytes=210
12/10/10 23:07:19 INFO mapred.JobClient:     Reduce output records=12
12/10/10 23:07:19 INFO mapred.JobClient:     Spilled Records=24
12/10/10 23:07:19 INFO mapred.JobClient:     Map output bytes=98460
12/10/10 23:07:19 INFO mapred.JobClient:     Total committed heap usage (bytes)=269619200
12/10/10 23:07:19 INFO mapred.JobClient:     Combine input records=6564
12/10/10 23:07:19 INFO mapred.JobClient:     Map output records=6564
12/10/10 23:07:19 INFO mapred.JobClient:     SPLIT_RAW_BYTES=108
12/10/10 23:07:19 INFO mapred.JobClient:     Reduce input records=12

映射器内合并选项:

12/10/10 23:09:09 INFO mapred.JobClient:     Reduce input groups=12
12/10/10 23:09:09 INFO mapred.JobClient:     Combine output records=0
12/10/10 23:09:09 INFO mapred.JobClient:     Map input records=6565
12/10/10 23:09:09 INFO mapred.JobClient:     Reduce shuffle bytes=210
12/10/10 23:09:09 INFO mapred.JobClient:     Reduce output records=12
12/10/10 23:09:09 INFO mapred.JobClient:     Spilled Records=24
12/10/10 23:09:09 INFO mapred.JobClient:     Map output bytes=180
12/10/10 23:09:09 INFO mapred.JobClient:     Total committed heap usage (bytes)=269619200
12/10/10 23:09:09 INFO mapred.JobClient:     Combine input records=0
12/10/10 23:09:09 INFO mapred.JobClient:     Map output records=12
12/10/10 23:09:09 INFO mapred.JobClient:     SPLIT_RAW_BYTES=108
12/10/10 23:09:09 INFO mapred.JobClient:     Reduce input records=12

计算结果:
(注意:示例文件中的温度以摄氏度* 10为单位)

未优化 合路器 映射器内合并器映射器
190101 -25
190102 -91
190103 -49 190104 22 190105 76 190106 146 190107 192 190108 170 190109 114 190110 86 190111 -16 190112 -77
190101 -25
190102 -91
190103 -49 190104 22 190105 76 190106 146 190107 192 190108 170 190109 114 190110 86 190111 -16 190112 -77
190101 -25
190102 -91
190103 -49 190104 22 190105 76 190106 146 190107 192 190108 170 190109 114 190110 86 190111 -16 190112 -77


结论

对于简单的情况(可以将reducer重用为组合器)和更复杂的情况(对于如何构造数据同时仍能从本地聚集数据以提高处理效率)有所了解,我们已经介绍了本地聚集。

进一步阅读

  • Jimmy Lin和Chris Dyer 使用MapReduce进行的数据密集型处理
  • Hadoop: Tom White 的权威指南
  • 来自博客的源代码
  • Hadoop API
  • MRUnit用于单元测试Apache Hadoop映射减少工作
  • Gutenberg项目提供了大量纯文本格式的书籍,非常适合在本地测试Hadoop作业。

参考: 使用MapReduce进行数据密集型文本处理-本地聚合第二部分,来自我们的JCG合作伙伴 Bill Bejeck,来自“ 随机编码思考”博客。


翻译自: https://www.javacodegeeks.com/2012/10/mapreduce-working-through-data-2.html

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

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

相关文章

python爬虫需要什么知识-学习Python爬虫技术,需要掌握哪些web端的知识?

HTML5&#xff1a;html概述和基本结构、html标题标签、html段落标签、换行标签、块标签、图片标签、a链接标签、列表标签、表格、表单、页面布局等。 CSS3&#xff1a;CSS基本语法和页面引用、CSS文本设置、颜色表示法、CSS选择器、盒子模型、盒子模型实际尺寸、浮动、四大定位…

UDP学习总结

1、UDP的优势是什么&#xff1f;有哪些典型的应用是使用UDP的&#xff1f;为什么&#xff1f; 2、转载于:https://www.cnblogs.com/zhouhaibing/p/7669251.html

Linux版本的SVN客户端,linux 下安装 subversion(svn) 客户端

svn server 为只支持http://协议的windows;test web server 为as4,现需安装svn客户端方便同步代码网上找了下都是讲如何安装svn server的&#xff0c;我只需要一个支持http协议的客户端哈&#xff0c;不想装apache。安装所需软件apr,apr-util,sqlite,neon,subversion1.下载软件…

使用bootstrap的dropdown部件时报错:error:Bootstrap dropdown require Popper.js

前言&#xff1a;前端小白一枚&#xff0c;刚注册博客&#xff0c;先发个学习过程中新碰到小问题试试水吧~ 摘要&#xff1a;最近在学习bootstrap&#xff0c;偶然碰到了一个小问题&#xff0c;bootstrap网站也没有做过多的解释&#xff0c;今天分享给大家。 问题描述&#x…

C#中的三层

三层架构(3-tier architecture) 通常意义上的三层架构就是将整个业务应用划分为&#xff1a;界面层&#xff08;User Interface layer&#xff09;、业务逻辑层&#xff08;Business Logic Layer&#xff09;、数据访问层&#xff08;Data access layer&#xff09;。区分层次的…

研究僵局–第3部分

在本系列的前两个博客&#xff08; 第1部分和第2部分&#xff09;中 &#xff0c;我演示了如何创建一段死锁的不良代码&#xff0c;然后使用该代码展示了进行线程转储的三种方式。 在这个博客中&#xff0c;我将分析线程转储以找出错误的原因。 下面的讨论同时涉及本系列第1部…

qq2009显ip版怎么用_毛孔粗大怎么破?用对方法,轻松改善显皮肤嫩滑

脸上毛孔粗大怎么破&#xff1f;超级烦恼尤其是一到秋季脸上经常油腻腻的为什么会毛孔粗大呢&#xff1f;毛孔粗大怎么破&#xff1f;用对方法&#xff0c;轻松改善显皮肤嫩滑 当皮肤老旧角质积聚越多&#xff0c;会使肌肤变厚、变粗糙&#xff0c;毛孔变粗大&#xff0c;肌肤也…

linux 账号密码 字段,详解Linux中的用户密码管理命令passwd和change

passwd修改用户密码参数-k 保持未过期身份验证令牌-l 关闭账号密码。效果相当于usermod -L&#xff0c;只有root才有权使用此项。-u 恢复账号密码。效果相当于usermod -U&#xff0c;同样只有root才有权使用。-g 修改组密码。gpasswd的等效命令。-f 更改由finger命令访问的用户…

hello程序的运行过程-从计算机系统角度

hello程序的运行过程-从计算机系统角度 1、gcc编译器驱动程序读取源程序文件hello.c&#xff0c;并将它翻译成一个可执行目标文件hello。翻译过程分为四个阶段&#xff1a;预处理阶段&#xff0c;编译阶段&#xff0c;汇编阶段&#xff0c;链接阶段。 2、初始时&#xff0c;she…

靠谱的div引入任何外链内容

靠谱的div引入任何外链内容 开发中经常要在div中引入一个页面,该页面可能是内部页面,可能是一个外部页面,也可能只是一个域名获取的请求. 对于内部页面的加载,建议使用jquery的load函数,如: 1 $("#targetId").load("someUrl/templatePage.html"); 对于外…

Eclipse对类固醇的重构

在上一篇有关常见Java违规的文章中 &#xff0c;我列出了Java开发人员容易犯的一系列错误。 在重构Java项目以解决这些违规问题的同时&#xff0c;我广泛使用了Eclipse的重构功能来快速更改代码。 下面是这种重构技术的汇编。 1.在块级语句周围添加花括号 用{curly braces}包装…

微服务发展的历史_“美丽新羌 光照未来” 新羌社区开展微视频宣传片拍摄活动...

见圳客户端、深圳新闻网讯(记者 王志明 通讯员 甘力宇)为记录新羌社区的历史变迁&#xff0c;弘扬新羌人与时俱进、开拓进取的创新精神&#xff0c;宣传社区党委、社区一线工作者及社区居民的感人事迹和精神&#xff0c;展现深圳社区发展新风貌&#xff0c;2020年10月&#xff…

linux中扫描仪驱动程序,VueScan For Linux通用扫描仪驱动下载_VueScan For Linux通用扫描仪驱动官方下载-太平洋下载中心...

VueScan For Linux通用扫描仪驱动是一款提供 Linux 使用的图片扫描工具&#xff0c;它具有各种高级硬件能力使用非常广泛的的扫描仪软件&#xff0c;支持EPSon、HP、Nikon 和Canon 品牌的扫描仪设备&#xff0c;具有优良的色彩保真度和色彩平衡&#xff0c;可以让用户比平板扫描…

HTML head 头部中的各类标签

HTML <head> 头部 <head> 元素包含了所有的头部标签元素。在 <head>元素中你可以插入脚本&#xff08;scripts&#xff09;, 样式文件&#xff08;CSS&#xff09;&#xff0c;及各种meta信息。 可以添加在头部区域的元素标签为: <title>, <style&g…

CSS变量(自定义属性)实践指南

本文翻译自&#xff1a;https://www.sitepoint.com/practical-guide-css-variables-custom-properties/ 转载请注明出处&#xff1a;葡萄城官网&#xff0c;葡萄城为开发者提供专业的开发工具、解决方案和服务&#xff0c;赋能开发者。 Sass和Less这样的预处理器&#xff0c;让…

避免使用FOR –反假战役

您是否想知道FOR如何影响您的代码&#xff1f; 他们如何限制您的设计&#xff0c;更重要的是如何将您的代码转换为无人为含义的多行代码&#xff1f; 在这篇文章中&#xff0c;我们将看到如何将for的简单示例&#xff08;由Francesco Cirillio提供- 反if活动&#xff09;转换为…

ffmpeg-win32-v3.2.4 下载_MVBOX下载|MVBOX 7.1.0.4官方版

还是要强调一句&#xff0c;现在市面上很多盗版或者免费的软件&#xff0c;都给一些黑客留下了暗门&#xff0c;所以大家还是支持正版比较好&#xff0c;不要贪图便宜使用盗版软件造成不好的后果。MVBOX播放器功能介绍1、在线卡拉OK2、虚拟摄像头3、画面调色板4、摄像头抠像5、…

linux重启鼠标键盘服务,Linux 关闭服务后 鼠标 键盘用不了

大部分情况下我们做实验都是使用虚拟机&#xff0c;但是个人比较本实在太老了&#xff0c;性能有限&#xff0c;所以虚拟机里面的系统启动神慢&#xff0c;怎么办&#xff1f;把系统中自己用不到的服务全部关闭掉呗&#xff0c;如下for i in chkconfig --list | awk {print $1}…

拖拽功能-jquery

<!DOCTYPE html><html lang"en"><head> <meta charset"UTF-8"> <title>拖拽</title> <style> .nav { width: 200px; height: 200px; border: 1px solid blac…

PNG,GIF,JPG的区别及如何选

GIF&#xff1a; 1&#xff1a;256色 2&#xff1a; 无损&#xff0c;编辑 保存时候&#xff0c;不会损失。 3&#xff1a;支持简单动画。 4&#xff1a;支持boolean透明&#xff0c;也就是要么完全透明&#xff0c;要么不透明 JPEG&#xff1a; 1&#xff1a;millions o…