guava读取配置文件_使用Guava MapSplitters配置Hadoop
guava讀取配置文件
在本文中,我們將為通過(guò)Context對(duì)象將配置參數(shù)傳遞給Hadoop Mapper提供新的思路。 通常,我們?cè)趩?dòng)map-reduce作業(yè)時(shí)將配置參數(shù)設(shè)置為Context對(duì)象上的鍵/值對(duì)。 然后在Mapper中,我們使用鍵來(lái)檢索要用于我們的配置需求的值。 不同之處在于,我們將在Context對(duì)象上設(shè)置一個(gè)特殊格式的字符串,并在Mapper中檢索值時(shí),使用Guava MapSplitter將格式化后的字符串轉(zhuǎn)換為將用于獲取配置參數(shù)的HashMap 。 我們可能會(huì)問(wèn)自己為什么要去解決這個(gè)麻煩? 通過(guò)這種方式進(jìn)行配置,我們可以在Context對(duì)象上設(shè)置單個(gè)鍵值對(duì)的情況下將多個(gè)參數(shù)傳遞給Mapper。 為了說(shuō)明一種可能的用法,我們將回顧上一篇文章 ,其中介紹了如何執(zhí)行減少側(cè)連接。 該職位提出的解決方案存在兩個(gè)問(wèn)題。 首先,我們假設(shè)要加入的鍵始終是文件中帶分隔符的字符串中的第一個(gè)值。 其次,我們假設(shè)每個(gè)文件使用相同的定界符。 如果我們要從密鑰位于每個(gè)文件中不同位置的文件中加入數(shù)據(jù),而某些文件使用不同的定界符怎么辦? 另外,我們希望對(duì)輸出的所有數(shù)據(jù)使用相同的定界符(如果有),而不考慮任何輸入文件中使用的定界符。 盡管這是人為的情況,但它將很好地用于演示目的。 首先讓我們研究一下MapSplitter類(lèi)是什么以及如何使用它。
MapSplitter
MapSplitter是Splitter類(lèi)中的一個(gè)嵌套類(lèi)。 Spitter接受一個(gè)字符串,并使用給定的定界符將其拆分為多個(gè)部分。 MapSplitter通過(guò)從字符串創(chuàng)建Map <String,String>進(jìn)一步走了一步,該字符串的鍵值對(duì)用一個(gè)定界符分隔,而對(duì)值本身則完全用另一個(gè)定界符分隔。 讓我們看一個(gè)例子:
Map<String,String> configParams = Splitter.splitOn("#").withKeyValueSeparator("=").split("6=June#7=July#8=August");在上面的示例中,字符串"6=June#7=July#8=August"將被轉(zhuǎn)換為Map,鍵6,7和8分別映射到June,July和August。 MapSplitter是一個(gè)非常簡(jiǎn)單但功能強(qiáng)大的類(lèi)。 現(xiàn)在我們知道了MapSplitter工作原理,讓我們看一下如何使用它來(lái)幫助我們?yōu)閙ap-reduce作業(yè)設(shè)置配置參數(shù)
使用MapSplitter進(jìn)行配置
以前,我們通過(guò)在Context對(duì)象中為map-reduce作業(yè)設(shè)置值,來(lái)將連接鍵的索引位置和分隔符設(shè)置為對(duì)所有文件相同。 現(xiàn)在,我們希望能夠根據(jù)需要在每個(gè)輸入文件的基礎(chǔ)上進(jìn)行設(shè)置。 我們?nèi)詫⒏鶕?jù)需要提供默認(rèn)值。 為了完成此更改,我們將創(chuàng)建一個(gè)屬性文件,該屬性文件將文件名作為鍵,并且該值將是格式設(shè)置為MapSplitter使用的MapSplitter 。 我們的屬性文件如下所示:
oneToManyEmployer2.txt=keyIndex=1&separator=| oneToManyVehicles2.txt=keyIndex=1&separator=#在這里,我們指示文件oneToManyEmployer2.txt在索引位置1處具有我們的連接鍵,而分隔符為“ |” 豎線字符和oneToManyVehicles2.txt文件在索引位置1處具有連接鍵,并使用“,”逗號(hào)作為分隔符。 我們將對(duì)驅(qū)動(dòng)程序類(lèi)進(jìn)行一些更改。 首先,我們將加載屬性文件(假設(shè)我們已將文件放置在相對(duì)于調(diào)用hadoop的目錄中)。
InputStream inputStream = new FileInputStream(new File("./jobs/join-config.properties")); Properties properties = new Properties(); properties.load(inputStream);首先,我們定義一個(gè)常規(guī)的Splitter對(duì)象,該對(duì)象將在斜杠“ /”上拆分文件名。 接下來(lái),當(dāng)我們遍歷文件名時(shí),通過(guò)對(duì)從Splitter.split方法調(diào)用返回的Iterable對(duì)象調(diào)用Iterables.getLast來(lái)獲得文件的基本名稱(chēng)。 然后,我們嘗試在Properties.getProperty方法中為每個(gè)文件檢索配置的屬性字符串。 請(qǐng)注意,如果找不到文件的屬性,我們還將傳遞defaultMapConfig變量,該變量提供默認(rèn)值。 我們還添加了一些其他配置鍵和值。 將值連接在一起時(shí)使用的定界符以及文件的連接順序,該順序由文件在提供給程序的參數(shù)中的位置確定。 然后,我們僅使用文件名作為鍵將格式化后的字符串放入Context對(duì)象。
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(","); }使用配置值
要使用我們的配置值,我們首先必須檢索存儲(chǔ)為包含我們的配置參數(shù)的字符串的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實(shí)例變量,并通過(guò)使用此Mapper使用的文件名檢索存儲(chǔ)在Context的格式化字符串來(lái)創(chuàng)建HashMap 。 現(xiàn)在,我們可以簡(jiǎn)單地從映射中拉出所需的配置參數(shù),如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方法中的代碼與我們先前的文章中的代碼相同。現(xiàn)在我們每個(gè)文件都具有完全可配置的設(shè)置,而且我們不限于將join鍵放在一個(gè)位置,也不必每個(gè)文件使用相同的定界符。 當(dāng)然,這只是一個(gè)示例,但是此處概述的方法可用于配置許多其他設(shè)置,并且只需要Context對(duì)象中的一個(gè)鍵即可。
結(jié)果
最初,我們的數(shù)據(jù)如下所示:
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 ......運(yùn)行我們的map-reduce作業(yè)后,結(jié)果看起來(lái)就像我們想要的一樣:
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進(jìn)行的數(shù)據(jù)密集型處理
- Hadoop: Tom White 的權(quán)威指南
- 來(lái)自博客的源代碼和測(cè)試
- 編程蜂巢愛(ài)德華卡普里奧羅,院長(zhǎng)Wampler和Jason拉瑟格倫
- 通過(guò)Alan Gates 編程Pig
- Hadoop API
- MRUnit用于單元測(cè)試Apache Hadoop映射減少工作
翻譯自: https://www.javacodegeeks.com/2013/09/configuring-hadoop-with-guava-mapsplitters.html
guava讀取配置文件
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的guava读取配置文件_使用Guava MapSplitters配置Hadoop的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 优学派安装电脑系统(电脑优学派官方平台)
- 下一篇: Zuul 2 –样本过滤器