hdfs系列 – SequenceFile格式与mapreduce

这是系列博客,你应该从《hdfs系列 – Text格式与mapreduce》开始阅读。

HDFS程序

SequenceFile是Hadoop内置的二进制文件格式,它支持压缩的同时支持Mapper分片处理,比Text格式更加适合作为数仓存储格式。

SequenceFile文件格式按K-V存储行数据,K是WritableComparable可序列化可比较即可,V是Writable可序列化的即可,具体K与V的含义则由写入者自行解释。

SequenceFile支持不压缩、行压缩、块压缩三种压缩方式,压缩算法则支持类似常见的Snappy、Gzip等,我们一般选择块压缩来带来较高的压缩率,所谓块压缩就是将n行数据整体压缩一次追加到文件中。

代码实现如下:

利用SequenceFile的createWriter方法打开文件进行写入:

  • SequenceFile.Writer.file:写入路径
  • SequenceFile.Writer.keyClass:Key的类型
  • SequenceFile.Writer.valueClass:Value的类型
  • SequenceFile.Writer.compression:压缩方式,这里为块级GZIP压缩
  • SequenceFile.Writer.syncInterval:sync marker的写入间隔,用于文件分片。

sync marker是一段16字节的固定magic字节数组,SequenceFile会在文件中每间隔一定的行就写入一个sync mark,这样在hdfs block内只要找到sync marker就可以切出一个InputSplit分片了(拥有2^(16*8)种组合,很难和数据部分冲突),这样就可以给多个mapper并行输入来提高并发度了,因此sync marker是二进制文件格式的一个主要的分片手段,被多种高级文件格式使用。

我们循环向文件写入Key和Value作为一条记录,一共写入1000个记录。

接着利用SequenceFile.Reader读打开这个文件,读的时候不需要再声明文件的压缩类型、K/V的数据类型,因为这些元信息都被存储在SequenceFile文件头部,我们直接开始循环读取记录即可。

运行HDFS程序

没什么特殊的:

查看文件:

mapreduce程序

根据我们上述写入的SequenceFile文件,每一条记录的K与V都是Text类型,可以直接被SequenceFileInputFormat的RecordReader解析到Mapper的Key和Value上。

因此,我们可以实现如下Mapper和Reducer:

Mapper把输入的K和V连接起来,然后输出<K=V, 1>。Reducer则统计一下每个K=V的出现次数,程序没什么意义,仅仅为了演示。

Mapper输入包括几个配置项:

  • SequenceFileOutputFormat.addInputPath:设置输入路径
  • setInputFormatClass:设置SequenceFileInputFormat的文件格式作为输入。
  • setMapperClass:mapper实现。
  • setMapOutputKeyClass:mapper输出的key类型。
  • setMapOutputValueClass:mapper输出的value类型。

Reducer输出包括几个配置:

  • SequenceFileOutputFormat.setOutputPath:输出路径
  • SequenceFileOutputFormat.setCompressOutput:输出结果压缩
  • SequenceFileOutputFormat.setOutputCompressorClass:输出结果采用GZIP压缩
  • SequenceFileOutputFormat.setOutputCompressionType:输出结果采用块级压缩
  • setOutputFormatClass:输出也是SequenceFile格式
  • setReducerClass:reducer实现
  • setOutputKeyClass:reducer输出key类型
  • setOutputValueClass:reducer输出value类型

这里我们让reducer输出的Key和Value直接进入到SequenceFile的K-V记录,所以大家要注意理解MR的KV和SequenceFile的KV完全是两码事,MR的KV交给具体某种OutputFormat之后怎么存储是OutputFormat的事情。

运行Mapreduce

运行没什么特殊的:

这个MR的输入是sequenceFile,输出也是seqenceFile,当然MR并不要求输入和输出一定要采用同一种文件格式,但是sequenceFile是个很实用的文件格式,能在压缩的同时支持InputSplit。

经过前一篇博客的Text格式和本篇SequenceFile格式,我们基本已经熟悉了HDFS和MR的工作原理。

这两种格式都是Hadoop内置的文件格式,并且都是基于行的存储。

接下来我们会再接触2个非Hadoop自带的文件格式,它们一个是行存储,一个是列存储,而列存储是Hive数据仓库主要使用的文件格式,因为它的数据压缩率和IO效率都要高于行存储。

如果文章帮助您解决了工作难题,您可以帮我点击屏幕上的任意广告,或者赞助少量费用来支持我的持续创作,谢谢~