hadoop IO操作

大数据学习之hadoop IO操作

一、hadoop IO简述

Hadoop的HDFS和MapReduce子框架主要是针对大数据文件来设计的,在小文件的处理上不但效率低下,而且十分消耗内存资源(每一个小文件占用一个Block,每一个block的元数据都存储在namenode的内存里)。解决办法通常是选择一个容器,将这些小文件组织起来统一存储。HDFS提供了两种类型的容器,分别是SequenceFile和MapFile。

二、sequenceFile简述

a.Sequence file由一系列的二进制key/value组成,如果key为小文件名,value为文件内容,则可以将大批小文件合并成一个大文件。Hadoop-0.21.0版本开始中提供了SequenceFile,包括Writer,Reader和SequenceFileSorter类进行写,读和排序操作。该方案对于小文件的存取都比较自由,不限制用户和文件的多少,支持Append追加写入,支持三级文档压缩(不压缩、文件级、块级别)。其存储结构如下图所示:
这里写图片描述

b.前三个字节是一个Bytes SEQ代表着版本号,同时header也包括key的名称,value class , 压缩细节,metadata,以及Sync markers。Sync markers的作用在于可以读取任意位置的数据。
在recourds中,又分为是否压缩格式。当没有被压缩时,key与value使用Serialization序列化写入SequenceFile。当选择压缩格式时,record的压缩格式与没有压缩其实不尽相同,除了value的bytes被压缩,key是不被压缩的。当保存的记录很多时候,可以把一串记录组织到一起同一压缩成一块。
在Block中,它使所有的信息进行压缩,压缩的最小大小由配置文件中,io.seqfile.compress.blocksize配置项决定。

c.写入策略
SequenceFile写操作
通过createWrite创建SequenceFile对象,返回Write实例,指定待写入的数据流如FSDataOutputStream或FileSystem对象和Path对象。还需指定Configuration对象和键值类型(都需要能序列化)。
SequenceFile通过API来完成新记录的添加操作
fileWriter.append(key,value);

d.实现代码

private static void writeTest(FileSystem fs, int count, int seed, Path file,  
                              CompressionType compressionType, CompressionCodec codec)  
  throws IOException {  
  fs.delete(file, true);  
  LOG.info("creating " + count + " records with " + compressionType +  
           " compression");  

//指明压缩方式  
  SequenceFile.Writer writer =  SequenceFile.createWriter(fs, conf, file,  
                              RandomDatum.class, RandomDatum.class, compressionType, codec);  
  RandomDatum.Generator generator = new RandomDatum.Generator(seed);  
  for (int i = 0; i < count; i++) {  
    generator.next();    
//keyh  
    RandomDatum key = generator.getKey();    
//value  
    RandomDatum value = generator.getValue();  
//追加写入  
    writer.append(key, value);  
  }  
  writer.close();  
}  
public class SequenceFileWriteDemo { 
private static final String[] DATA = { "One, two, buckle my shoe", "Three, four, shut the door", "Five, six, pick up sticks", "Seven, eight, lay them straight", "Nine, ten, a big fat hen" }; 

public static void main(String[] args) throws IOException { 
 String uri = =“hdfs://master:8020/number.seq";
 Configuration conf = new Configuration(); 
FileSystem fs = FileSystem.get(URI.create(uri), conf); 
Path path = new Path(uri); 
IntWritable key = new IntWritable(); 
Text value = new Text(); 
SequenceFile.Writer writer = null; 
try { 
writer = SequenceFile.createWriter(fs, conf, path, key.getClass(), value.getClass()); 
for (int i = 0; i < 100; i++) { 
key.set(100 - i); 
value.set(DATA[i % DATA.length]); System.out.printf("[%s]\t%s\t%s\n", writer.getLength(), key, value); 
writer.append(key, value); 
} } 
finally { IOUtils.closeStream(writer); }
 } 
}

三、mapFile简述

a.一个MapFile可以通过SequenceFile的地址,进行分类查找的格式。使用这个格式的优点在于,首先会将SequenceFile中的地址都加载入内存,并且进行了key值排序,从而提供更快的数据查找。
与SequenceFile只生成一个文件不同,MapFile生成一个文件夹。
索引模型按128个键建立的,可以通过io.map.index.interval来修改
b.读写策略
排序后的SequeneceFile,并且它会额外生成一个索引文件提供按键的查找.读写mapFile与读写SequenceFile
非常类似,只需要换成MapFile.Reader和MapFile.Writer就可以了。
在命令行显示mapFile的文件内容同样要用 -text
c.实现代码

public class MapFileWriteFile
{
private static final String[] myValue={"hello world","bye world","hello hadoop","bye hadoop"};
public static void main(String[] args)
{
String uri=“hdfs://master:8020/number.map";
Configuration conf=new Configuration();
FileSystem fs=FileSystem.get(URI.create(uri),conf);
IntWritable key=new IntWritable();
Text value=new Text();
MapFile.Writer writer=null;
try
{
writer=new MapFile.Writer(conf,fs,uri,key.getClass(),value.getClass());
for(int i=0;i<500;i )
{
key.set(i);
value.set(myValue[i%myValue.length]);
writer.append(key,value);
}
finally {IOUtils.closeStream(writer);}
}
}
}
MapFile会生成2个文件 1个名data,1个名index
查看前10条data+index $ hdfs –fs –text /number.map/data | head
public class MapFileReadFile
{
public static void main(String[] args)
{
String uri=“hdfs://master:8020/number.map";
Configuration conf=new Configuration();
FileSystem fs=FileSystem.get(URI.create(uri),conf);
MapFile.Reader reader=null;
try
{
reader=new MapFile.Reader(fs,uri,conf);
WritableComparable key=(WritableComparable)ReflectionUtils.newInstance(reader.getValueClass(),conf);
while(reader.next(key,value))
{
System.out.printf("%s\t%s\n",key,value);
}
reader.get(new IntWritable(7),value);
System.out.printf("%s\n",value);
}
finally
{ IOUtils.closeStream(reader); }
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值