使用Guava MapSplitters配置Hadoop

在本文中,我们将为通过Context对象将配置参数传递给Hadoop Mapper提供新的思路。 通常,我们在启动map-reduce作业时将配置参数设置为Context对象上的键/值对。 然后,在Mapper中,我们使用键来检索用于我们的配置需求的值。 不同之处在于,我们将在Context对象上设置一个特殊格式的字符串,并在Mapper中检索值时,使用Guava MapSplitter将格式化后的字符串转换为将用于获取配置参数的HashMap 。 我们可能会问自己为什么要去解决这个麻烦? 通过以这种方式进行配置,我们可以在Context对象上设置单个键值对的情况下将多个参数传递给Mapper。 为了说明一种可能的用法,我们将回顾最后一篇文章 ,其中介绍了如何执行减少侧联接。 该职位提出的解决方案存在两个问题。 首先,我们假设要加入的键始终是文件中带分隔符的字符串中的第一个值。 其次,我们假设每个文件都使用相同的定界符。 如果我们要从密钥位于每个文件中不同位置的文件中加入数据,而某些文件使用不同的定界符怎么办? 另外,我们想对输出的所有数据使用相同的定界符(如果有的话),而与任何输入文件中使用的定界符无关。 尽管这确实是人为的情况,但它将很好地用于演示目的。 首先让我们研究一下MapSplitter类是什么以及如何使用它。

MapSplitter

MapSplitterSplitter类中的嵌套类。 Spitter接受一个字符串,并使用给定的定界符将其拆分为多个部分。 MapSplitter通过从字符串创建Map <String,String>进一步走了一步,该字符串的键值对之间用一个定界符分隔,而对值本身则完全用另一个定界符分隔。 让我们看一个例子:

Map<String,String> configParams = Splitter.splitOn("#").withKeyValueSeparator("=").split("6=June#7=July#8=August");

在上面的示例中,字符串"6=June#7=July#8=August"将被转换为Map,键6,7和8分别映射到June,July和August。 MapSplitter是一个非常简单但功能强大的类。 现在我们知道了MapSplitter工作原理,让我们看一下如何使用它来帮助我们为map-reduce作业设置配置参数

使用MapSplitter进行配置

以前,我们通过在Context对象中为map-reduce作业设置值,来将连接键和分隔符的索引位置设置为对所有文件相同。 现在,我们希望能够根据需要在每个输入文件的基础上进行设置。 我们仍将根据需要提供默认值。 为了完成此更改,我们将创建一个属性文件,该属性文件将文件名作为键,并且该值将是格式设置为MapSplitter使用的MapSplitter 。 我们的属性文件如下所示:

oneToManyEmployer2.txt=keyIndex=1&separator=|
oneToManyVehicles2.txt=keyIndex=1&separator=#

在这里,我们指示文件oneToManyEmployer2.txt在索引位置1处具有我们的连接键,而分隔符为“ |” 竖线字符和oneToManyVehicles2.txt文件的连接键位于索引位置1,并使用“,”逗号作为分隔符。 我们将对驱动程序类进行一些更改。 首先,我们将加载属性文件(假设我们已将文件放置在相对于调用hadoop的目录中)。

InputStream inputStream = new FileInputStream(new File("./jobs/join-config.properties"));
Properties properties = new Properties();
properties.load(inputStream);

首先,我们定义一个常规的Splitter对象,该对象将在斜杠“ /”上拆分文件名。 接下来,当我们遍历文件名时,通过对从Splitter.split方法调用返回的Iterable对象调用Iterables.getLast来获得文件的基本名称。 然后,我们尝试在Properties.getProperty方法中为每个文件检索配置的属性字符串。 请注意,如果找不到文件的属性,我们还将传递defaultMapConfig变量,该变量提供默认值。 我们还添加了一些其他配置键和值。 将值连接在一起时使用的分隔符以及文件的连接顺序,该顺序由文件在提供给程序的参数中的位置确定。 然后,我们仅使用文件名作为键将格式化后的字符串放入Context对象。

String defaultMapConfig = "keyIndex=0&separator=,";
Splitter splitter = Splitter.on('/');
for (int i = 0; i < args.length - 1; i++) {String fileName = Iterables.getLast(splitter.split(args[i]));String mapConfig = properties.getProperty(fileName, defaultMapConfig);builder.append(mapConfig).append("&joinDelimiter=,&joinOrder=").append(i + 1);config.set(fileName, builder.toString());builder.setLength(0);filePaths.append(args[i]).append(",");
}

使用配置值

要使用我们的配置值,我们首先必须检索存储为包含我们的配置参数的字符串的HashMap

private Splitter.MapSplitter mapSplitter = Splitter.on("&").withKeyValueSeparator("=");
.......
private Map<String,String> getConfigurationMap(Context context){FileSplit fileSplit = (FileSplit)context.getInputSplit();String configString = context.getConfiguration().get(fileSplit.getPath().getName());return mapSplitter.split(configString);}

在这里,我们使用MapSplitter实例变量,并通过使用此Mapper使用的文件名检索存储在Context的格式化字符串来创建HashMap 。 现在,我们可以简单地从映射中拉出所需的配置参数,如setup方法中所示:

protected void setup(Context context) throws IOException, InterruptedException {Map<String,String> configMap = getConfigurationMap(context);keyIndex = Integer.parseInt(configMap.get("keyIndex"));String separator = configMap.get("separator");splitter = Splitter.on(separator).trimResults();String joinDelimiter = configMap.get("joinDelimiter");joiner = Joiner.on(joinDelimiter);joinOrder = Integer.parseInt(configMap.get("joinOrder"));}

map方法中的代码与我们先前的文章中的代码相同。现在,我们对每个文件都有完全可配置的设置,而不必局限于将join键放在一个位置或对每个文件使用相同的定界符。 当然,这只是一个示例,但是此处概述的方法可用于配置许多其他设置,并且只需要Context对象中的一个键即可。

结果

最初,我们的数据如下所示:

oneToManyEmployer2.txt:

Creative Wealth|cdd8dde3-0349-4f0d-b97a-7ae84b687f9c
Susie's Casuals|81a43486-07e1-4b92-b92b-03d0caa87b5f
Super Saver Foods|aef52cf1-f565-4124-bf18-47acdac47a0e
.....

oneToManyVehicles2.txt:

2003 Holden Cruze#cdd8dde3-0349-4f0d-b97a-7ae84b687f9c
2012 Volkswagen T5#81a43486-07e1-4b92-b92b-03d0caa87b5f
2009 Renault Trafic#aef52cf1-f565-4124-bf18-47acdac47a0e
.....

singlePersonRecords.txt:

cdd8dde3-0349-4f0d-b97a-7ae84b687f9c,Esther,Garner,4071 Haven Lane,Okemos,MI
81a43486-07e1-4b92-b92b-03d0caa87b5f,Timothy,Duncan,753 Stadium Drive,Taunton,MA
aef52cf1-f565-4124-bf18-47acdac47a0e,Brett,Ramsey,4985 Shinn Street,New York,NY
......

运行我们的map-reduce作业后,结果看起来就像我们想要的一样:

08db7c55-22ae-4199-8826-c67a5689f838,John,Gregory,258 Khale Street,Florence,SC,2010 Nissan Titan,Ellman's Catalog Showrooms
0c521380-f868-438c-9916-4ab4ea76d316,Robert,Eversole,518 Stratford Court,Fayetteville,NC,2002 Toyota Highlander,Specialty Restaurant Group
1303e8a6-0085-45b1-8ea5-26c809635da1,Joe,Nagy,3438 Woodstock Drive,El Monte,CA,2011 Hyundai ix35,Eagle Food Centers
15360125-38d6-4f1e-a584-6ab9d1985ab8,Sherri,Hanks,4082 Old House Drive,Alexandria,OH,2003 Toyota Solara,Odyssey Records & Tapes
......

资源资源

  • Jimmy Lin和Chris Dyer 使用MapReduce进行的数据密集型处理
  • Hadoop: Tom White 的权威指南
  • 来自博客的源代码和测试
  • 爱德华·卡普里奥洛(Edward Capriolo),迪恩·沃普勒(Dean Wampler)和杰森·卢瑟格伦(Jason Rutherglen)的编程蜂巢
  • 通过Alan Gates对Pig进行编程
  • Hadoop API
  • MRUnit用于单元测试Apache Hadoop映射减少工作

参考: 《 随机编码》博客上的JCG合作伙伴 Bill Bejeck提供的使用Guava MapSplitters配置Hadoop 。

翻译自: https://www.javacodegeeks.com/2013/09/configuring-hadoop-with-guava-mapsplitters.html

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

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

相关文章

pdo 参数化查询 mysql函数_PDO笔记之参数化查询

参数化查询解释在这里&#xff1a;Wiki参数化查询 (少有的Wiki中文比英文介绍的要详细的编程条目)PDO中参数化查询主要用到prepare()方法&#xff0c;然后这个方法会返回一个PDOStatement对象&#xff0c;也就SQL声明(不知道怎么翻译)&#xff0c;此时SQL语句只是被编译&#x…

二叉树和哈希表的优缺点对比与选择

二叉树(binary tree)和哈希表(hash table)都是很基本的数据结构&#xff0c;但是我们要怎么从两者之间进行选择呢&#xff1f;他们的不同是什么&#xff1f;优缺点分别是什么&#xff1f; 回答这个问题不是一两句话可以说清楚的&#xff0c;原因是在不同的情况下&#xff0c;选…

编码Java时的10个微妙的最佳实践

这是10个最佳实践的列表&#xff0c;这些最佳实践比您的平均Josh Bloch有效Java规则要微妙得多。 尽管Josh Bloch的列表很容易学习&#xff0c;并且涉及日常情况&#xff0c;但此处的列表包含了涉及API / SPI设计的较不常见的情况&#xff0c;但可能会产生很大的影响。 我在编…

Vue 实现微信 jssdk 扫码, 上传图片

流程 1: 配置微信公众号JS域名 2:前端发送URL后台获取JSSDK配置, 后台Service代码如下, 修改2处位置: WeixinUtil.APPID > 当前公众号APPID WeixinUtil.getAccessToken() > 当前公众号access_token public interface IWxJssdkService {Map<String, Object> getJssd…

有意思的前端函数面试题

1:考引用类型在比较运算符时候 隐式转换会调用本类型那个方法 toString和valueOf&#xff1f;(去年过年吵的很火国外的题) if(a 1 && a 2 && a 3){console.log("我走进来了"); }<!--答案1:--> var a {num:0}; a.valueOf function(){retur…

用java写个简单的直播强求_全网最简单易懂的Netty入门示例,再不会用Netty我直播吃翔...

//server引导类ServerBootstrap serverBootstrap new ServerBootstrap();//boss 对应 IOServer.java 中的接受新连接线程,主要负责创建新连接NioEventLoopGroup boss new NioEventLoopGroup();//worker 对应 IOServer.java 中的负责读取数据的线程,主要用于读取数据以及业务逻…

XamarinAndroid组件教程设置自定义子元素动画(一)

XamarinAndroid组件教程设置自定义子元素动画(一) 如果在RecyclerViewAnimators.Animators中没有所需要的动画效果&#xff0c;就可以自定义一个。此时&#xff0c;需要让自定义的动画继承BaseItemAnimator抽象类。 【示例1-2】下面以RecylerViewAnimatorsItemAnimator项目为基…

使用Storm进行可扩展的实时状态更新

在本文中&#xff0c;我将说明如何借助Storm框架以可扩展且无锁定的方式在数据库中维护实时事件驱动流程的当前状态。 Storm是基于事件的数据处理引擎。 它的模型依赖于基本原语&#xff0c;例如事件转换&#xff0c;过滤&#xff0c;聚合……&#xff0c;我们将它们组合成拓扑…

python关于字典嵌套字典,列表嵌套字典根据值进行排序

python 对于字典嵌套字典&#xff0c; 列表嵌套字典排序 例&#xff1a;列表嵌套自字典&#xff1a;d [{"name": 张三, s: 68}, {name: 李四, s: 97}] 对于列表嵌套字典可以使用python的sorted()方法&#xff0c;也可以使用list的sort()方法&#xff1a; sorted方法…

【干货】十分钟读懂浏览器渲染流程

在之前写过的一篇《"天龙八步"细说浏览器输入URL后发生了什么》一文中&#xff0c;和大家分享了从在浏览器中输入网址URL到最终页面展示的整个过程。部分读者向我反馈对于最后的浏览器渲染布局这块不是很清晰&#xff0c;所以本文就浏览器渲染流程单独开篇讲解&#…

控制台资费管理主菜单java_java毕业设计_springboot框架的高速公路收费管理系统...

今天介绍一个java毕设题目, 题目内容为springboot框架的高速公路收费管理系统, 是一个采用b/s结构的javaweb项目, 采用java语言编写开发工具eclipse, 项目框架jspspringbootmybatis, 高速公路收费管理系统的信息存储于mysql中, 并基于mybatis进行了orm封装, 该高速公路收费管理…

Hibernate框架的搭建和一个简单的实例

Hibernate是一个支持对JDBC进行封装的框架&#xff0c;实现了对底层数据库访问的封装。非常适合使用和开发。首先需要下载Hibernate&#xff0c;可以在这个网站下载最新包。http://www.hibernate.org/然后打开他的目录结构&#xff0c;将lib目录下的required目录下的包全部导入…

在Amazon EMR上运行Hadoop MapReduce作业

不久前&#xff0c;我发布了如何使用CLI设置EMR群集的信息。 在本文中&#xff0c;我将展示如何使用适用于AWS的Java SDK来设置集群。 展示如何使用Java AWS开发工具包执行此操作的最佳方法是展示完整的示例&#xff0c;因此&#xff0c;让我们开始吧。 设置一个新的Maven项目…

在商城系统开发时遇到商品的多级分类,为增强扩展性,子类可以任意添加,此类问题数据库如何设计...

表结构为&#xff1a; id&#xff08;编号&#xff09; name&#xff08;分类名&#xff09; parentID&#xff08;父类编号&#xff09; 简单举例如下&#xff1a; id name parentID 1 饮料 0&#xff08;为0表示第一大类&#xff09; 2 水果 …

[JSConf EU 2018] 大脑控制 Javascript

先解释&#xff0c;本人为前端菜鸟&#xff0c;之前也未参加过类似的活动&#xff0c;没有翻译过什么文章&#xff0c;此次是好奇心使然&#xff0c;也是想尝试下&#xff0c;学习学习&#xff0c;英文很烂&#xff0c;全靠有道&#xff0c;但是视频整个看下来&#xff0c;还是…

init tarray 太大_[NOIP 2001提高组T4]Car的旅行路线

[题目来源]&#xff1a;NOIP2001提高组T4[关键字]&#xff1a;最短路径[题目大意]&#xff1a;给定平面直角若干个矩形&#xff0c;计算(可经过其他矩形)两个矩形任意顶点间的最短路程费用。//[分析]&#xff1a;其实题目本事没有太大的难点&#xff0c;只需要对每两个点进行连…

Caffe Caffe2入门博客存档

caffe2 教程入门&#xff08;python版&#xff09; https://www.jianshu.com/p/5c0fd1c9fef9?fromtimeline caffe入门学习 https://blog.csdn.net/hjimce/article/details/48933813 运行caffe自带的两个简单例子 https://www.linuxidc.com/Linux/2016-11/136774p9.htm 关于caf…

JavaScript中不得不说的断言?

断言主要应用于“调试”与“测试” 一、前端中的断言 仔细地查找一下JavaScript中的API&#xff0c;实际上并没有多少关于断言的方法。唯一一个就是console.assert&#xff1a; // console.assert(condition, message)const a 1console.assert(typeof a number, a should be…

Java EE状态会话Bean(EJB)示例

在本文中&#xff0c;我们将了解如何在简单的Web应用程序中使用状态会话Bean来跟踪客户端会话中的状态。 1.简介 有状态会话Bean通常保存有关特定客户端会话的信息&#xff0c;并在整个会话中保留该信息&#xff08;与无状态会话Bean相对&#xff09;。 有状态EJB实例仅与一个…

计算机科学速成课16:软件工程

概念&#xff1a;建造标准或者大型软件的方法和工具代码打包成函数 面向过程函数打包成对象 面向对象对象层层打包Car.Engine.CruiseControl.SetCruiseSpeed(55)应用程序接口api集成开发环境IDE&#xff1a;code&#xff0c;整理&#xff0c;编译&#xff0c;测试注释和readme文…