Hadoop SequenceFile

来源:互联网 发布:电脑无法登陆淘宝网 编辑:程序博客网 时间:2024/05/17 02:56

apache原文:http://hadoop.apache.org/docs/r1.0.4/api/org/apache/hadoop/io/SequenceFile.html


概念:

SequenceFile是一个由二进制序列化过的key/value的字节流组成的文本存储文件,它可以在map/reduce过程中的input/output 的format时被使用。

在map/reduce过程中,map处理文件的临时输出就是使用SequenceFile处理过的。 所以一般的SequenceFile均是在FileSystem中生成,供map调用的原始文件。






在存储结构上,SequenceFile主要由一个Header后跟多条Record组成。


Header主要包含了Key classname,Value classname,存储压缩算法,用户自定义元数据等信息,此外,还包含了一些同步标识,用于快速定位到记录的边界。


每条Record以键值对的方式进行存储,用来表示它的字符数组可依次解析成:记录的长度、Key的长度、Key值和Value值,并且Value值的结构取决于该记录是否被压缩。



数据压缩有利于节省磁盘空间和加快网络传输,SeqeunceFile支持两种格式的数据压缩,分别是:record compression和block compression。


record compression如上图所示,是对每条记录的value进行压缩。


block compression是将一连串的record组织到一起,统一压缩成一个block,如上图。


block信息主要存储了:块所包含的记录数、每条记录Key长度的集合、每条记录Key值的集合、每条记录Value长度的集合和每条记录Value值的集合
注:每个block的大小是可通过io.seqfile.compress.blocksize属性来指定的。



读写实例代码:

分旧API和新API


package filedemo;import java.net.URI;import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.FileSystem;import org.apache.hadoop.fs.Path;import org.apache.hadoop.io.IOUtils;import org.apache.hadoop.io.IntWritable;import org.apache.hadoop.io.SequenceFile;import org.apache.hadoop.io.SequenceFile.Reader;import org.apache.hadoop.io.SequenceFile.Writer;import org.apache.hadoop.io.Text;import org.junit.Test;public class SequenceFileDemo2 {@Testpublic void writerOldApi() throws Exception {// String uri = "file:///D://B.txt"; //本地windowsString uri = "hdfs://hello110:9000/testdata/oldApi.seq";Configuration conf = new Configuration();FileSystem fs = FileSystem.get(new URI(uri), conf, "hadoop");Path path = new Path(uri);IntWritable key = new IntWritable();Text value = new Text();Writer writer = null;try {// 方法一 writer = SequenceFile.createWriter(fs, conf, path,// key.getClass(), value.getClass());该方法已过时writer = new Writer(fs, conf, path, key.getClass(), value.getClass());for (int i = 0; i < 100; i++) {key.set(i);value.set("now the number is :" + i);System.out.printf("[%s]\t[%s]\t%s\t%s\n", "写入",writer.getLength(), key, value);writer.append(key, value);}} finally {IOUtils.closeStream(writer);}}@Testpublic void readerOldApi() throws Exception {// String uri = "file:///D://B.txt"; //本地windowsString uri = "hdfs://hello110:9000/testdata/oldApi.seq";Configuration conf = new Configuration();FileSystem fs = FileSystem.get(new URI(uri), conf, "hadoop");Path path = new Path(uri);IntWritable key = new IntWritable();Text value=new Text();Reader reader =null;try {reader=new Reader(fs, path, conf);while(reader.next(key, value)){System.out.printf("[%s]\t%s\t%s\n", "读取", "key", key);System.out.printf("[%s]\t%s\t%s\n", "读取", "value", value);}} finally {IOUtils.closeStream(reader);}}@Testpublic void writerNewApi() throws Exception {/* * windows环境使用hdfs://的时候,如果没有使用FileSystem指定用户, * 那么会以当前windows用户去访问,如果当前windows用户名和Linux的不同,则会报错: * Exception in thread "main" org.apache.hadoop.security.AccessControlException: Permission denied: user=xxxx * 故而本demo用了 file:// * 解决方法: * 1、修改windows当前用户名为相应的linux-hadoop的用户。win10系统较难修改用户名。 * 2、在linux上增加当前windows用户为hadoop的用户 *///String uri = "hdfs://hello110:9000/testdata/newApi.seq"; String uri = "file:///D://newApi.seq";Configuration conf = new Configuration();Path path = new Path(uri);IntWritable key = new IntWritable();Text value = new Text();Writer writer = null;try {writer = SequenceFile.createWriter(conf,Writer.file(path), Writer.keyClass(key.getClass()),Writer.valueClass(value.getClass()));for (int i = 0; i < 100; i++) {key.set(i);value.set("now the new number is :" + i);System.out.printf("[%s]\t%s\t%s\n", writer.getLength(), key, value);writer.append(key, value);}} finally {IOUtils.closeStream(writer);}}@Testpublic void readerNewApi() throws Exception {String uri = "file:///D://newApi.seq";Configuration conf = new Configuration();Path path = new Path(uri);IntWritable key = new IntWritable();Text value = new Text();Reader reader=null;try {reader=new Reader(conf, Reader.file(path));while(reader.next(key, value)){System.out.printf("[%s]\t%s\t%s\n", "读取", "key", key);System.out.printf("[%s]\t%s\t%s\n", "读取", "value", value);}} finally {IOUtils.closeStream(reader);}}}



0 0
原创粉丝点击