MapReduce:通過數據密集型文本處理

自上次發布以來已經有一段時間了,因為我一直在忙于Coursera提供的一些課程。 有一些非常有趣的產品,值得一看。 前一段時間,我購買了Jimmy Lin和Chris Dyer的MapReduce數據密集型處理程序 。 本書以偽代碼格式介紹了幾種關鍵的MapReduce算法。 我的目標是采用第3-6章中介紹的算法,并以Hadoop: Tom White的《權威指南》為參考在Hadoop中實現它們。 我將假設您熟悉Hadoop和MapReduce,并且不介紹任何入門資料。 因此,讓我們從局部聚合開始進入第3章-MapReduce算法設計。

本地聚集

在很高的級別上,當Mappers發出數據時,中間結果將寫入磁盤,然后通過網絡發送到Reducers以進行最終處理。 在處理MapReduce作業中,寫入磁盤然后通過網絡傳輸數據的延遲是一項昂貴的操作。 因此,有理由認為,只要有可能,減少從映射器發送的數據量將提高MapReduce作業的速度。 本地聚合是一種用于減少數據量并提高MapReduce工作效率的技術。 本地聚合不能代替reducers,因為我們需要一種方法來使用來自不同映射器的相同鍵來收集結果。 我們將考慮實現本地聚合的3種方法:

  1. 使用Hadoop Combiner函數。
  2. 文本處理和MapReduce書中介紹了兩種“映射器”組合方法。

當然,任何優化都需要權衡取舍,我們也會對此進行討論。
為了演示本地聚合,我們將使用hadoop-0.20.2-cdh3u3在MacBookPro上安裝的偽分布式群集上,在Charles Dickens的純文本版本的A Christmas Carol (從Project Gutenberg下載)上運行無處不在的字數統計作業。從Cloudera發行。 我計劃在以后的文章中在具有更實際大小的數據的EC2集群上運行相同的實驗。
合路器

組合器函數是擴展Reducer類的對象。 實際上,對于此處的示例,我們將重復使用單詞計數作業中使用的相同的reduce。 設置MapReduce作業時會指定組合器功能,如下所示:

job.setReducerClass(TokenCountReducer.class);

這是化簡器代碼:

public class TokenCountReducer extends Reducer<Text,IntWritable,Text,IntWritable>{@Overrideprotected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {int count = 0;for (IntWritable value : values) {count+= value.get();}context.write(key,new IntWritable(count));}
}

組合器的工作就是按照名稱中的含義進行操作,聚合數據的最終結果是網絡上的數據減少,從而使效率得到提高。 如前所述,請記住,仍然需要簡化器將結果與來自不同映射器的相同鍵組合在一起。 由于組合器功能是一種優化,因此Hadoop框架無法保證組合器將被調用多少次(如果有的話)。

在Mapper組合選項1中

使用Combiners的第一種選擇(圖3.2,第41頁)非常簡單,對我們原始的字數映射器進行了一些修改:

public class PerDocumentMapper extends Mapper<LongWritable, Text, Text, IntWritable> {@Overrideprotected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {IntWritable writableCount = new IntWritable();Text text = new Text();Map<String,Integer> tokenMap = new HashMap<String, Integer>();StringTokenizer tokenizer = new StringTokenizer(value.toString());while(tokenizer.hasMoreElements()){String token = tokenizer.nextToken();Integer count = tokenMap.get(token);if(count == null) count = new Integer(0);count+=1;tokenMap.put(token,count);}Set<String> keys = tokenMap.keySet();for (String s : keys) {text.set(s);writableCount.set(tokenMap.get(s));context.write(text,writableCount);}}
}

正如我們在這里看到的,對于遇到的每個單詞,我們不會發出計數為1的單詞,而是使用映射來跟蹤已處理的每個單詞。 然后,在處理完所有標記后,我們遍歷該映射并發出該行中遇到的每個單詞的總數。

在Mapper組合選項2中

映射器合并的第二個選項(圖3.3,第41頁)與上述示例非常相似,但有兩個區別-創建哈希映射時和發出映射中包含的結果時。 在上面的示例中,創建了一個映射,并在每次調用map方法時將其內容通過電線轉儲。 在此示例中,我們將使地圖成為實例變量,并將地圖的實例化移動到我們的映射器中的setUp方法。 同樣,在完成對mapper的所有調用并調用cleanUp方法之前,不會將映射的內容發送到reducers。

public class AllDocumentMapper extends Mapper<LongWritable,Text,Text,IntWritable> {private  Map<String,Integer> tokenMap;@Overrideprotected void setup(Context context) throws IOException, InterruptedException {tokenMap = new HashMap<String, Integer>();}@Overrideprotected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {StringTokenizer tokenizer = new StringTokenizer(value.toString());while(tokenizer.hasMoreElements()){String token = tokenizer.nextToken();Integer count = tokenMap.get(token);if(count == null) count = new Integer(0);count+=1;tokenMap.put(token,count);}}@Overrideprotected void cleanup(Context context) throws IOException, InterruptedException {IntWritable writableCount = new IntWritable();Text text = new Text();Set<String> keys = tokenMap.keySet();for (String s : keys) {text.set(s);writableCount.set(tokenMap.get(s));context.write(text,writableCount);}}
}

從上面的代碼示例中可以看到,在對map方法的所有調用中,映射器都跟蹤唯一字數。 通過跟蹤唯一令牌及其計數,應該大大減少發送給reducer的記錄數量,這反過來又可以改善MapReduce作業的運行時間。 這樣可以達到與使用MapReduce框架提供的Combiner Function選項相同的效果,但是在這種情況下,可以確保將調用組合代碼。 但是這種方法也有一些警告。 在地圖調用之間保持狀態可能會出現問題,并且絕對違反“地圖”功能的功能精神。 同樣,通過保持所有映射器的狀態,取決于作業中使用的數據,內存可能是另一個要解決的問題。 最終,必須權衡所有權衡以確定最佳方法。

結果

現在,讓我們看一下不同映射器的一些結果。 由于作業是在偽分布式模式下運行的,因此實際的運行時間是無關緊要的,但是我們仍然可以推斷出使用本地聚合會如何影響在實際集群上運行的MapReduce作業的效率。

每個令牌映射器:

12/09/13 21:25:32 INFO mapred.JobClient:     Reduce shuffle bytes=366010
12/09/13 21:25:32 INFO mapred.JobClient:     Reduce output records=7657
12/09/13 21:25:32 INFO mapred.JobClient:     Spilled Records=63118
12/09/13 21:25:32 INFO mapred.JobClient:     Map output bytes=302886

在Mapper精簡選項1中:

12/09/13 21:28:15 INFO mapred.JobClient:     Reduce shuffle bytes=354112
12/09/13 21:28:15 INFO mapred.JobClient:     Reduce output records=7657
12/09/13 21:28:15 INFO mapred.JobClient:     Spilled Records=60704
12/09/13 21:28:15 INFO mapred.JobClient:     Map output bytes=293402

在Mapper精簡選項2中:

12/09/13 21:30:49 INFO mapred.JobClient:     Reduce shuffle bytes=105885
12/09/13 21:30:49 INFO mapred.JobClient:     Reduce output records=7657
12/09/13 21:30:49 INFO mapred.JobClient:     Spilled Records=15314
12/09/13 21:30:49 INFO mapred.JobClient:     Map output bytes=90565

組合器選項:

12/09/13 21:22:18 INFO mapred.JobClient:     Reduce shuffle bytes=105885
12/09/13 21:22:18 INFO mapred.JobClient:     Reduce output records=7657
12/09/13 21:22:18 INFO mapred.JobClient:     Spilled Records=15314
12/09/13 21:22:18 INFO mapred.JobClient:     Map output bytes=302886
12/09/13 21:22:18 INFO mapred.JobClient:     Combine input records=31559
12/09/13 21:22:18 INFO mapred.JobClient:     Combine output records=7657

不出所料,沒有合并的Mapper的結果最差,緊隨其后的是第一個映射器內的合并選項(盡管如果在運行字數統計之前將數據清理干凈,這些結果本來可以更好)。 第二個映射器內合并選項和合并器功能實際上具有相同的結果。 重要的事實是,作為前兩個選項,兩者產生的結果都減少了2/3,減少了混洗字節。 將通過網絡發送到縮減程序的字節數量減少該數量一定會對MapReduce作業的效率產生積極影響。 這里要牢記一點,那就是合并器/映射器合并不能僅在所有MapReduce作業中使用,在這種情況下,字數計數非常適合于這種增強,但這可能并不總是正確的。

結論

正如您所看到的,在尋求提高MapReduce作業的性能時,需要認真考慮使用映射器內合并或Hadoop合并器功能的好處。 至于哪種方法,則要權衡每種方法的權衡。

相關鏈接

  • Jimmy Lin和Chris Dyer 使用MapReduce進行的數據密集型處理
  • Hadoop: Tom White 的權威指南
  • 來自博客的源代碼
  • MRUnit用于單元測試Apache Hadoop映射減少工作
  • Gutenberg項目提供了大量純文本格式的書籍,非常適合在本地測試Hadoop作業。

祝您編程愉快,別忘了分享!

參考: 《 隨機編碼》博客上的JCG合作伙伴 Bill Bejeck 提供的MapReduce數據密集型文本處理功能 。


翻譯自: https://www.javacodegeeks.com/2012/09/mapreduce-working-through-data.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/371173.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/371173.shtml
英文地址,請注明出處:http://en.pswp.cn/news/371173.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ubuntu(deepin)安裝apache2并支持php7.0

linux虛擬機下用于開發環境測試&#xff0c;安裝的apache和php7.0&#xff0c;但是簡單安裝完兩者后apache并不能解析php&#xff0c;原因是確實apache的php擴展。 # 首先安裝apache sudo apt-get install apache2 # 然后安裝php7.0 sudo apt-get install php7.0 # 一般執行完這…

java applet 換行_Java復習題

一、選擇題1.有Java語句如下&#xff0c;則說法正確的是()A.此語句是錯誤的B. a.length的值為5C. b.length的值為5D. a.length和b.length的值都為52.整數除法中&#xff0c;如果除數為0&#xff0c;則將導致的異常是( B )A. NullPointerExceptionB. ArithmeticExceptionC. Arra…

解決:MVC對象轉json包含\r \n

項目中對象轉json字符串時&#xff0c;如下&#xff1a;JsonSerializerSettings jsetting new JsonSerializerSettings(); jsetting.DefaultValueHandling DefaultValueHandling.Ignore; return JsonConvert.SerializeObject(resultMoldels, Formatting.Indented, jsetting);…

CSS 小結筆記之滑動門技術

所謂的滑動門技術&#xff0c;就是指盒子背景能夠自動拉伸以適應不同長度的文本。即當文字增多時&#xff0c;背景看起來也會變長。 大多數應用于導航欄之中&#xff0c;如微信導航欄: 具體實現方法如下&#xff1a; 1、首先每一塊文本內容是由a標簽與span標簽組成 <a hr…

使用API??身份驗證的Spring Security

背景 盡管有許多博客文章詳細介紹了如何使用Spring Security&#xff0c;但是當問題域位于標準LDAP或數據庫身份驗證之外時&#xff0c;我仍然經常發現配置挑戰。 在本文中&#xff0c;我將介紹一些針對Spring Security的簡單自定義&#xff0c;使其能夠與基于REST的API調用一起…

java nlpir_4-NLPIR漢語分詞系統-JAVA

好吧&#xff0c;之前用的是舊版的&#xff0c;現在出了個新版的&#xff0c;優先選擇用新版的哈。從官網下載相應的開發包&#xff0c;然后主要需要找到這幾個東西添加到項目工程里面&#xff0c;1.Data文件夾 2.NLPIR_JNI.DLL 3.NLPIR.jar 4.nlpir.properties添加完那些東西后…

淺析C語言中assert的用法(轉)

原文地址&#xff1a;http://www.jb51.net/article/39685.htm 以下是對C語言中assert的使用方法進行了介紹&#xff0c;需要的朋友可以參考下。 assert宏的原型定義在<assert.h>中&#xff0c;其作用是如果它的條件返回錯誤&#xff0c;則終止程序執行&#xff0c;原型定…

hihocoder offer收割編程練習賽12 D 尋找最大值

思路&#xff1a; 可能數據太水了&#xff0c;隨便亂搞就過了。 實現&#xff1a; 1 #include <iostream>2 #include <cstdio>3 #include <algorithm>4 using namespace std;5 typedef long long ll;6 7 int a[100005], n;8 9 int main() 10 { 11 int t;…

vue error:The template root requires exactly one element.

error:[vue/valid-template-root] The template root requires exactly one element. 原因&#xff1a; 因為vue的模版中只有能一個根節點&#xff0c;所以在<template>中插入第二個元素就會報錯 解決方案&#xff1a; 將<template>中的元素先用一個<div>…

測試驅動陷阱,第2部分

單元測試中單元的故事 在本文的上半部分 &#xff0c;您可能會看到一些不好但很流行的測試示例。 但是我不是一個專業評論家&#xff08;也被稱為“巨魔”或“仇恨者”&#xff09;&#xff0c;沒有任何建設性的話就抱怨。 多年的TDD教給我的不僅僅是事情會變得多么糟糕。 有許…

java 代碼 設置環境變量_Java 配置環境變量教程

【聲明】歡迎轉載&#xff0c;但請保留文章原始出處→_→【正文】1、安裝JDK開發環境開始安裝JDK&#xff1a;修改安裝目錄如下&#xff1a;確定之后&#xff0c;單擊“下一步”。注&#xff1a;當提示安裝JRE時&#xff0c;可以選擇不要安裝。2、配置環境變量&#xff1a;對于…

組合數據類型練習,英文詞頻統計實例上(2017.9.22)

字典實例&#xff1a;建立學生學號成績字典&#xff0c;做增刪改查遍歷操作。 sno[33號,34號,35號,36號] grade[100,90,80,120] d{33號:100,34號:90,35號:80,36號:120} print(d) print(每個學號對應分數:,d.items()) print(彈出35號的分數:,d.pop(35號)) print(獲取學號:,d.key…

java 代碼中設置 臨時 環境變量

System.setProperty("hadoop.home.dir", "D:\\software\\software_install\\dev_install\\hadoop-2.4.1"); 轉載于:https://www.cnblogs.com/zychengzhiit1/p/6662376.html

什么是快速開發框架

什么是快速開發框架 前言 做為一個程序員&#xff0c;在開發的過程中會發現&#xff0c;有框架同無框架&#xff0c;做起事來是完全不同的概念&#xff0c;關系到開發的效率、程序的健壯、性能、團隊協作、后續功能維護、擴展......等方方面面的事情。很多朋友在學習搭建自己…

java中的math.abs_Java.math.BigDecimal.abs()方法

全屏Java.math.BigDecimal.abs()方法java.math.BigDecimal.abs()返回一個BigDecimal&#xff0c;其值是此BigDecimal的絕對值&#xff0c;其標度是this.scale()。聲明以下是java.math.BigDecimal.abs()方法的聲明public BigDecimal abs()參數NA返回值此方法返回的名為value&…

我需要多少內存

什么是保留堆&#xff1f; 我需要多少內存&#xff1f; 在構建解決方案&#xff0c;創建數據結構或選擇算法時&#xff0c;您可能會問自己&#xff08;或其他人&#xff09;這個問題。 如果此圖包含1,000,000條邊并且我使用HashMap進行存儲&#xff0c;此圖是否適合我的3G堆&am…

C語言程序設計預報作業

1閱讀鄒欣老師的博客--師生關系,針對文中的幾種師生關系談談你的看法&#xff0c;你期望的師生關系是什么樣的&#xff1f; 答&#xff1a;我認為文中的師生關系都存在一些缺陷&#xff0c;第一種師生關系是建立在病態關系上的&#xff0c;學生不是植物自然有自己的思想。所以我…

淺談23種設計模式

淺談23種設計模式 類之間的關聯關系&#xff1a;在使用Java、C#和C等編程語言實現關聯關系時&#xff0c;通常將一個類作為另一個類的屬性。   (1)雙向關聯&#xff0c;兩個類互相為各自的屬性&#xff0c;比如顧客類Customer和商品類Product&#xff0c;顧客擁有商品&#x…

網頁布局基礎

1、盒子模型的第一層到第五層&#xff1a; border、padding content、background-image、background-color、margin 2、清除浮動。對受到浮動影響的標簽作以下操作&#xff1a; 1、clear: both; 2、clear: right; clear: left; 3、設置寬度width: 100%(或者固定寬度) overflow…

mysql與串口通信_虛擬機串口與主機串口通信·小程序(下)

上次說到的&#xff0c;不能做到實時通信。那么開兩個進程就可以了&#xff0c;一個用來監聽是否有消息傳來&#xff0c;一個用來等待用戶輸入。那么&#xff0c;先來復習一下進程的相關概念。進程結構linux中進程包含PCB(進程控制塊)、程序以及程序所操縱的數據結構集&#xf…