MapReduce进阶笔记1
4. MapReduce编程:数据清洗
mapreduce在企业中,可以用于对海量数据的数据清洗;当然,随着新一代大数据框架的出现,也可以使用spark、flink等框架,做数据清洗
4.1 需求
- 现有一批日志文件,日志来源于用户使用搜狗搜索引擎搜索新闻,并点击查看搜索结果过程;
- 但是,日志中有一些记录损坏,现需要使用MapReduce来将这些损坏记录(如记录中少字段、多字段)从日志文件中删除,此过程就是传说中的数据清洗。
- 并且在清洗时,要统计损坏的记录数。
4.2 数据结构
- 日志格式:每行记录有6个字段;分别表示时间datetime、用户ID userid、新闻搜索关键字searchkwd、当前记录在返回列表中的序号retorder、用户点击链接的顺序cliorder、点击的URL连接cliurl
4.3 逻辑分析
- MapReduce程序一般分为map阶段,将任务分而治之;
- reduce阶段,将map阶段的结果进行聚合;
- 而有些mapreduce应用不需要数据聚合的操作,也就是说不需要reduce阶段。即编程时,不需要编写自定义的reducer类
- 而本例的数据清洗就是属于此种情况
- 统计损坏的记录数,可使用自定义计数器的方式进行
- map方法的逻辑:取得每一行数据,与每条记录的固定格式比对,是否符合;
- 若符合,则是完好的记录;
- 否则是损坏的记录。并对自定义计数器累加
4.4 MR代码
将sogou.50w.utf8上传到HDFS根目录
[hadoop@node01 soft]$ pwd /kkb/soft [hadoop@node01 soft]$ hadoop fs -put sogou.50w.utf8 /
给MR程序在IDEA中设置参数,运行等操作,与上边类似;不再赘述
4.4.1 Mapper类
具体逻辑,可详见代码注释
注意:实际工作中,写良好的代码注释也是基本的职业素养
package com.wph.hadoop.dataclean;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Counter;
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.output.FileOutputFormat;
import java.io.IOException;
/**
*
* 现对sogou日志数据,做数据清洗;将不符合格式要求的数据删除
* 每行记录有6个字段;
* 分别表示时间datetime、用户ID userid、新闻搜索关键字searchkwd、当前记录在返回列表中的序号retorder、用户点击链接的顺序cliorder、点击的URL连接cliurl
* 日志样本:
* 20111230111308 0bf5778fc7ba35e657ee88b25984c6e9 nba直播 4 1 http://www.hoopchina.com/tv
*
*/
public class DataClean {
/**
*
* 基本上大部分MR程序的main方法逻辑,大同小异;将其他MR程序的main方法代码拷贝过来,稍做修改即可
* 实际开发中,也会有很多的复制、粘贴、修改
*
* 注意:若要IDEA中,本地运行MR程序,需要将resources/mapred-site.xml中的mapreduce.framework.name属性值,设置成local
* @param args
*/
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
//判断一下,输入参数是否是两个,分别表示输入路径、输出路径
if (args.length != 2 || args == null) {
System.out.println("please input Path!");
System.exit(0);
}
Configuration configuration = new Configuration();
//调用getInstance方法,生成job实例
Job job = Job.getInstance(configuration, DataClean.class.getSimpleName())