Hadoop: the definitive guide 第三版 拾遗 第四章 之SequenceFile操作

来源:互联网 发布:淘宝怎么搜二手 编辑:程序博客网 时间:2024/04/30 09:19

本文转自:http://blog.csdn.net/hadoop_    


SequenceFile文件是Hadoop用来存储二进制形式的key-value对而设计的一种平面文件(Flat File)。目前,也有不少人在该文件的基础之上提出了一些HDFS中小文件存储的解决方案,他们的基本思路就是将小文件进行合并成一个大文件,同时对这些小文件的位置信息构建索引。不过,这类解决方案还涉及到Hadoop的另一种文件格式——MapFile文件。SequenceFile文件并不保证其存储的key-value数据是按照key的某个顺序存储的,同时不支持append操作。
      在SequenceFile文件中,每一个key-value被看做是一条记录(Record),因此基于Record的压缩策略,SequenceFile文件可支持三种压缩类型(SequenceFile.CompressionType):
1、NONE: 对records不进行压缩;
2、RECORD: 仅压缩每一个record中的value值;对每一条记录的value值进行了压缩(文件头中包含上使用哪种压缩算法的信息)
3、BLOCK: 将一个block中的所有records压缩在一起;当数据量达到一定大小后,将停止写入进行整体压缩,整体压缩的方法是把所有的keylength,key,vlength,value 分别合在一起进行整体压缩。文件的压缩态标识在文件开头的header数据中。


       基于这三种压缩类型,Hadoop提供了对应的三种类型的Writer:
1、SequenceFile.Writer  写入时不压缩任何的key-value对(Record);

2、SequenceFile.RecordCompressWriter写入时只压缩key-value对(Record)中的value;

3、SequenceFile.BlockCompressWriter 写入时将一批key-value对(Record)压缩成一个Block;

一、SequenceFile写操作

[java] view plaincopy
  1. package com.tht.hadoopIO;  
  2.   
  3. //cc SequenceFileWriteDemo Writing a SequenceFile  
  4. import java.io.IOException;  
  5. import java.net.URI;  
  6.   
  7. import org.apache.hadoop.conf.Configuration;  
  8. import org.apache.hadoop.fs.FileSystem;  
  9. import org.apache.hadoop.fs.Path;  
  10. import org.apache.hadoop.io.IOUtils;  
  11. import org.apache.hadoop.io.IntWritable;  
  12. import org.apache.hadoop.io.SequenceFile;  
  13. import org.apache.hadoop.io.Text;  
  14.   
  15. //vv SequenceFileWriteDemo  
  16. public class SequenceFileWriteDemo {  
  17.   
  18.     private static final String[] DATA = { "One, two, buckle my shoe",  
  19.             "Three, four, shut the door""Five, six, pick up sticks",  
  20.             "Seven, eight, lay them straight""Nine, ten, a big fat hen" };  
  21.   
  22.     public static void main(String[] args) throws IOException {  
  23. //      String uri = args[0];  
  24.         String uri = "hdfs://master:9000/seq/numbers.seq";  
  25.           
  26.         Configuration conf = new Configuration();  
  27.         FileSystem fs = FileSystem.get(URI.create(uri), conf);  
  28.         Path path = new Path(uri);  
  29.   
  30.         IntWritable key = new IntWritable();  
  31.         Text value = new Text();  
  32.         SequenceFile.Writer writer = null;  
  33.         try {  
  34.             writer = SequenceFile.createWriter(fs, conf, path, key.getClass(),  
  35.                     value.getClass());  
  36.   
  37.             for (int i = 0; i < 100; i++) {  
  38.                 key.set(100 - i);  
  39.                 value.set(DATA[i % DATA.length]);  
  40.                 System.out.printf("[%s]\t%s\t%s\n", writer.getLength(), key,  
  41.                         value);  
  42.                 writer.append(key, value);  
  43.             }  
  44.         } finally {  
  45.             IOUtils.closeStream(writer);  
  46.         }  
  47.     }  
  48. }  
  49. // ^^ SequenceFileWriteDemo  
上述代码将自定义的DATA写入hdfs集群的../seq/numbers.seq文件中。
二、SequenceFile读操作

[java] view plaincopy
  1. package com.tht.hadoopIO;  
  2.   
  3. //cc SequenceFileReadDemo Reading a SequenceFile  
  4. import java.io.IOException;  
  5. import java.net.URI;  
  6.   
  7. import org.apache.hadoop.conf.Configuration;  
  8. import org.apache.hadoop.fs.FileSystem;  
  9. import org.apache.hadoop.fs.Path;  
  10. import org.apache.hadoop.io.IOUtils;  
  11. import org.apache.hadoop.io.SequenceFile;  
  12. import org.apache.hadoop.io.Writable;  
  13. import org.apache.hadoop.util.ReflectionUtils;  
  14.   
  15. //vv SequenceFileReadDemo  
  16. public class SequenceFileReadDemo {  
  17.   
  18.     public static void main(String[] args) throws IOException {  
  19. //      String uri = args[0];     
  20.         String uri = "hdfs://master:9000/seq/numbers.seq";  
  21.   
  22.         Configuration conf = new Configuration();  
  23.         FileSystem fs = FileSystem.get(URI.create(uri), conf);  
  24.         Path path = new Path(uri);  
  25.   
  26.         SequenceFile.Reader reader = null;  
  27.         try {  
  28.             reader = new SequenceFile.Reader(fs, path, conf);  
  29.             Writable key = (Writable) ReflectionUtils.newInstance(  
  30.                     reader.getKeyClass(), conf);  
  31.             Writable value = (Writable) ReflectionUtils.newInstance(  
  32.                     reader.getValueClass(), conf);  
  33.             long position = reader.getPosition();  
  34.             while (reader.next(key, value)) {  
  35.                 String syncSeen = reader.syncSeen() ? "*" : "";  
  36.                 System.out.printf("[%s%s]\t%s\t%s\n", position, syncSeen, key,  
  37.                         value);  
  38.                 position = reader.getPosition(); // beginning of next record  
  39.             }  
  40.         } finally {  
  41.             IOUtils.closeStream(reader);  
  42.         }  
  43.     }  
  44. }  
  45. // ^^ SequenceFileReadDemo  

三、搜索SequenceFile中的指定位置

[java] view plaincopy
  1. package com.tht.hadoopIO;  
  2.   
  3. //== SequenceFileSeekAndSyncTest  
  4. //== SequenceFileSeekAndSyncTest-SeekNonRecordBoundary  
  5. //== SequenceFileSeekAndSyncTest-SyncNonRecordBoundary  
  6. import static org.hamcrest.CoreMatchers.is;  
  7. import static org.junit.Assert.assertThat;  
  8.   
  9. import java.io.IOException;  
  10. import java.net.URI;  
  11. import org.apache.hadoop.conf.Configuration;  
  12. import org.apache.hadoop.fs.*;  
  13. import org.apache.hadoop.io.*;  
  14. import org.apache.hadoop.util.ReflectionUtils;  
  15. import org.junit.*;  
  16.   
  17. public class SequenceFileSeekAndSyncTest {  
  18.   
  19.     private static final String SF_URI = "hdfs://master:9000/seq/numbers.seq";  
  20.     private FileSystem fs;  
  21.     private SequenceFile.Reader reader;  
  22.     private Writable key;  
  23.     private Writable value;  
  24.   
  25.     @Before  
  26.     public void setUp() throws IOException {  
  27.         SequenceFileWriteDemo.main(new String[] { SF_URI });  
  28.   
  29.         Configuration conf = new Configuration();  
  30.         fs = FileSystem.get(URI.create(SF_URI), conf);  
  31.         Path path = new Path(SF_URI);  
  32.   
  33.         reader = new SequenceFile.Reader(fs, path, conf);  
  34.         key = (Writable) ReflectionUtils  
  35.                 .newInstance(reader.getKeyClass(), conf);  
  36.         value = (Writable) ReflectionUtils.newInstance(reader.getValueClass(),  
  37.                 conf);  
  38.     }  
  39.   
  40. //  @After  
  41. //  public void tearDown() throws IOException {  
  42. //      fs.delete(new Path(SF_URI), true);  
  43. //  }  
  44.   
  45.     @Test  
  46.     public void seekToRecordBoundary() throws IOException {  
  47.         // vv SequenceFileSeekAndSyncTest  
  48.         reader.seek(359);  
  49.         assertThat(reader.next(key, value), is(true));  
  50.         assertThat(((IntWritable) key).get(), is(95));  
  51.         // ^^ SequenceFileSeekAndSyncTest  
  52.     }  
  53.   
  54.     @Test(expected = IOException.class)  
  55.     public void seekToNonRecordBoundary() throws IOException {  
  56.         // vv SequenceFileSeekAndSyncTest-SeekNonRecordBoundary  
  57.         reader.seek(360);  
  58.         reader.next(key, value); // fails with IOException  
  59.         // ^^ SequenceFileSeekAndSyncTest-SeekNonRecordBoundary  
  60.     }  
  61.   
  62.     @Test  
  63.     public void syncFromNonRecordBoundary() throws IOException {  
  64.         // vv SequenceFileSeekAndSyncTest-SyncNonRecordBoundary  
  65.         reader.sync(360);  
  66.         assertThat(reader.getPosition(), is(2021L));  
  67.         assertThat(reader.next(key, value), is(true));  
  68.         assertThat(((IntWritable) key).get(), is(59));  
  69.         // ^^ SequenceFileSeekAndSyncTest-SyncNonRecordBoundary  
  70.     }  
  71.   
  72.     @Test  
  73.     public void syncAfterLastSyncPoint() throws IOException {  
  74.         reader.sync(4557);  
  75.         assertThat(reader.getPosition(), is(4788L));  
  76.         assertThat(reader.next(key, value), is(false));  
  77.     }  
  78.   
  79. }  
0 0