Hadoop(一)复合键

来源:互联网 发布:淘宝的整机为什么便宜 编辑:程序博客网 时间:2024/04/29 17:18

目录(?)[+]

简介:

在大数据处理的基本方法上,对于相互间计算的依赖性不大的数据,mapreduce采用分治的策略进行处理,将大的问题划分成小的问题进行求解,使得问题变得简单可行,同时在处理问题上面,MapReduce框架隐藏了很多的处理细节,将数据切分,任务调度,数据通信,容错,负载均衡.....交给了系统负责,对于很多问题,只需要采取框架的缺省值完成即可,用户只需完成设计map函数很reduce函数即可。

复合键

在一般的情况下只需要使用简单的<key,value>对即可,但是在一些复杂的情况下可以完成很多有效的处理,可以减少网络数据通信开销,提高程序计算效率。
例子:倒排索引 文档检索系统中最常用的数据结构,广泛的应用与全文检索,存储某个单词或者词组在一个文挡或是多个文档中的存储位置的映射,根据内容来查找文档的方式。由于不是根据文档查找内容 而是根据内容来查找文档,进行相反的操作,继而成为倒排索引。
代码:
[java] view plaincopy
  1. package reverseIndex;  
  2.   
  3. import java.io.IOException;  
  4. import java.util.StringTokenizer;  
  5. import org.apache.hadoop.io.LongWritable;  
  6. import org.apache.hadoop.io.Text;  
  7. import org.apache.hadoop.mapred.FileSplit;  
  8. import org.apache.hadoop.mapreduce.Mapper;  
  9. import org.apache.hadoop.mapreduce.Reducer;  
  10.   
  11. /** 
  12.  * 倒排索引:根据内容查找文件  
  13.  * xd is a good man ->file1.txt 
  14.  * good boy is xd   ->file2.txt 
  15.  * xd like beautiful women ->file3.txt 
  16.  * 对应下: 
  17.  * xd ->file1.txt file2.txt file3.txt 
  18.  * is ->file1.txt file2.txt 
  19.  * a ->file1.txt 
  20.  * good ->file1.txt file2.txt 
  21.  * man ->file1.txt 
  22.  * boy ->file2.txt 
  23.  * like ->file3.txt 
  24.  * beautiful ->file3.txt 
  25.  * women ->file3.txt 
  26.  * 在每个map函数中 所需数据对 是<"单词+文件名","词频"> 便于combiner的词频统计 
  27.  * 而在combiner中  将数据对变为<"单词","文件名+词频"> 便于将相同的key的数据 分发到 同一个reducer中执行 (HashPartition). 
  28.  * @author XD 
  29.  */  
  30. public class inverseIndex {  
  31.     public static class Map extends Mapper<LongWritable,Text,Text,Text>{  
  32.         private Text keyInfo = new Text();  //key值  
  33.         private Text valueInfo = new Text();    //value值  
  34.         private FileSplit split;    //回去文件的splie对象  
  35.         public void map(LongWritable key,Text value,Context context) throws IOException, InterruptedException{  
  36.             split = (FileSplit)context.getInputSplit(); //关键 获取<key,value>所属的split对象  
  37.             StringTokenizer itr = new StringTokenizer(value.toString());  
  38.             while(itr.hasMoreTokens()){  
  39.                 int splitIndex = split.getPath().toString().indexOf("file");//获取文件名 包含file的索引位置  
  40.                 keyInfo.set(itr.nextToken()+":"+split.getPath().toString().substring(splitIndex));  //设定key值  
  41.                 valueInfo.set("1");  
  42.                 context.write(keyInfo, valueInfo);  
  43.             }  
  44.         }  
  45.     }  
  46.     public static class combiner extends Reducer<Text,Text,Text,Text>{  
  47.         private Text info = new Text(); //为了拆分 key值 准备存储新的value值  
  48.         public void reduce(Text key,Iterable<Text>values,Context context) throws IOException, InterruptedException{  
  49.             int sum = 0;  
  50.             for(Text val:values){  
  51.                 sum += Integer.parseInt(val.toString());  
  52.             }  
  53.             int splitIndex = key.toString().indexOf(":");  
  54.             info.set(key.toString().substring(splitIndex+1)+":"+sum);   //新的value值  
  55.             key.set(key.toString().substring(0, splitIndex));  
  56.             context.write(key, info);  
  57.         }  
  58.     }  
  59.     public static class Reduce extends Reducer<Text,Text,Text,Text>{  
  60.         private Text result = new Text();   //设定最终的输出结果  
  61.         public void reduce(Text key,Iterable<Text>values,Context context) throws IOException, InterruptedException{  
  62.             String list = new String();  
  63.             for(Text val:values){  
  64.                 list += val.toString()+";"//不同的索引文件分隔开来  
  65.             }  
  66.             result.set(list);  
  67.             context.write(key,result);  
  68.         }         
  69.     }  
  70. }  

用户自定义数据类型

Hadoop中提供了很多的内置数据类型,但是在解决一些复杂的问题,这些内置的简单数据类型很难满足用户的需求,需要自定义数据类型。用户在自定义数据类型的时候,需要实现Writable接口,以便数据可以被序列化后完成网络传输或是文件的输入输出。此外,要是数据需要作为主键使用或者需要比较数值大小时,需要实现WritableComparable接口。
例子:
[java] view plaincopy
  1. package com.rpc.nefu;  
  2.   
  3. import java.io.DataInput;  
  4. import java.io.DataOutput;  
  5. import java.io.IOException;  
  6.   
  7. import org.apache.hadoop.io.WritableComparable;  
  8.   
  9. //对自己输入的数据需要 可序列化  即自定义一个可序列化的类  
  10. public class keyvalue implements WritableComparable<keyvalue>{  
  11.     public int x,y;  
  12.     public keyvalue(){  
  13.         this.x = 0;  
  14.         this.y = 0;  
  15.     }  
  16.     public keyvalue(int x1,int y1){  
  17.         this.x = x1;  
  18.         this.y = y1;  
  19.     }  
  20.     @Override  
  21.     public void readFields(DataInput in) throws IOException {  
  22.         // TODO Auto-generated method stub  
  23.         x = in.readInt();  
  24.         y = in.readInt();  
  25.           
  26.     }  
  27.   
  28.     @Override  
  29.     public void write(DataOutput out) throws IOException {  
  30.         // TODO Auto-generated method stub  
  31.         out.writeInt(x);  
  32.         out.writeInt(y);  
  33.     }  
  34.     public int distanceFromOrigin(){  
  35.         return (x*x+y*y);  
  36.     }  
  37.     public boolean equals(keyvalue o){  
  38.         if(!(o instanceof keyvalue)){  
  39.             return false;  
  40.         }  
  41.         return (this.x == o.x) && (this.y == o.y);  
  42.     }  
  43.     public int hashCode() {  
  44.         return Float.floatToIntBits(x)  
  45.             ^ Float.floatToIntBits(y);  
  46.               
  47.     }  
  48.     public String toString(){  
  49.         return Integer.toString(x)+","+Integer.toString(y);  
  50.     }  
  51.     @Override  
  52.     public int compareTo(keyvalue o) {  
  53.         //return x;  
  54.         // TODO Auto-generated method stub  
  55.         if(x > o.x){  
  56.             return 1;  
  57.         }else if(x == o.x){  
  58.             return 0;  
  59.         }else{  
  60.             return -1;  
  61.         }  
  62.     }     
  63. }  
0 0
原创粉丝点击