ProtocolBuffer 结合 LZO在 Hadoop中的使用(二)
1.LZO介绍
LZO是一种高压缩比和解压速度极快的编码, 特点是
解压缩速度非常快。
LZO是无损压缩,压缩后的数据能准确还原
LZO是基于block分块的,允许数据被分解成chunk,能够被并行的解压
安装可以参照这篇文章:LZO安装
2.如何编写读取写出 protocolBuffer + lzo 文件的mapreduce程序
这里,我用到了elephant-bird-1.0.jar里面的类
mapred/input/LzoProtobufBlockInputFormat.java 读取proto+lzo的数据文件,解析成proto对象, 主要是mapreduce程序使用;
mapred/output/LzoProtobufBlockOutputFormat.java 获取proto对象,存储成proto+lzo的数据文件。 主要是mapreduce程序使用。
1.通过protocol buffers的命令生成java文件(上一章有说明)
假定这个java文件叫做Log.java,只里面定义了输入的文本每个字段的意义
2.调用hadoop按照指定格式导入数据:
hadoop jar /home/app_admin/load.jar com.Test -libjars /home/app_admin/lib/protobuf-java-2.3.0.jar,/home/app_admin/lib/netty-3.5.5.Final.jar,/home/app_admin/lib/elephant-bird-core-3.0.2.jar,/home/app_admin/lib/slf4j-api-1.6.4.jar,/home/app_admin/lib/slf4j-log4j12-1.6.4.jar,/home/app_admin/lib/commons-lang-2.4.jar,/home/app_admin/lib/guava-11.0.1.jar $d
这里的Test类里面大致是这么调用的:
Job job = new Job(getConf(), "load");
job.setJarByClass(com.Test.class);
job.setOutputKeyClass(org.apache.hadoop.io.Text.class);
job.setOutputValueClass(org.apache.hadoop.io.IntWritable.class);
job.setMapperClass(com.TestMapper.class);
job.setNumReduceTasks(0);
job.setInputFormatClass(org.apache.hadoop.mapreduce.lib.input.TextInputFormat.class);
LzoProtobufBlockOutputFormat.setClassConf(com.Logformat.Log.class, job.getConfiguration());
job.setOutputFormatClass(com.twitter.elephantbird.mapreduce.output.LzoProtobufBlockOutputFormat.class);
Date date;
if(args.length >= 1)
{
String st = args[0];
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
try
{
date = sdf.parse(st);
}
catch(ParseException ex)
{
throw new RuntimeException((new StringBuilder()).append("input format error,").append(st).toString());
}
} else
{
Calendar cal = Calendar.getInstance();
cal.add(5, -1);
date = cal.getTime();
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
String inputdir = (new StringBuilder()).append("/log/raw/").append(sdf.format(date)).append("/*access.log*.gz").toString();
logger.info((new StringBuilder()).append("inputdir = ").append(inputdir).toString());
String outfilename = (new StringBuilder()).append("/log/").append((new SimpleDateFormat("yyyyMMdd")).format(date)).toString();
logger.info((new StringBuilder()).append("outfile dir = ").append(outfilename).toString());
Path outFile = new Path(outfilename);
FileSystem.get(job.getConfiguration()).delete(outFile, true);
FileInputFormat.addInputPath(job, new Path(inputdir));
FileOutputFormat.setOutputPath(job, outFile);
job.waitForCompletion(true);
3.使用Pig来处理数据
register /home/app_admin/apps/hadoop/lib/hadoop-lzo-0.4.16.jar
register /home/app_admin/piglib/*.jar
/** com.Logformat.Log类在这里面 */
register /home/app_admin/loadplainlog/loadplainlog-1.0.0.jar
/** 首先从hadoop载入某日的accesslog */
a = load '/log/$logdate/*.lzo' using com.twitter.elephantbird.pig.load.ProtobufPigLoader('com.Logformat.Log');
这里只用了Map函数来导入数据,之后用的是Pig脚本处理数据,并没有使用reduce