Hadoop SequenceFile

1. 简介

SequenceFile是Hadoop自带的一种文件格式,为二进制键/值对提供一个持久化的数据结构。它并列地存放<键,值>均为Hadoop序列化支援的Writable对象。SequenceFile可以作为小型的文件容器,提供一种解决大量小文件的存放方案。

2. 编程示例

写入操作

将写入十个键值对到文件中,分别是0~9的数字和英文单词的键值对,如<0,”zero”> <1,”one”>等。写入操作非常简单,只需要获得SequenceFile.Writer对象并调用append方法写入即可。SequenceFileWrite.java:

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.IOUtils;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.SequenceFile;
import org.apache.hadoop.io.Text;

/**
 * 2011年11月16日 上午11:26:23
 */
public class SequenceFileWrite {

    private static final String[] DATA = { "zero", "one", "two", "three",
            "four", "five", "six", "seven", "eight", "nine" };

    public static void main(String[] args) throws IOException {
        if (args.length != 1) {
            System.out.println("usage: SequenceFileWrite URI");
            return;
        }

        String uri = args[0];
        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(conf);
        Path path = new Path(uri);

        IntWritable key = new IntWritable();
        Text value = new Text();
        SequenceFile.Writer writer = null;

        try {
            // 获得SequenceFile.Writer对象
            writer = SequenceFile.createWriter(fs, conf, path, key.getClass(),
                    value.getClass());

            for (int i = 0; i < DATA.length; i++) {
                key.set(i);
                value.set(DATA[i]);
                // 写入键/值对
                writer.append(key, value);
            }
        } finally {
            IOUtils.closeStream(writer);
        }
    }
}

编译后执行:

hadoop-run SequenceFileWrite test.seq

成功的话将在HDFS下看到test.seq这个文件:

hadoop fs -ls

查看seq文件的内容(实用):

hadoop fs -text test.seq

读取操作

读取操作与写入操作对应,获得SequenceFile.Reader对象再循环读出数据。SequenceFileRead.java:

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.IOUtils;
import org.apache.hadoop.io.SequenceFile;
import org.apache.hadoop.io.Writable;
import org.apache.hadoop.util.ReflectionUtils;

/**
 * 2011年11月16日 上午11:26:23
 */
public class SequenceFileRead {

    public static void main(String[] args) throws IOException {
        if (args.length != 1) {
            System.out.println("usage: SequenceFileRead URI");
            return;
        }

        String uri = args[0];
        Configuration conf = new Configuration();
        FileSystem fs = FileSystem.get(conf);
        Path path = new Path(uri);

        SequenceFile.Reader reader = null;
        try {
            // 获得SequenceFile.Reader对象
            reader = new SequenceFile.Reader(fs, path, conf);

            // 获得key/value的类型
            Writable key = (Writable) ReflectionUtils.newInstance(reader
                    .getKeyClass(), conf);
            Writable value = (Writable) ReflectionUtils.newInstance(reader
                    .getValueClass(), conf);

            long position = reader.getPosition();
            // 循环读取文件内容
            while (reader.next(key, value)) {
                String syncSeen = reader.syncSeen() ? "*" : "";
                // 打印出键/值对
                System.out.printf("[pos:%s%s]\t%s\t%s\n", position, syncSeen,
                        key, value);
                position = reader.getPosition();
            }
        } finally {
            IOUtils.closeStream(reader);
        }
    }

}

SequenceFile.Reader提供2种方式查找文件指定位置:

  1. seek方法,给定的位置必须是记录边界,否则调用next方法读取key/value时将出错
  2. sync方法,找到给定位置之后的同步点,如果之后没有同步点,则定位到文件末尾

3. 数据结构/原理

SequenceFile的文件结构是扁平式、并列式的,虽然还分压缩未压缩、分块不分块等集中组织结构,但基本文件结构如下:

header * <key,value><key,value><key,value> * <key,value><key,value>

其中header是文件头,它包含了版本号、键值类型、是否压缩、是否分块等信息;<key,value>则是并列地存放着键/值对,存放的实际内容是:键的长度(4字节)、总长度(4字节)、二进制的键、二进制的值。

上面的型号*表示同步点,它佔有容量不超过文件大小的1%。它以4个字节的-1开头,以此区分<key,value>;然后紧跟16字节的hash校验值。和可能的猜想不同,header并没有记录同步点的位置,因此seek和sync方法很慢。

文档更新时间: 2018-11-10 19:03   作者:nick