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 文件,包含的是二进制的过滤表,在每一次写操作完成时,会更新这个过滤表。

操作

读写文件

package com.eric.hadoop.io.sequencefile;
import java.io.IOException;
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.Text;
/**
 * @author Eric.sunah 2014年12月10日
 *
 */
public class SequenceFileDemo {

 private static final String OPERA_FILE = "./output.seq";
 /**
  * 随便从网上截取的一段文本
  */
 private static String[]    testArray = { "<plugin>                                                                     ",
         "  <groupId>org.apache.avro</groupId>                                         ",
         "  <artifactId>avro-maven-plugin</artifactId>                                 ",
         "  <version>1.7.7</version>                                                   ",
         "  <executions>                                                               ",
         "    <execution>                                                              ",
         "      <phase>generate-sources</phase>                                        ",
         "      <goals>                                                                ",
         "        <goal>schema</goal>                                                  ",
         "      </goals>                                                               ",
         "      <configuration>                                                        ",
         "        <sourceDirectory>${project.basedir}/src/main/avro/</sourceDirectory> ",
         "        <outputDirectory>${project.basedir}/src/main/java/</outputDirectory> ",
         "      </configuration>                                                       ",
         "    </execution>                                                             ",
         "  </executions>                                                              ",
         "</plugin>                                                                    ",
         "<plugin>                                                                     ",
         "  <groupId>org.apache.maven.plugins</groupId>                                ",
         "  <artifactId>maven-compiler-plugin</artifactId>                             ",
         "  <configuration>                                                            ",
         "    <source>1.6</source>                                                     ",
         "    <target>1.6</target>                                                     ",
         "  </configuration>                                                           ", "</plugin>"};

 public static void main(String[] args) throws IOException {
  writeSequenceFile(OPERA_FILE);
  readSequenceFile(OPERA_FILE);
 }

 private static void readSequenceFile(String inputFile) throws IOException {
  Configuration config = new Configuration();
  Path path = new Path(inputFile);
  SequenceFile.Reader reader = null;
  try {

   FileSystem fs = FileSystem.get(URI.create(inputFile), config);
   reader = new SequenceFile.Reader(fs, path, config);
   IntWritable key = new IntWritable();
   Text value = new Text();
   long posion = reader.getPosition();
   // reader.next()返回非空的话表示正在读,如果返回null表示已经读到文件结尾的地方
   while (reader.next(key, value)) {
    //打印同步点的位置信息
    String syncMark = reader.syncSeen() ? "*" : "";
    System.out.printf("[%s\t%s]\t%s\t%s\n", posion, syncMark, key, value);
    posion = reader.getPosition();
   }
  } finally {
   IOUtils.closeStream(reader);
  }

 }

 /**
  * 写Sequence File 文件
  *
  * @param outputFile
  * @throws IOException
  */
 private static void writeSequenceFile(String outputFile) throws IOException {
  Configuration config = new Configuration();
  Path path = new Path(outputFile);
  IntWritable key = new IntWritable();
  Text value = new Text();
  SequenceFile.Writer writer = null;
  try {

   FileSystem fs = FileSystem.get(URI.create(outputFile), config);
   writer = SequenceFile.createWriter(fs, config, path, key.getClass(), value.getClass());
   for (int i = 1; i < 2000; i++) {
    key.set(2000 - i);
    value.set(testArray[i % testArray.length]);
    System.out.printf("[%s]\t%s\t%s\n", writer.getLength() + "", key, value);
    // 通过Append方法进行写操作
    writer.append(key, value);
   }
  } finally {
   IOUtils.closeStream(writer);
  }

 }
}
时间: 2024-12-21 05:16:51

Hadoop 中SequenceFile的简介的相关文章

Hadoop中SequenceFile的使用

1.对于某些应用而言,需要特殊的数据结构来存储自己的数据.对于基于MapReduce的数据处理,将每个二进制数据的大对象融入自己的文件中并不能实现很高的可扩展性,针对上述情况,Hadoop开发了一组更高层次的容器SequenceFile. 2. 考虑日志文件,其中每一条日志记录是一行文本.如果想记录二进制类型,纯文本是不合适的.这种情况下,Hadoop的SequenceFile类非常合适,因为上述提供了二进制键/值对的永久存储的数据结构.当作为日志文件的存储格式时,可以自己选择键,比如由Long

hadoop中slot简介(map slot 和 reduce slot)

Slots是Hadoop的一个重要概念.然而在Hadoop相关论文,slots的阐述难以理解.网上关于slots的概念介绍也很少,而对于一个有经验的Hadoop开发者来说,他们可能脑子里已经理解了slots的真正含义,但却难以清楚地表达出来,Hadoop初学者听了还是云里雾里.我来尝试讲解一下,以期抛砖引玉. 首先,slot不是CPU的Core,也不是memory chip,它是一个逻辑概念,一个节点的slot的数量用来表示某个节点的资源的容量或者说是能力的大小,因而slot是 Hadoop的资

Hadoop之SequenceFile

Hadoop序列化文件SequenceFile可以用于解决大量小文件(所谓小文件:泛指小于black大小的文件)问题,SequenceFile是Hadoop API提供的一种二进制文件支持.这种二进制文件直接将<key,value>对序列化到文件中,一般对小文件可以使用这种文件合并,即将文件名作为key,文件内容作为value序列化到大文件中. hadoop Archive也是一个高效地将小文件放入HDFS块中的文件存档文件格式,详情请看:hadoop Archive 但是SequenceFi

Zookeeper 在Hadoop中的应用

Zookeeper 简介 Zookeeper 分布式服务框架是 Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务.状态同步服务.集群管理.分布式应用配置项的管理等. Hadoop简介 Hadoop是一个由Apache基金会所开发的分布式系统基础架构. 用户可以在不了解分布式底层细节的情况下,开发分布式程序.充分利用集群的威力进行高速运算和存储. Hadoop主要包含两部分:HDFS,YARN. HDFS有高容错性的特点,并且设计用

Hadoop中Writable类之二

1.ASCII.Unicode.UFT-8 在看Text类型的时候,里面出现了上面三种编码,先看看这三种编码: ASCII是基于拉丁字母的一套电脑编码系统.它主要用于显示现代英语和其他西欧语言.它是现今最通用的单字节编码系统,并等同于国际标准ISO/IEC 646.ASCII是7位字符集,是美国标准信息交换代码的缩写,为美国英语通信所设计.它由128个字符组成,包括大小写字母.数字0-9.标点符号.非打印字符(换行副.制表符等4个)以及控制字符(退格.响铃等)组成.从定义,很明显,单字节编码,现

[转] - hadoop中使用lzo的压缩

在hadoop中使用lzo的压缩算法可以减小数据的大小和数据的磁盘读写时间,不仅如此,lzo是基于block分块的,这样他就允许数据被分解成chunk,并行的被hadoop处理.这样的特点,就可以让lzo在hadoop上成为一种非常好用的压缩格式. lzo本身不是splitable的,所以当数据为text格式时,用lzo压缩出来的数据当做job的输入是一个文件作为一个map.但是sequencefile本身是分块的,所以sequencefile格式的文件,再配上lzo的压缩格式,就可实现lzo文

关于学习Hadoop中未总结的资料

出自:http://www.cnblogs.com/xia520pi/archive/2012/01/02/2310118.html 1)Cygwin相关资料 (1)Cygwin上安装.启动ssh服务失败.ssh localhost失败的解决方案 地址:http://blog.163.com/pwcrab/blog/static/16990382220107267443810/ (2)windows2003+cygwin+ssh 地址:http://wenku.baidu.com/view/37

c#中的数据类型简介(数组)

c#中的数据类型简介(数组) 数组定义 可以将数组看成相同数据类型的一组或多组数据,包括一维数组,多维数组和交错数组 数据申明 一维数组的几种申明和实例化 type[]  typeName = new type[n]:                                                //定义数组但是未赋值 type[0] = item1; type[1] = item2; type[2] = item3; ...... type[n-1] =itemn; type[

c#中的数据类型简介(枚举)

C#中的数据类型简介(枚举) 枚举的定义 根据MSDN上给出的定义,枚举是一个指定的常数集,其基础类型可以是除Char外的任何整型. 如果没有显式声明基础类型,则使用 Int32. Enum 是 .NET Framework 中所有枚举的基类.其基础类型可以是byte.sbyte.short.ushort.int.unit.long.ulong.默认情况下,第一个枚举数的值为0,然后后续的枚举数依次加1. 枚举的申明 枚举可以申明在命名空间下和类同级别,也可申明在类的内部.申明语法如下: [ac