Hadoop中SequenceFile用法

概念

SequenceFile是一个由二进制序列化过的key/value的字节流组成的文本存储文件,它可以在map/reduce过程中的input/output 的format时被使用。在map/reduce过程中,map处理文件的临时输出就是使用SequenceFile处理过的。 所以一般的SequenceFile均是在FileSystem中生成,供map调用的原始文件。

特点

SequenceFile是 Hadoop 的一个重要数据文件类型,它提供key-value的存储,但与传统key-value存储(比如hash表,btree)不同的是,它是append only的,于是你不能对已存在的key进行写操作。

SequenceFile可以作为小文件的容器,可以通过它将小文件包装起来传递给MapReduce进行处理。

SequenceFile提供了两种定位文件位置的方法

  1. seek(long poisitiuion):poisition必须是记录的边界,否则调用next()方法时会报错
  2. sync(long poisition):Poisition可以不是记录的边界,如果不是边界,会定位到下一个同步点,如果Poisition之后没有同步点了,会跳转到文件的结尾位置

状态

SequenceFile 有三种压缩态:

  1.   Uncompressed – 未进行压缩的状
  2.   record compressed - 对每一条记录的value值进行了压缩(文件头中包含上使用哪种压缩算法的信息)
  3.   block compressed – 当数据量达到一定大小后,将停止写入进行整体压缩,整体压缩的方法是把所有的keylength,key,vlength,value 分别合在一起进行整体压缩,块的压缩效率要比记录的压缩效率高

格式

每一个SequenceFile都包含一个“头”(header)。Header包含了以下几部分。

     1.SEQ三个字母的byte数组

     2.Version number的byte,目前为数字3的byte

     3.Key和Value的类名

     4.压缩相关的信息

     5.其他用户定义的元数据

     6.同步标记,sync marker

对于每一条记录(K-V),其内部格式根据是否压缩而不同。SequenceFile的压缩方式有两种,“记录压缩”(record compression)和“块压缩”(block compression)。如果是记录压缩,则只压缩Value的值。如果是块压缩,则将多条记录一并压缩,包括Key和Value。具体格式如下面两图所示:

扩展实现

  1. MapFile  一个key-value 对应的查找数据结构,由数据文件/data 和索引文件 /index 组成,数据文件中包含所有需要存储的key-value对,按key的顺序排列。索引文件包含一部分key值,用以指向数据文件的关键位置
  2. SetFile – 基于 MapFile 实现的,他只有key,value为不可变的数据。
  3. ArrayFile – 也是基于 MapFile 实现,他就像我们使用的数组一样,key值为序列化的数字。      
  4. BloomMapFile – 他在 MapFile 的基础上增加了一个 /bloom 文件,包含的是二进制的过滤表,在每一次写操作完成时,会更新这个过滤表。

以上装载与: https://blog.csdn.net/eric_sunah/article/details/41854731

下面我是对sequenceFIle的一些编写

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.SequenceFile;
import org.apache.hadoop.io.SequenceFile.Writer;
import org.apache.hadoop.io.Text;
import org.junit.Test;


public class mySequence {
//写数据
@Test
public void SequenceW() throws Exception {
	Configuration conf=new Configuration();
	FileSystem fs = FileSystem.get(conf);
	Path p=new Path("/user/had/zxz.txt");
	Writer w=SequenceFile.createWriter(fs,conf, p, IntWritable.class, Text.class);
	w.append(new IntWritable(1), new Text("zxz1"));
	w.append(new IntWritable(2), new Text("zxz2"));
	w.append(new IntWritable(3), new Text("zxz3"));
	w.append(new IntWritable(4), new Text("zxz4"));
	w.close();
}

//读数据
@Test
public void SequenceR() throws Exception {
	Configuration conf=new Configuration();
	FileSystem fs = FileSystem.get(conf);
	Path p=new Path("/user/had/zxz.txt");
	SequenceFile.Reader sr=new SequenceFile.Reader(fs, p, conf);
	IntWritable k = new IntWritable();
	Text v = new Text();
    while(sr.next(k, v)) {
    	System.out.println(k+"  "+v);
    }
    sr.close();
}
//写数据时手动创建同步点
@Test
public void SequenceWSync() throws IOException {
	Configuration conf=new Configuration();
	FileSystem fs = FileSystem.get(conf);
	Path p=new Path("/user/had/zxz1.txt");
	SequenceFile.Writer sfw=new SequenceFile.Writer(fs, conf, p,new  Text().getClass(), new IntWritable().getClass());
	for (int i = 0; i < 100; i++) {
		sfw.append(new Text("zxz"+i), new IntWritable(i));
	    sfw.sync();
	}
	sfw.close();
}
//利用同步点实现读写所有数据
@Test
public void SequenceRSysnc() throws IOException {
	Configuration conf=new Configuration();
	FileSystem fs = FileSystem.get(conf);
	Path p=new Path("/user/had/zxz1.txt");
	SequenceFile.Reader sfr=new SequenceFile.Reader(fs, p, conf);
	IntWritable v = new IntWritable();
	Text k = new Text();
	while(sfr.next(k, v)){
		sfr.sync(sfr.getPosition());
		System.out.println(k+"   "+v);
	}
	sfr.close();
}
}

猜你喜欢

转载自blog.csdn.net/weixin_41122339/article/details/82621536
今日推荐