文档章节

Hive 文件格式

Avner
 Avner
发布于 2017/08/11 13:33
字数 2751
阅读 93
收藏 0
点赞 0
评论 0

本文主要转至:http://www.cnblogs.com/skyl/

Hadoop 作为MR 的开源实现,一直以动态运行解析文件格式并获得比MPP数据库快上几倍的装载速度为优势。不过,MPP数据库社区也一直批评Hadoop由于文件格式并非为特定目的而建,因此序列化和反序列化的成本过高。

文本格式的数据也是Hadoop中经常碰到的。如TextFile 、XML和JSON。 文本格式除了会占用更多磁盘资源外,对它的解析开销一般会比二进制格式高几十倍以上,尤其是XML 和JSON,它们的解析开销比Textfile 还要大,因此强烈不建议在生产系统中使用这些格式进行储存。 如果需要输出这些格式,请在客户端做相应的转换操作。 文本格式经常会用于日志收集,数据库导入,Hive默认配置也是使用文本格式,而且常常容易忘了压缩,所以请确保使用了正确的格式。另外文本格式的一个缺点是它不具备类型和模式,比如销售金额、利润这类数值数据或者日期时间类型的数据,如果使用文本格式保存,由于它们本身的字符串类型的长短不一,或者含有负数,导致MR没有办法排序,所以往往需要将它们预处理成含有模式的二进制格式,这又导致了不必要的预处理步骤的开销和储存资源的浪费。

1.TextFile

  • Hive数据表的默认格式,存储方式:行存储。
  • 可使用Gzip,Bzip2等压缩算法压缩,压缩后的文件不支持split
  • 但在反序列化过程中,必须逐个字符判断是不是分隔符和行结束符,因此反序列化开销会比SequenceFile高几十倍。
--创建数据表:
create table if not exists textfile_table(
site string,
url  string,
pv   bigint,
label string)
row format delimited fields terminated by '\t'
stored as textfile;
--插入数据:
set hive.exec.compress.output=true; --启用压缩格式 
set mapred.output.compress=true;    
set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;  --指定输出的压缩格式为Gzip  
set io.compression.codecs=org.apache.hadoop.io.compress.GzipCodec;      
insert overwrite table textfile_table select * from T_Name;

2.SequenceFile

  • Hadoop API提供的一种二进制文件,以<key,value>的形式序列化到文件中。
  • 存储方式:行存储。
  • 支持三种压缩选择:NONE,RECORD,BLOCK。Record压缩率低,一般建议使用BLOCK压缩。
  • 这种二进制文件内部使用Hadoop 的标准的Writable 接口实现序列化和反序列化。它与Hadoop API中的MapFile 是互相兼容的,这是sequence file的一个优势。
  • Hive 中的SequenceFile 继承自Hadoop API 的SequenceFile,不过它的key为空,使用value 存放实际的值, 这样是为了避免MR 在运行map 阶段的排序过程。如果你用Java API 编写SequenceFile,并让Hive 读取的话,请确保使用value字段存放数据,否则你需要自定义读取这种SequenceFile 的InputFormat class 和OutputFormat class。 
  • SequenceFile是Hadoop本身就可以支持的一种标准文件格式,因为它也是在Hive和其他Hadoop相关的工具中共享文件的可以接受的选择。而对于Hadoop生态系统之外的其它工具而言,其并不适用.
  • SequenceFile可以在块级别和记录级别进行压缩,这对于优化磁盘利用率和I/0来说非常有意义。同时仍然可以支持按照块级别的文件进行分割,以方便并行处理。

值得注意的是,hive读取sequencefile的时候,是把key忽略的,也就是直接读value并且按照指定分隔符分隔字段。但是如果hive的数据来源是从mr生成的,那么写sequencefile的时候,key和value都是有意义的,key不能被忽略,而是应该当成第一个字段。为了解决这种不匹配的情况,有两种办法。一种是要求凡是结果会给hive用的mr job输出value的时候带上key。但是这样的话对于开发是一个负担,读写数据的时候都要注意这个情况。所以更好的方法是第二种,也就是把这个源自于hive的问题交给hive解决,写一个InputFormat包装一下,把value输出加上key即可。

create table if not exists seqfile_table(
site string,
url  string,
pv   bigint,
label string)
row format delimited fields terminated by '\t'
stored as sequencefile;
--插入数据操作:
set hive.exec.compress.output=true;  --启用输出压缩格式
set mapred.output.compress=true;  
set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;  --指定输出压缩格式为Gzip
set io.compression.codecs=org.apache.hadoop.io.compress.GzipCodec;  
SET mapred.output.compression.type=BLOCK; --指定为Block
insert overwrite table seqfile_table select * from T_Name;

 

3.RCFile

BG:大多数的Hadoop和Hive存储都是行式存储的,在大多数场景下,这是比较高效的。这种高效归根于如下几点:大多数的表具有的字段个数都不大(一般小于20个);对文件按块进行压缩对于需要处理重复数据的情况比较高效,同时很多的处理和调试工具(如:more,head,awk)都可以很好的应用于行式存储的数据。

并非所有的工具和数据存储都是采用行式存储的方式的,对于特定类型的数据和应用来说,采用列式存储有时会更好。例如,如果指定的表具有成百上千个字段,而大多数的查询只需要使用到其中的一小部分字段,这是扫描所有的行而过滤掉大部分的数据显然是个浪费。然而,如果数据是按照列而不是行进行存储的话,那么只要对其需要的列进行扫描就可以了,这样可以提高性能。

对于列式存储而言,进行压缩通常会非常高效,特别是在这列的数据具有较低计算的时候(只有很少的排重值时)。同时,一些列式存储并不需要无力存储NULL值的列。

基于这些场景,HIVE中才设计了RCFile.

Hive功能强大的一个方面体现在不同的存储格式间相互转换数据非常的简单。存储信息存放在了表的元数据信息中。当对表执行一个select查询时。以及向其他表中执行insert操作时,Hive就会使用这个表的元数据信息中提供的内容,然后自动执行转换过程。这样使用可以有多种选择,而不需要额外的程序来对不同的存储格式进行转换。

可以在创建表时使用:ColumnarSerDe, RCFileInputFormat 和 RCFileOutputFormat;  /(end bg)

 

存储方式:数据按行分块,每块按列存储。结合了行存储和列存储的优点:

  • 首先,RCFile 保证同一行的数据位于同一节点,因此元组重构的开销很低
  • 其次,像列存储一样,RCFile 能够利用列维度的数据压缩,并且能跳过不必要的列读取
  • RCFile是Hive推出的一种专门面向列的数据格式。 它遵循“先按列划分,再垂直划分”的设计理念。当查询过程中,针对它并不关心的列时,它会在IO上跳过这些列。需要说明的是,RCFile在map阶段从远端拷贝仍然是拷贝整个数据块,并且拷贝到本地目录后RCFile并不是真正直接跳过不需要的列,并跳到需要读取的列, 而是通过扫描每一个row group的头部定义来实现的但是在整个HDFS Block 级别的头部并没有定义每个列从哪个row group起始到哪个row group结束。所以在读取所有列的情况下,RCFile的性能反而没有SequenceFile高。
  •  

RCFile的一个行组包括三个部分:

  1.  第一部分是行组头部的【同步标识】,主要用于分隔 hdfs 块中的两个连续行组
  2.  第二部分是行组的【元数据头部】,用于存储行组单元的信息,包括行组中的记录数、每个列的字节数、列中每个域的字节数
  3.  第三部分是【表格数据段】,即实际的列存储数据。在该部分中,同一列的所有域顺序存储。
     从图可以看出,首先存储了列 A 的所有域,然后存储列 B 的所有域等。

数据追加:RCFile 不支持任意方式的数据写操作,仅提供一种追加接口,这是因为底层的 HDFS当前仅仅支持数据追加写文件尾部。 
行组大小:行组变大有助于提高数据压缩的效率,但是可能会损害数据的读取性能,因为这样增加了 Lazy 解压性能的消耗。而且行组变大会占用更多的内存,这会影响并发执行的其他MR作业。 考虑到存储空间和查询效率两个方面,Facebook 选择 4MB 作为默认的行组大小,当然也允许用户自行选择参数进行配置。

create table if not exists rcfile_table(
site string,
url  string,
pv   bigint,
label string)
row format delimited fields terminated by '\t'
stored as rcfile;
--插入数据操作:
set hive.exec.compress.output=true;  
set mapred.output.compress=true;  
set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;  
set io.compression.codecs=org.apache.hadoop.io.compress.GzipCodec;  
insert overwrite table rcfile_table select * from T_Name;


 

4.ORCFile

  • 存储方式:数据按行分块 每块按照列存储
  • 压缩快 快速列存取
  • 效率比rcfile高,是rcfile的改良版本

自定义格式

  • 用户可以通过实现inputformat和 outputformat来自定义输入输出格式。
hive>  create table myfile_table(str STRING)  
    >  stored as  
    >  inputformat 'org.apache.hadoop.hive.contrib.fileformat.base64.Base64TextInputFormat'  
    >  outputformat 'org.apache.hadoop.hive.contrib.fileformat.base64.Base64TextOutputFormat'; 
OK
Time taken: 0.399 seconds
hive> load data local inpath '/root/hive/myfile_table'
    > overwrite into table myfile_table;--加载数据
hive> dfs -text /user/hive/warehouse/myfile_table/myfile_table;--数据文件内容,编码后的格式
aGVsbG8saGl2ZQ==
aGVsbG8sd29ybGQ=
aGVsbG8saGFkb29w
hive> select * from myfile_table;--使用自定义格式进行解码
OK
hello,hive
hello,world
hello,hadoop
Time taken: 0.117 seconds, Fetched: 3 row(s)

 

5. Avro

Avro是一种用于支持数据密集型的二进制文件格式。它的文件格式更为紧凑,若要读取大量数据时,Avro能够提供更好的序列化和反序列化性能。并且Avro数据文件天生是带Schema定义的,所以它不需要开发者在API 级别实现自己的Writable对象。最近多个Hadoop 子项目都支持Avro数据格式,如Pig 、Hive、Flume、Sqoop和Hcatalog。

 

6.示例自定义输入格式:DualInputFormat;

总结:

数据仓库的特点:一次写入、多次读取,因此,整体来看,ORCFile相比其他格式具有较明显的优势。

  • TextFile 默认格式,加载速度最快,可以采用Gzip、bzip2等进行压缩,压缩后的文件无法split,即并行处理
  • SequenceFile 压缩率最低,查询速度一般,三种压缩格式NONE,RECORD,BLOCK
  • RCfile 压缩率最高,查询速度最快,数据加载最慢。

 

 

© 著作权归作者所有

共有 人打赏支持
Avner
粉丝 8
博文 42
码字总数 45068
作品 0
杭州
程序员

暂无相关文章

mysql in action / alter table

change character set ALTER SCHEMA `employees` DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci ;ALTER TABLE `employees`.`t2` CHARACTER SET = utf8mb4 , COLLAT......

qwfys ⋅ 今天 ⋅ 0

Java 开发者不容错过的 12 种高效工具

Java 开发者常常都会想办法如何更快地编写 Java 代码,让编程变得更加轻松。目前,市面上涌现出越来越多的高效编程工具。所以,以下总结了一系列工具列表,其中包含了大多数开发人员已经使用...

jason_kiss ⋅ 昨天 ⋅ 0

Linux下php访问远程ms sqlserver

1、安装freetds(略,安装在/opt/local/freetds 下) 2、cd /path/to/php-5.6.36/ 进入PHP源码目录 3、cd ext/mssql进入MSSQL模块源码目录 4、/opt/php/bin/phpize生成编译配置文件 5、 . ./...

wangxuwei ⋅ 昨天 ⋅ 0

如何成为技术专家

文章来源于 -- 时间的朋友 拥有良好的心态。首先要有空杯心态,用欣赏的眼光发现并学习别人的长处,包括但不限于工具的使用,工作方法,解决问题以及规划未来的能力等。向别人学习的同时要注...

长安一梦 ⋅ 昨天 ⋅ 0

Linux vmstat命令实战详解

vmstat命令是最常见的Linux/Unix监控工具,可以展现给定时间间隔的服务器的状态值,包括服务器的CPU使用率,内存使用,虚拟内存交换情况,IO读写情况。这个命令是我查看Linux/Unix最喜爱的命令...

刘祖鹏 ⋅ 昨天 ⋅ 0

MySQL

查看表相关命令 - 查看表结构    desc 表名- 查看生成表的SQL    show create table 表名- 查看索引    show index from  表名 使用索引和不使用索引 由于索引是专门用于加...

stars永恒 ⋅ 昨天 ⋅ 0

easyui学习笔记

EasyUI常用控件禁用方法 combobox $("#id").combobox({ disabled: true }); ----- $("#id").combobox({ disabled: false}); validatebox $("#id").attr("readonly", true); ----- $("#id").r......

miaojiangmin ⋅ 昨天 ⋅ 0

金山WPS发布了Linux WPS Office

导读 近日,金山WPS发布了Linux WPS Office中文社区版新版本,支持大部分主流Linux系统,功能更加完善,兼容性、稳定性大幅度提升。本次更新WPS将首次在Linux提供专业办公文件云存储服务,实...

问题终结者 ⋅ 昨天 ⋅ 0

springboot2输出metrics到influxdb

序 本文主要研究一下如何将springboot2的metrics输出到influxdb maven <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-bo......

go4it ⋅ 昨天 ⋅ 0

微信小程序 - 选择图片显示操作菜单

之前我分享过选择图片这个文章,但是我在实际开发测试使用中发现一个问题在使用 wx.chooseImage 选择照片显示出第一格是拍照,后面是相册里的图片。这种实现之前说过了,效果如下。 但是你从...

hello_hp ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部