对于给定的video日志数据,先利用mapreduce程序进行数据清洗,把数据的存储格式按我们的要求存入文件。
一、数据清洗代码
mapper端对数据清洗后直接输出,不需要reduce阶段
public class ETLMapper extends Mapper<LongWritable, Text,Text, NullWritable>{
private Counter pass;
private Counter fail;
private StringBuilder sb = new StringBuilder();
private Text result = new Text();
@Override
protected void setup(Mapper<LongWritable, Text, Text, NullWritable>.Context context) throws IOException, InterruptedException {
pass = context.getCounter("ETL", "Pass");
fail = context.getCounter("ETL","Fail");
}
/**日志样例:SDNkMu8ZT68 w00dy911 630 People & Blogs 186 10181 3.49 494 257 rjnbgpPJUks
* 将一行的日志进行处理,字段不够的抛弃,将第四个字段中的空格去掉,将最后的相关视频的分隔符改成‘&’
* @param key 行偏移量
* @param value 这行内容
* @param context
* @throws IOException
* @throws InterruptedException
*/
@Override
protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, NullWritable>.Context context) throws IOException, InterruptedException {
//一行数据
String line = value.toString();
//这样切分会把最后一个字段的数据切开,需要最后做拼接
String[] fields = line.split("\t");
//每一行数据都会进入map一次,sb是可变字符串,所以每次进来需要清零。
sb.setLength(0);
//先判断字段个数够不够
if (fields.length >= 9){
//去掉第四个字段的空格(视频标签字段的数组用&连接) 样例:People & Blogs
fields[3] = fields[3].replace(" ","");
//拼接字段
for (int i = 0; i < fields.length; i++) {
if (i == fields.length-1){ //相关视频的最后一个,不用做处理,直接添加
sb.append(fields[i]);
}else if (i <= 8){ //前九个字段之间用\t隔开
sb.append(fields[i]).append("\t");
}else{ //相关视频字段用&隔开
sb.append(fields[i]).append("&");
}
}
result.set(sb.toString());
context.write(result,NullWritable.get());
pass.increment(1);
}else {
//如果字段不够,舍弃不要
fail.increment(1);
}
}
}
driver端