SequenceFile 简介
SequenceFile是hadoop作业中中间序列化传输的格式,其主要作用是压缩空间,以便提高传输速率,因为hadoop任务的速度主要消耗在网络IO和磁盘IO上,减小文件大小当然可以加快速度。
SequenceFile的格式
几个点:
- 可以看出还是KV格式的,具体的介绍就赘述了,网上和官网上都很多。
- 可以压缩
- 二进制文件
hadoop2.x中的SequenceFile包
- SequenceFileInputFormat
- SequenceFileAsBinaryInputFormat
- SequenceFileAsTextInputFormat
- SequenceFileOutputFormat
使用
首先你要明白几个配置:
job.setOutputKeyClass(Text.class); // 设置输出key的类型
job.setOutputValueClass(BytesWritable.class);//设置输出的类型
job.setInputFormatClass(TextInputFormat.class); // 设置Job输入分割格式(InputFormat)
job.setOutputFormatClass(SequenceFileOutputFormat.class); // 设置Job输出分割格式(InputFormat)
// job.setOutputFormatClass(TextOutputFormat.class); // 设置Job输出分割格式(InputFormat)
看起来是不是很奇怪,既然设置了输出的Value为BytesWritable类型了,那和OutputFormatClass有什么关系呢?
我们看一下TextOutputFormat.class的源码:
private void writeObject(Object o) throws IOException {
if (o instanceof Text) {
Text to = (Text) o;
out.write(to.getBytes(), 0, to.getLength());
} else {
out.write(o.toString().getBytes(utf8));
}
}
你会发现调用了Object o的toString()方法。
也就是最后job输出的时候,会用outputformat去封装OutputValueClass,调用OutputValueClass中的write函数输出到流,然后转成outputformat定义的格式,那么从此,可以推断出,想要读入的话,制定相应的类型就行了。
就像这样:
输出SequenceFile
public static class Reduce extends Reducer<Text, Text, Text, BytesWritable> {
@Override
public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
HLLCounter hll = new HLLCounter(true);
for (Text v : values) {
hll.put(v.toString());
}
HLLWritable hw = new HLLWritable(hll);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(bos);
hw.write(out);
context.write(key, new BytesWritable(bos.toByteArray()));
}
}
读入刚才的输出
public static class MyMapper extends Mapper<Text, BytesWritable, Text, Text> {
@Override
protected void map(Text key, BytesWritable value, Context context) throws IOException, InterruptedException {
// TODO Auto-generated method stub
ByteArrayInputStream bis = new ByteArrayInputStream(value.getBytes());
DataInputStream dis = new DataInputStream(bis);
HLLWritable hw = new HLLWritable();
hw.readFields(dis);
dis.close();
dis.close();
context.write(key, new Text(hw.toString()));
}
}
上面那几个Format就不介绍了,自己百度一下都有。