1. 程式人生 > >hadoop程式設計小技巧(1)---map端聚合

hadoop程式設計小技巧(1)---map端聚合

測試hadoop版本:2.4 

Map端聚合的應用場景:當我們只關心所有資料中的部分資料時,並且資料可以放入記憶體中。

使用的好處:可以大大減小網路資料的傳輸量,提高效率;

一般程式設計思路:在Mapper的map函式中讀入所有資料,然後新增到一個List(佇列)中,然後在cleanup函式中對list進行處理,輸出我們關係的少量資料。

例項:

在map函式中使用空格分隔每行資料,然後把每個單詞新增到一個堆疊中,在cleanup函式中輸出堆疊中單詞次數比較多的單詞以及次數;

package fz.inmap.aggregation;

import java.io.IOException;
import java.util.ArrayList;
import java.util.PriorityQueue;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class InMapArrgegationDriver extends Configured implements Tool{
	public static Logger log = LoggerFactory.getLogger(InMapArrgegationDriver.class);
	/**
	 * @throws Exception 
	 * 
	 */
	public static void main(String[] args) throws Exception {
		ToolRunner.run(new Configuration(), new InMapArrgegationDriver(),args);
	}

	@Override
	public int run(String[] arg0) throws Exception {
		if(arg0.length!=3){
			System.err.println("Usage:\nfz.inmap.aggregation.InMapArrgegationDriver <in> <out> <maxNum>");
			return -1;
		}
		Configuration conf = getConf();
		
//		System.out.println(conf.get("fs.defaultFS"));
		Path in = new Path(arg0[0]);
		Path out= new Path(arg0[1]);
		out.getFileSystem(conf).delete(out, true);
		conf.set("maxResult", arg0[2]);
		Job job = Job.getInstance(conf,"in map arrgegation job");
		job.setJarByClass(getClass());
		
		job.setInputFormatClass(TextInputFormat.class);
		job.setOutputFormatClass(TextOutputFormat.class);
		
		job.setMapperClass(InMapMapper.class);
		job.setMapOutputKeyClass(Text.class);
		job.setMapOutputValueClass(IntWritable.class);
//		job.setOutputKeyClass(LongWritable.class);
//		job.setOutputValueClass(VectorWritable.class);
		job.setNumReduceTasks(0);
//		System.out.println(job.getConfiguration().get("mapreduce.job.reduces"));
//		System.out.println(conf.get("mapreduce.job.reduces"));
		FileInputFormat.setInputPaths(job, in);
		FileOutputFormat.setOutputPath(job, out);
		
		return job.waitForCompletion(true)?0:-1;
	}
	
	protected static class InMapMapper extends Mapper<LongWritable,Text,Text,IntWritable>{
		private ArrayList<Word> words = new ArrayList<Word>();
		private PriorityQueue<Word> queue;
		private int maxResult;
		
		protected void setup(Context cxt){
			maxResult = cxt.getConfiguration().getInt("maxResult", 10);
		}
		
		protected void map(LongWritable key, Text value,Context cxt){
			String  [] line = value.toString().split(" "); // use blank to split
			for(String word:line){
				Word curr = new Word(word,1);
				if(words.contains(curr)){
					// increase the exists word's frequency
					for(Word w:words){
						if(w.equals(curr)){
							w.frequency++;
							break;
						}
					}
				}else{
					words.add(curr);
				}
			}
		}
		protected void cleanup(Context cxt) throws InterruptedException,IOException{
			Text outputKey = new Text();
			IntWritable outputValue = new IntWritable();
			
			queue = new PriorityQueue<Word>(words.size());
			queue.addAll(words);
			for(int i=0;i< maxResult;i++){
				Word tail = queue.poll();
				if(tail!=null){
					outputKey.set(tail.value);
					outputValue.set(tail.frequency);
					log.info("key is {},value is {}", outputKey,outputValue);
					cxt.write(outputKey, outputValue);
					
				}
			}
		}
	}

}

使用到的Word類
package fz.inmap.aggregation;

public class Word implements Comparable<Word>{

	public String value;
	public int frequency;
	
	public Word(String value,int frequency){
		this.value=value;
		this.frequency=frequency;
	}
	@Override
	public int compareTo(Word o) {
		return o.frequency-this.frequency;
	}
	@Override
	public boolean equals(Object obj){
		if(obj instanceof Word){
			return value.equalsIgnoreCase(((Word)obj).value);
		}else{
			return false;
		}
	}
}

檢視輸出結果,可以看日誌(由於在程式中輸出了日誌,所以在日誌中也可以檢視到);


或者檢視輸出結果:


總結:使用map端聚合,雖然可以大大減小網路資料傳輸量,提高效率,但是我們在應用的時候還是需要考慮實際的應用環境。比如,如果使用上面的演算法來計算最大單詞頻率的前10個,然後還是使用上面的程式碼,就會有問題。每個mapper會處理並輸出自己的單詞詞頻最大的10個單詞,並沒有考慮到所有資料,這樣在reducer端整合的時候就會可能會忽略部分資料,造成最終結果的錯誤。

分享,成長,快樂


相關推薦

hadoop程式設計技巧1---map聚合

測試hadoop版本:2.4 Map端聚合的應用場景:當我們只關心所有資料中的部分資料時,並且資料可以放入記憶體中。使用的好處:可以大大減小網路資料的傳輸量,提高效率;一般程式設計思路:在Mapper的map函式中讀入所有資料,然後新增到一個List(佇列)中,然後在clea

hadoop程式設計技巧5---自定義輸入檔案格式類InputFormat

Hadoop程式碼測試環境:Hadoop2.4應用:在對資料需要進行一定條件的過濾和簡單處理的時候可以使用自定義輸入檔案格式類。Hadoop內建的輸入檔案格式類有:1)FileInputFormat<K,V>這個是基本的父類,我們自定義就直接使用它作為父類;2)T

hadoop程式設計技巧4---全域性key排序類TotalOrderPartitioner

Hadoop程式碼測試版本:Hadoop2.4原理:在進行MR程式之前對輸入資料進行隨機提取樣本,把樣本排序,然後在MR的中間過程Partition的時候使用這個樣本排序的值進行分組資料,這樣就可以達到全域性排序的目的了。難點:如果使用Hadoop提供的方法來實現全域性排序,

程式設計技巧-----前端相關字尾檔案的記錄

最近在學習Vue.js的原始碼,過程之中遇到了一些除了html,css,js字尾的檔案,本著好奇寶寶的原則,我做了一個收集,在這裡做一個分享,希望有跟我一樣坑在前端路上的小白少踩點彎路。 .md: md 表示的是 MarkDown,是一種文字格式的檔案,通過新增一些符號讓文

程式設計技巧-------前端編碼規範

年末了最近在整理檔案,順手寫了一套編碼規範,來源於工作和習慣。雖然程式設計師多不勝數,但是不是每一個程式設計師都寫的一手好程式碼,不論邏輯,單是看上去就沒有讓人讀的慾望。寫程式碼跟寫書寫文件一樣,簡單整潔易明瞭是通用的原則,接觸前端已經四個月,好死不死還是寫了不少的程式碼,爬

一些實用的電腦技巧1

電腦高手的140個電腦小技巧 1. 重灌Windows XP不需再啟用   如果你需要重灌Windows XP,通常必須重新啟用。事實上只要在第一次啟用時,備份好Windows\System32目錄中的Wpa.dbl檔案,就不用再進行啟用的工作了。在重灌Windows XP後,只需要複製該檔案到上面的目錄

Cocos2dx 技巧十三聊聊坐標系

south world 有趣 rect 區別 發現 技術 ins 不同 一好友考上了空姐。她說:以後基本上不會回來了。等下次見面時請叫我白富美!盡管有點羨慕。但我依然不甘示弱回復:下次見面時請叫我高富帥!未來,誰說得準呢?------------------有段時間沒用到

Python練習1

duyuheng python 比較價錢 找出一個月中的天數 計算三角的周長 點在矩形內嗎?金融方面:比較價錢假設你購買大米時發現它有兩種包裝。你會別寫一個程序比較這兩種包裝的價錢。程序提示用戶輸入每種包裝的重量和價錢,然後顯示價錢更好的那種包裝。下面是個示例運行#!/usr/bin/env pytho

unity_實用技巧const

pla refs ref 常量 利用 遊戲 ems 實用 col const:聲明某個常量字段或常量局部變量。 註意:常量字段和常量局部變量不是變量並且不能修改 利用const管理遊戲標簽 例如: //管理所有標簽 public const string Playe

Java開發技巧:配置文件敏感信息處理

加載 gem 加密解密 -i false valid ges enc factory 前言 不知道在上一篇文章中你有沒有發現,jdbc.properties中的數據庫密碼配置是這樣寫的: jdbc.password=5EF28C5A9A0CE86C2D231A526ED5

Excel技巧

輸入 類型 設置 需要 工作 位數 數字 字號 ctrl 1、自動標出不及格分數假定需用紅色字體顯示60以下分數,藍色字體顯示60以上分數。按Ctrl+1,設置單元格格式→自定義。例如:類型輸入框中輸入:[藍色][>=60];[紅色][<60] 2、直接輸入字號

shell腳本編程技巧2——如何解決多行重定,變量不被shell解釋

tps log shell腳本 ces ESS size 分享 sha blog 參考資料 https://blog.csdn.net/ccwwff/article/details/48519119 例子 原理 ![]shell腳本編程小技巧(2)——如何解決多行重定,

C#實戰技巧:List<string>和string[]的相互轉換

List是string型別列表,string[]是string型別陣列,二者可以互相轉換。 1.string[]轉List string[] strArray = {"a", "ab", "abc"}; List<string> strList = new List<s

C#實戰技巧:將剪下板中的內容儲存為圖片

進行C#開發時,可以將複製到剪下板中的內容轉為HTML檔案,再將HTML頁面轉為圖片進行儲存,示例效果如下。 被複制的Excel表格: 生成的圖片: 實現上述功能的主要程式碼如下,能夠將從Word、Excel、網頁等地方複製的內容匯出,並儲存為圖片。 程式碼:

vue開發技巧1

在vue專案中使用stylus Stylus:用於node.js的直觀、強健、極具特色的CSS語言,使css的排版更加直觀 npm install stylus<style scoped lang="stylus"> 在.vue檔案的style塊中使用 <style

cocoscreator之KUOKUO分享常用封裝1

學習cocoscreator一年了,因為自學走過了許許多多的彎路,當然也累積到了不少心得,獨樂樂不如眾樂樂。 在這裡分享給熱愛遊戲開發的小夥伴們,從今天,現在,開始部落格之旅! 都是常用的: //度與弧度進行轉化 function radToDegree(rad){  

基於Visual C++之Windows核心程式設計程式碼分析1實現裝置管理器列舉裝置

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Atitit web 之道 艾龍著 Atitit web 之道 艾龍艾提拉著v2 saa.docx 1. 第1章 Web程式設計基礎知識 1 3 1.1. 1.1 什麼是Web 1 3 1.2.

Atitit web 之道 艾龍著 Atitit web 之道 艾龍艾提拉著v2 saa.docx   1. 第1章 Web程式設計基礎知識 (1) 3 1.1. 1.1 什麼是Web (1) 3 1.2. 1.2 Web的工作原理 (2) 3 1.3. 1.3 Int

easyUI技巧

1、使用tabs時,如果使用的不是url,而是content,則要嵌入iframe addTab({ title:node.text, closeable:true, content:‘<if

C語言筆記1

列舉型別的大小是4,和一個int整形大小一樣   就是最後一個逗號後面的表示式的值,比如: int a=1,b; b=(a+1,a+2,a+3); 那麼b的值就是a+3,也就是4   函式名   :printf  函式原型:in