hdoop 文本数据按列去重

来源:互联网 发布:绵阳广电网络宽带 编辑:程序博客网 时间:2024/06/17 05:23
问题描述:
多个数据源的文件合并,根据具体几列(根据需求确定到底是几列)的值确定行的唯一性,删除掉重复的行。我们假设我们的需求是根据文本的前3列来确定行的唯一性,对于重复的行,我们随机选取一行的数据进行保留,不需要考虑其他列的数据。


实际应用中,我们对不同的业务表合并时,可能有这方面的需求,这里我举的例子可能业务说明性不强,但是逻辑一样。


是所以选择使用mapreduce ,是因为真实环境中我们可能需要处理的数据量特别大,使用python进行单机文本处理时,时间效率会受到限制,当文件有1T时,他是不可能一次加载,在根据你需要查找的重复行,去遍历整个文件,这样我们不仅效率低 还容易死机。Mapreduce正适合处理大规模数据,可以并行的执行,减少了运行时间。

   
相同颜色的表示,前三个元素是相同的,我们只需要保留相同行的其中一行就可以了,人为数了一下最后我们需要保留32行的数据。




解决思路: 将需要的列组成key键

需要两个  mapreduce 程序



第一个mapreduce
map函数{   //多个数据源数据合并,并把需要的几列设计为key值,


ComKey=col1+ "+" +col2+ "+" +col3; //我们必须要列之间的 “+”号,这样可以防止元素合并时出现相同的数据
value= line    //line为每一行的数据


context.write(key,value)


}


reduce函数{
//接收 map传递的key/value , 对重复的行进行叠加   
*****使用特定字符串(必须是记录中不可能出现的)在重复行内容叠加的时候有个间隔标志 这里我使用 “[@123456654321@]” ,用于区别重复行的叠加。这个值可以随便设定
 Midd= [@123456654321@]
for(Text each : value){
ComValue=ComValue+each_value+midd;
输出 context.write(counter,"");
}




第二个mapreduce函数   //他的作用就是把刚才的输出文件,进行数据的裁剪


map{


int index= 每个value中 [@123456654321@] 这个字符创出现的位置


String each_value=line.substring(0, index);   //便得到了我们想要的最终结果
Context.write(Text,Text) //写出

}


第一个mapreduce执行完后的结果 




可以看到,重复行的,每行原始数据都没【@123456654312@】这个字符串,分割存储到一行了。
第二个mapreduce执行完后的结果

 

我们可以看到只剩下重复的行已经去除了。


源码:  

http://download.csdn.net/detail/tiandd12/9731296



0 0
原创粉丝点击