大数据面试必问-快速理解Hive的数据存储格式及mapreduce底层原理

在大数据工程师面试时,下面这个题可谓是面试官的最爱,他考察了对于mapreduce框架以及hive的原理的理解,阅读完这篇文章,在面试这一类的问题时,就会胸有撑住了!

在创建hive表时,会有这样一句:STORED AS TEXTFILE,这一句的作用,其实是

STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat'

OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat' 的简写。要想理解hive存储格式或者Mapreduce的原理,我们先从理解InputFormat开始。

一、理解 InputFormat

InputFormat是个抽象类,他有两个成员方法。理解了这两个方法的作用,我们就知道InputFormat是用来做什么的了。我们依次来看

1)第一个方法: List getSplits(JobContext var1),它实现了对文件切分成多个分片,分片对象的定义为InputSplit,我们以他的一个实现:FileInputFormat 为例,FileInputFormat继承了InputFormat,实现了对于文件的读入,下图为getSplits的实现。可以看到实现里根据computeSplitSize 方法取分块大小,循环所有输入文件,将拆分后的文件路径,起始位置,长度,host等信息赋值到inputsplit对象上,这其实是一个逻辑上的划分,数据在这一步不会发生任何变动。另外,在读取文件时(截图里的listStatus方法内)还通过定义的PathFilter进行了文件过滤,去掉那些以.或_开头的临时文件等。

13553988-caa45687ab18ae7e

2)第二个方法:RecordReader<K,V> createRecordReader(InputSplit split, TaskAttemptContext context )

从函数定义来看,其实就是读取InputSplit的分块信息,返回了单独的record。没错,这个函数的作用就是从InputSplit中正确读出一条一条的key value值,供Mapper使用。

3)Hive定义中TextInputFormat的实现

我们再来看在定义hive表时,使用的TextInputFormat的实现,他是继承了上面的FileInputFormat,重写了 createRecordReader 方法使用LineRecordReader实现了文本读取,重写isSplitable增加了对于压缩文件不可分割的判断。

13553988-bf28f562cb4de55e

看到这里,大家对于InputFormat的作用就比较清晰了,他提供了文件的过滤、切分以及每个split的明细读取,为下一步的map工作做好了前期准备。

二、Hive的存储格式

那回到hive存储格式的问题上,其实就是Hive对InputFormat 提供了不同的实现,用来解析为优化hive速度而定义的不同存储格式。hive主要有下面三种存储格式。

1)textfile 也就是hive默认的存储格式,数据可以使用任意分隔符进行分割,每一行为一条记录。默认无压缩,可以用gzip、snappy等方式对数据压缩,但是会造成无法对数据切分并行操作。(textInputFormat的isSplitable判断)

2) sequencefile 这种方式是讲hdfs上的数据进行二进制格式编码,存储进行了压缩,有利于减少IO,也是基于行存储。

3) rcfile:这种方式 是基于sequencefile存储,但是是基于列存储,列值通常重复值很多,所以更利于压缩。这种方式压缩率更高。他先对行进行分组 ,在对列进行合并。比如我们select 表中的一列数据时,只会对该列的数据进行处理,但是其他存储方式不论select几列会对所有数据都读取出来。但是当select 全列时,rcfile反而不如sequencefile的性能高了。

13553988-da09951b8f9de52a

猜你喜欢

转载自blog.csdn.net/weixin_38653290/article/details/86625847